Originally posted by: rsbeigi
I was trying to add subtour elimination constraints through lazy constraint callback for a routing problem. I use CPLEX 12.8 on Ubuntu 18.04 with C++. Some problem instances are solved without any issues. However, I have come across an instance in which after around one hour CPLEX just freezes (at some point, everything just stops even printing commands without throwing an error). I tried my best to debug the code but it seems to be very strange. Here is the contents of my Lazy callback:
ILOLAZYCONSTRAINTCALLBACK0(LazyCallback)
{
if (hasIncumbent())
{
cout << endl << endl << "UB=" << getIncumbentObjValue() << endl << endl ;
}
for( int s = 0 ; s < M ; s++ )
{
for ( int k = 0 ; k < K1[s] ; k++ )
{
cout << "\n\nVehicle: " << k+1 << "\n\n" ;
vector <int> A, B ;
vector <int> VISIT ;
for(int i = 0 ; i < N ; i++ )
{
if (getValue (V1[i][s][k]) > EPSILON)
{
VISIT.push_back(i) ;
cout << endl << "V1(" << i+1 << ")(" << k+1 << ")=" << getValue (V1[i][s][k]) ;
}
}
int v_size = VISIT.size() ;
cout << endl << "|V|=" << v_size << endl ;
if (v_size == 0) // if vehicle k is not used, vehicle k+1 will not be used
{
break ;
}
if (v_size <= 3) // if vehicle k visits 3 nodes (or less), definitely no subtour exists.
{
continue ;
}
Graph <double> G(v_size) ;
vector <double> MAX_FLOW (v_size,0) ;
for(int i = 0 ; i < v_size ; i++ )
{
for(int j = 0 ; j < v_size ; j++ )
{
if (i != j)
{
double val = getValue (U1[ VISIT[i] ][ VISIT[j] ][s][k]) ;
if (val > EPSILON)
{
G.addEdge(i, j, val) ;
cout << endl << "U1(" << VISIT[i]+1 << ")(" << VISIT[j]+1 << ")(" << k+1 << ")=" << val ;
}
}
}
}
double min_max_flow = IloInfinity ;
double val ;
MAX_FLOW[0] = IloInfinity ;
for(int i = 1 ; i < v_size ; i++ ) // Note that we start from i=1
{
val = G.DinicMaxflow(0, i) ;
MAX_FLOW[i] = val ;
if (val < min_max_flow)
min_max_flow = val ;
}
if (1-min_max_flow < EPSILON) // no subtour found
{
continue ;
}
cout << "\n\nMaxFlow:" ;
for(int i = 0 ; i < v_size ; i++ )
{
cout << endl << VISIT[i]+1 << ' ' << MAX_FLOW[i] ;
if (MAX_FLOW[i] - min_max_flow < EPSILON)
{
B.push_back(i) ;
}
else
{
A.push_back(i) ;
}
}
////////////////////////////////////////////////////
cout << "\n\nA:" ;
for(size_t i = 0 ; i < A.size() ; i++ )
{
size_t a = VISIT[ A[i] ] ;
cout << endl << a+1 << ' ' ;
}
////////////////////////////////////////////////////
cout << "\n\nB:" ;
for(size_t i = 0 ; i < B.size() ; i++ )
{
size_t a = VISIT[ B[i] ] ;
cout << endl << a+1 << ' ' ;
}
////////////////////////////////////////////////////
IloExpr SUM (env) ;
for(size_t i = 0 ; i < A.size() ; i++ )
{
for(size_t j = 0 ; j < A.size() ; j++ )
{
if (i!=j)
SUM += U1[ VISIT[A[i]] ][ VISIT[A[j]] ][s][k] ;
}
}
IloExpr SUM1 (env) ;
for(size_t i = 0 ; i < B.size() ; i++ )
{
SUM1 += V1[ VISIT[B[i]] ][s][k] ;
}
// IloConstraint lazy_const = SUM - A.size() + SUM1 <= 0 ;
// LAZY_CONST.add( lazy_const ) ;
cout << endl << lazy_const << endl ;
add (lazy_const) ;
SUM.end() ;
SUM1.end() ;
}
///////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////
for ( int k = 0 ; k < K2[s] ; k++ )
{
cout << "\n\nVehicle: " << k+1 << "\n\n" ;
vector <int> A, B ;
vector <int> VISIT ;
for(int i = 0 ; i < N ; i++ )
{
if (getValue (V2[i][s][k]) > EPSILON)
{
VISIT.push_back(i) ;
cout << endl << "V2(" << i+1 << ")(" << k+1 << ")=" << getValue (V2[i][s][k]) ;
}
}
int v_size = VISIT.size() ;
cout << endl << "|V|=" << v_size << endl ;
if (v_size == 0) // if vehicle k is not used, vehicle k+1 will not be used
{
break ;
}
if (v_size <= 3) // if vehicle k visits 3 nodes (or less), definitely no subtour exists.
{
continue ;
}
Graph <double> G(v_size) ;
vector <double> MAX_FLOW (v_size,0) ;
for(int i = 0 ; i < v_size ; i++ )
{
for(int j = 0 ; j < v_size ; j++ )
{
if (i != j)
{
cout << "\n\nNow now\n\n" ;
double val = getValue (U2[ VISIT[i] ][ VISIT[j] ][s][k]) ;
cout << "\n\nNow now2\n\n" ;
if (val > EPSILON)
{
cout << "i=" << i << " j=" << j << "val=" << val << endl ;
cout << "ii=" << VISIT[i]+1 << " jj=" << VISIT[j]+1 << "val=" << val << endl ;
G.addEdge(i, j, val) ;
cout << endl << "U2(" << VISIT[i]+1 << ")(" << VISIT[j]+1 << ")(" << k+1 << ")=" << val ;
}
}
}
}
cout << endl << "Now" << endl ;
double min_max_flow = IloInfinity ;
cout << endl << "Now2" << min_max_flow ;
double val ;
cout << endl << "Now3" << v_size ;
MAX_FLOW[0] = IloInfinity ;
cout << endl << "Now4" << endl ;
for(int i = 0 ; i < MAX_FLOW.size() ; i++ )
cout << endl << MAX_FLOW[i] ;
for(int i = 1 ; i < v_size ; i++ ) // Note that we start from i=1
{
cout << "\nHi " ;
val = G.DinicMaxflow(0, i) ;
cout << "There! " << val << endl ;
MAX_FLOW[i] = val ;
if (val < min_max_flow)
min_max_flow = val ;
}
cout << "\n\nMIN(Maxflow)=" << min_max_flow << endl ;
if (1-min_max_flow < EPSILON) // no subtour found
{
cout << "\nContinued! " << 1-min_max_flow << endl ;
continue ;
}
cout << "\n\nMaxFlow:" ;
for(int i = 0 ; i < v_size ; i++ )
{
cout << endl << VISIT[i]+1 << ' ' << MAX_FLOW[i] ;
if (MAX_FLOW[i] - min_max_flow < EPSILON)
{
B.push_back(i) ;
}
else
{
A.push_back(i) ;
}
}
////////////////////////////////////////////////////
cout << "\n\nA:" ;
for(size_t i = 0 ; i < A.size() ; i++ )
{
size_t a = VISIT[ A[i] ] ;
cout << endl << a+1 << ' ' ;
}
////////////////////////////////////////////////////
cout << "\n\nB:" ;
for(size_t i = 0 ; i < B.size() ; i++ )
{
size_t a = VISIT[ B[i] ] ;
cout << endl << a+1 << ' ' ;
}
////////////////////////////////////////////////////
IloExpr SUM (env) ;
for(size_t i = 0 ; i < A.size() ; i++ )
{
for(size_t j = 0 ; j < A.size() ; j++ )
{
if (i!=j)
SUM += U2[ VISIT[A[i]] ][ VISIT[A[j]] ][s][k] ;
}
}
IloExpr SUM1 (env) ;
for(size_t i = 0 ; i < B.size() ; i++ )
{
SUM1 += V2[ VISIT[B[i]] ][s][k] ;
}
// IloConstraint lazy_const = SUM - A.size() + SUM1 <= 0 ;
LAZY_CONST.add( lazy_const ) ;
cout << endl << lazy_const << endl ;
add (lazy_const) ;
SUM.end() ;
SUM1.end() ;
}
}
}
And here is the output for the last callback (that freezes):
UB=45116.52136
Vehicle: 1
V1(3)(1)=1.00000
V1(12)(1)=1.00000
V1(17)(1)=1.00000
|V|=3
Vehicle: 2
V1(2)(2)=1.00000
V1(16)(2)=1.00000
|V|=2
Vehicle: 3
|V|=0
Vehicle: 1
V2(3)(1)=1.00000
V2(8)(1)=1.00000
V2(10)(1)=1.00000
V2(12)(1)=1.00000
V2(20)(1)=1.00000
|V|=5
Now now
Now now2
Now now
Now now2
Now now
Now now2
i=0 j=3val=1.00000
ii=3 jj=12val=1.00000
U2(3)(12)(1)=1.00000
Now now
Now now2
Now now
Now now2
Now now
Now now2
Now now
Now now2
Now now
Now now2
i=1 j=4val=1.00000
ii=8 jj=20val=1.00000
U2(8)(20)(1)=1.00000
Now now
Now now2
Now now
Now now2
i=2 j=1val=1.00000
ii=10 jj=8val=1.00000
U2(10)(8)(1)=1.00000
Now now
Now now2
Now now
Now now2
Now now
Now now2
Now now
Now now2
Now now
Now now2
i=3 j=2val=1.00000
ii=12 jj=10val=1.00000
U2(12)(10)(1)=1.00000
Now now
Now now2
Now now
Now now2
i=4 j=0val=1.00000
ii=20 jj=3val=1.00000
U2(20)(3)(1)=1.00000
Now now
Now now2
Now now
Now now2
Now now
Now now2
Now
Now2inf
Now35
Now4
inf
0.00000
0.00000
0.00000
0.00000
Hi There! 1.00000
Hi There! 1.00000
Hi There! 1.00000
Hi There! 1.00000
MIN(Maxflow)=1.00000
Continued! 0.00000
Vehicle: 2
V2(3)(2)=1.00000
V2(4)(2)=1.00000
V2(6)(2)=1.00000
V2(9)(2)=1.00000
V2(11)(2)=1.00000
V2(17)(2)=1.00000
V2(19)(2)=1.00000
|V|=7
Now now
Now now2
i=0 j=1val=0.33333
ii=3 jj=4val=0.33333
U2(3)(4)(2)=0.33333
Now now
Now now2
i=0 j=2val=0.33333
ii=3 jj=6val=0.33333
U2(3)(6)(2)=0.33333
Now now
Now now2
i=0 j=3val=0.33333
ii=3 jj=9val=0.33333
U2(3)(9)(2)=0.33333
Now now
Now now2
Now now
Now now2
Now now
Now now2
Now now
Now now2
Now now
Now now2
i=1 j=2val=0.66667
ii=4 jj=6val=0.66667
U2(4)(6)(2)=0.66667
Now now
Now now2
Now now
Now now2
i=1 j=4val=0.33333
ii=4 jj=11val=0.33333
U2(4)(11)(2)=0.33333
Now now
Now now2
Now now
Now now2
Now now
Now now2
i=2 j=0val=0.33333
ii=6 jj=3val=0.33333
U2(6)(3)(2)=0.33333
Now now
Now now2
Now now
Now now2
Now now
Now now2
i=2 j=4val=0.33333
ii=6 jj=11val=0.33333
U2(6)(11)(2)=0.33333
Now now
Now now2
i=2 j=5val=0.33333
ii=6 jj=17val=0.33333
U2(6)(17)(2)=0.33333
Now now
Now now2
Now now
Now now2
Now now
Now now2
Now now
Now now2
Now now
Now now2
Now now
Now now2
i=3 j=5val=0.66667
ii=9 jj=17val=0.66667
U2(9)(17)(2)=0.66667
Now now
Now now2
i=3 j=6val=0.33333
ii=9 jj=19val=0.33333
U2(9)(19)(2)=0.33333
Now now
Now now2
Now now
Now now2
i=4 j=1val=0.33333
ii=11 jj=4val=0.33333
U2(11)(4)(2)=0.33333
Now now
Now now2
Now now
Now now2
Now now
Now now2
Now now
Now now2
i=4 j=6val=0.66667
ii=11 jj=19val=0.66667
U2(11)(19)(2)=0.66667
Now now
Now now2
i=5 j=0val=0.66667
ii=17 jj=3val=0.66667
U2(17)(3)(2)=0.66667
Now now
Now now2
Now now
Now now2
Now now
Now now2
i=5 j=3val=0.33333
ii=17 jj=9val=0.33333
U2(17)(9)(2)=0.33333
Now now
Now now2
Now now
Now now2
Now now
Now now2
Now now
Now now2
i=6 j=1val=0.33333
ii=19 jj=4val=0.33333
U2(19)(4)(2)=0.33333
Now now
Now now2
Now now
Now now2
i=6 j=3val=0.33333
ii=19 jj=9val=0.33333
U2(19)(9)(2)=0.33333
Now now
Now now2
i=6 j=4val=0.33333
ii=19 jj=11val=0.33333
U2(19)(11)(2)=0.33333
Now now
Now now2
Now
Now2inf
Now37
Now4
inf
0.00000
0.00000
0.00000
0.00000
0.00000
It is very strange that the vector is of size 7 but 6 elements are given in the output. The program freezes at this point and nothing happens until I stop it myself. Any ideas?
#CPLEXOptimizers#DecisionOptimization