I'm working on a variant of a TSP, where each node has a Time Window, but i've some problems calculating the cost function. I'm using a succesors model, so i have a list where each variable rapresents the next destination, Xi = j is the link from node i to node j.
My code looks like this:
:-lib(ic).
:-lib(branch_and_bound).
:-lib(propia).
:-[nodes].
tsp(Next, Cost):-
Cost::1..10000,
Next::1..10000,
%Constraints
alldifferent(Next),
different_from_index(Next),
circuit(Next),
create_objective(Next, Cost),
minimize(labeling(Next), Cost).
Where different_from_index is a constraint between the index of a Next's variable and it's value: Next[i] != i, and create_objective is the predicate that define the objective function. First of all the create_objective predicate creates a list of the link's costs, so it would be easy to get the cost with a simple sumlist predicate. But i need to define a time window for each node and i thought something like this:
time_window([], _, _, 0).
time_window([HCost | TCost], Next, Start, Cost):-
element(Start, Next, Destination),
time_window(TCost, Next, Destination, Cost1),
Cost #= Cost1 + HCost,
node(Destination, Min, Max) infers most,
Cost #>= Min, Cost #=< Max.
where the [HCost | TCost] is the list of the costs mentioned before, but sorted and reversed (so i have as n element of the list the first link, ad n-1 the second and so on). Furthermore the node predicate is contained in prolog file loaded at the begin. Unfortunately this doesn't seem to work: it doesn't return false neither wrong solution. After some times of computing i receive this message:
[eclipse 2]: tsp(Next, Cost).
bb_min: search did not instantiate cost variable
Aborting execution ...
Abort
I understand the error, but i don't know how to fix it. I successfully did it with a simplier model and a similar time_window predicate, but in this case it not seems appropriate.
Can anyone help me out? Thanks in advice.
Let's start with the following basic TSP program. It takes as input a distance matrix
Dist
, and maintains a successor arrayNext
, and a distance arrayLegs
which contains the distance travelled from each node to its successor. We minimiseCost
, which is the total distance travelled.To enable time window handling, add an array
Time
giving the arrival time at each node, which can then be constrained according to requirements. Arrival time at the successor of nodeI
can be computed as arrival time atI
plus travel time fromI
to its successor (for simplicity, assume that distance = time, and that we start at node 1 at time 0). This leads toSample run: