Originally posted by: Ashraf_ISE
I'm still having problem with the solution I get for my n=64 instance of the TSP.
I added an extra power to your code
dvar int nextCity4[1..n+1] in 1..n;
and also used your previous answer to set the first four cities to visit- 1,8 , 57, 64
nextCity[1]==8;
nextCity[8]==57;
nextCity[57]==64;
so to recap, n = 64, n = 4 and d=3. My distance data is attached below
using CP;
int n = ...;
range Cities = 1..n;
int realCity[i in 1..n+1]=(i<=n)?i:1;
// Edges -- sparse set
tuple edge {int i; int j;}
setof(edge) Edges = {<i,j> | ordered i,j in 1..n};
setof(edge) Edges2 = {<i,j> | i,j in 1..n+1}; // node n+1 is node 1
int dist[Edges] = ...;
int dist2[<i,j> in Edges2]=(realCity[i]==realCity[j])?0:
((realCity[i]<realCity[j])?dist[<realCity[i],realCity[j]>]:dist[<realCity[j],realCity[i]>]);
int dist2b[i in Cities,j in Cities]=dist2[<i,j>];
dvar interval itvs[1..n+1] size 1;
dvar sequence seq in all(i in 1..n+1) itvs[i];
dvar sequence seq2 in all(i in 1..n+1) itvs[i] types all(i in 1..n+1)i;
// Gives which city is visited after city i
dvar int nextCity[1..n+1] in 1..n+1;
// Power 2
dvar int nextCity2[1..n+1] in 1..n;
// Power 3
dvar int nextCity3[1..n+1] in 1..n;
dvar int nextCity4[1..n+1] in 1..n;
execute
{
cp.param.TimeLimit=60;
var f = cp.factory;
cp.setSearchPhases(f.searchPhase(seq));
}
tuple triplet { int c1; int c2; int d; };
{triplet} Dist = {
<i-1,j-1,dist2[<i ,j >]>
| i,j in 1..n+1};
minimize endOf(itvs[n+1]) - (n+1);
subject to
{
startOf(itvs[1])==0; // break sym
noOverlap(seq,Dist,true); // nooverlap with a distance matrix
last(seq, itvs[n+1]); // last node
// prev(seq, itvs[1], itvs[9]);
// prev(seq, itvs[9], itvs[73]);
// prev(seq, itvs[73], itvs[81]);
//prev(seq, itvs[36], itvs[16]);
sameSequence(seq,seq2);
forall(i in 1..n+1) nextCity[i]==(typeOfNext(seq2,itvs[i],1)-1) mod n+1 ;
forall(i in 1..n+1) nextCity2[i]==nextCity[nextCity[i]];
forall(i in 1..n+1) nextCity3[i]==nextCity[nextCity2[i]];
forall(i in 1..n+1) nextCity4[i]==nextCity[nextCity3[i]];
forall(i in 1..n-1) dist2b[i,nextCity4[i]]<=3;
nextCity[1]==8;
nextCity[8]==57;
nextCity[57]==64;
}
int x[<i,j> in Edges]=prev(seq,itvs[i],itvs[j])+prev(seq,itvs[j],itvs[i]);
int isPrevFromNPlus1[i in 1..n]=prev(seq,itvs[i],itvs[n+1]);
int l=first({i | i in 1..n : isPrevFromNPlus1[i]==1});
edge el=<1,l>;
execute
{
isPrevFromNPlus1;
x;
x[el]=1;
}
// Let us check here that the constraints of the IP model are ok
assert forall (j in Cities)
as:sum (<i,j> in Edges) x[<i,j>] + sum (<j,k> in Edges) x[<j,k>] == 2;
// Let us compute here the objective the IP way
int cost=sum (<i,j> in Edges) dist[<i,j>]*x[<i,j>];
execute
{
writeln(cost);
}
and the data is attached in a file called Alex.
Now the solution start by visiting cities 1, 8, 57, and 64 as instructed. the 5th city visited is 20 and d(1,20) is 3 so that okay. the 6th city visited is 21 and d(8,21)=2 so that is good. the 7th node visited is 35 and d( 57,35) =3 which is also okay. the problem arises on the 8th visit which is node 34 and with the same trace back logic we used with the other nodes d(64,34) should be less than or equal to 3 but it is actually 6, and that is violates our constraint where d is 3. After that it gets messy and it visits city 42 that is not even near node 20 that was visited 4 steps before
I feel like it is a problem with sequencing and number more than a logical thing, since it works well for the first few cities
#DecisionOptimization#OPLusingCPLEXOptimizer