Originally posted by: MatthiasWalter
Dear Daniel,
thanks for the quick reply.
The exception occurs for both 'getValue(lhs[i])' and 'lhs[i] >= xrhs' whatever I put first. I noticed that the exception even occurs outside of ILOUSERCUTCALLBACK3, i.e. in my function Instance::solve_MIP(...) where I build the IloExprArray lhs. When I try to print lhs like
std::cout <<
"lhs[" << i <<
"] (" << lhs.getSize() <<
"): " << lhs[i] << std::endl;
only the getSize() part works. It returns the expected size of the array. lhs[i] causes an exception (access violation).
In the following you will find the content of the call stack window of Microsoft Visual Studio (german language version). I am not sure if that is what you mean when you asked for the stack trace:
Algorithms_MPSWAP_02.exe!IloControlCallbackManager::getValue() + 0x99 Bytes C++
Algorithms_MPSWAP_02.exe!IloCplex::ControlCallbackI::getValue() + 0xd Bytes C++
> Algorithms_MPSWAP_02.exe!CtCallbackI::main() Zeile 48 + 0x49 Bytes C++
Algorithms_MPSWAP_02.exe!IloControlCallbackManager::call() + 0x30 Bytes C++
Algorithms_MPSWAP_02.exe!IloCplexCallbackManager::call() + 0x4c Bytes C++
Algorithms_MPSWAP_02.exe!_cutcallback@20() + 0xda Bytes C++
cplex122.dll!10253222()
http://Unten angegebene Rahmen sind möglicherweise nicht korrekt und/oder fehlen, keine Symbole geladen für cplex122.dll cplex122.dll!102cbc29()
cplex122.dll!1025a3c2()
cplex122.dll!1025cd12()
cplex122.dll!10265baa()
cplex122.dll!104f2780()
cplex122.dll!100200cd()
cplex122.dll!1027bef8()
cplex122.dll!101eb11d()
cplex122.dll!104f2dc3()
cplex122.dll!101e927d()
KernelBase.dll!75286cf2()
cplex122.dll!101bd5b8()
cplex122.dll!101e205e()
cplex122.dll!101e4679()
cplex122.dll!101e211e()
cplex122.dll!101bd51d()
cplex122.dll!1011e809()
cplex122.dll!1011e816()
Algorithms_MPSWAP_02.exe!IloCplexI::solve() + 0xd1 Bytes C++
Algorithms_MPSWAP_02.exe!IloAlgorithm::solve() + 0x3d Bytes C++
Algorithms_MPSWAP_02.exe!IloCplex::solve() Zeile 2804 + 0x2b Bytes C++
Algorithms_MPSWAP_02.exe!Instance::solve_Standard_MIP_Cuts(int & cInst=1, std::basic_ofstream<char,std::char_traits<char> > & oFstreamOutputFile={...}, int & intTimeLim=15, int & intMaxNumProcedures=10, std::vector<std::vector<bool,std::allocator<bool> >,std::allocator<std::vector<bool,std::allocator<bool> > > > * xStartSol=
http://...()) Zeile 680 + 0xb Bytes C++
Algorithms_MPSWAP_02.exe!main(int argc=1, char * * argv=0x00862420) Zeile 155 C++
Algorithms_MPSWAP_02.exe!__tmainCRTStartup() Zeile 266 + 0x12 Bytes C
kernel32.dll!77011114()
ntdll.dll!76edb299()
ntdll.dll!76edb26c()
The line
> Algorithms_MPSWAP_02.exe!CtCallbackI::main() Zeile 48 + 0x49 Bytes C++
refers to line 48 in my code, that is
if (xrhs < IloInfinity && getValue(lhs[i]) < xrhs - eps)
{
where the exception occurs (it is the first time lhs[i] is encountered during execution).
I am not sure if I defined/how to define the NDEBUG macro. In the project properties > C/C++ > Preprocessor > Preprocessor definitions the entry reads as follows:
WIN32;NDEBUG;_CONSOLE;IL_STD
If I delete NDEBUG from that list, the exception does also occur.
I have the parameter specifying the number of threads at default (just like the other parameters). Log then says:
>>MIP search method: traditional branch-and-cut.
>>Parallel mode: none, using 1 thread.
Though, if I set IloCplex::Threads to 2 (my maximum number of threads) log reads as:
>>MIP search method: traditional branch-and-cut.
>>Parallel mode: opportunistic, using up to 2 threads.
In both cases the exception occurs.
When I use the following code where I build the left-hand-side expression within the cut callback function everything works fine.
ILOUSERCUTCALLBACK5(CtCallback, IloArray<IloBoolVarArray>, x, IloArray<IloNumArray>, rhs, Instance*, Inst, int&, intUserCut1Counter, IloNum, eps)
{
//Variable for the right-hand-side value IloNum xrhs;
for(
int s = 0; s < Inst->S; ++s)
{ xrhs = rhs[s][…];
if (xrhs < IloInfinity)
{
//Variable to store the value of the left-hand-side of the cut IloNum lhs; lhs = 0; IloExpr expr(getEnv());
for(v=0; v < V; ++v)
{
for(w=0; w < W; ++w)
{ lhs += getValue(x[v][w]); expr += x[v][w];
}
}
//If the solution is not feasible ...
if(lhs < xrhs - eps)
{ IloRange cut;
//... add the cut
try
{ cut = (expr >= xrhs); add(cut); cut.end(); rhs[s][...] = IloInfinity; ++intUserCut1Counter;
//cout << endl << "User cut 1 applied." << endl;
}
catch (...)
{ cut.end();
throw;
}
}
}
}
}
There I pass the vector x of decision variables via
cplex.use(CtCallback(env, x, IloNumArrayCutRhs, this, intUserCut1Counter, cplex.getParam(IloCplex::EpRHS)));
I hope this helps to let you identify the problem.
Kind regards
Matthias Walter
#CPLEXOptimizers#DecisionOptimization