I wrote a usercutcallback to separate cuts for a MIP model. There is some memory leak in the callback procedure, which I could not identify. This issue is reflected when repetitively calling the MIP model to solve many instances, where memory usage just piles up! The separation in the callback is done only locally by another library to solve a min cut model, so it should be Ok. I also have a nodecallback to get the depth (int cplex_node_depth) of the current node in order to separate cuts only for nodes on certain depths. I've listed the callback macros down below. Can anyone help me to check where it went wrong. Many thanks in advance!
ILONODECALLBACK0(NodeDepthCallback){
IloInt64 nextNode = 0;
cplex_node_depth = getDepth(nextNode);
//cout << cplex_node_depth << endl;
}
ILOUSERCUTCALLBACK6(BoundingCutsCallback, NumVarMatrix, arc, NumVarMatrix, y, IloNumArray, job_release_time_ilo, IloNumArray, job_frac_UB_ilo, IloNumArray, job_frac_LB_ilo, int, node_depth_choice)
{
assert(MAP_VEC.size() == y.getSize());
// Skip the separation if not at the end of the cut loop
if (!isAfterCutLoop())
return;
if (cplex_node_depth < 3 || cplex_node_depth % node_depth_choice == 0)
{
// get the master env and numbers
IloEnv env = getEnv();
//get num of jobs and planning horizon
int num_job = y.getSize();
int time_horizon = y[0].getSize();
// get the solution of the first stage
// the values of y variables
NumMatrix ySol(env, num_job);
for (int j = 0; j < num_job; j++)
{
ySol[j] = IloNumArray(env);
getValues(ySol[j], y[j]);
//cout << ySol[j] << endl;
}
// the solution of arc variables
NumMatrix arcSol(env, num_job);
for (int j = 0; j < num_job; j++)
{
arcSol[j] = IloNumArray(env);
getValues(arcSol[j], arc[j]);
}
vector<bool> cut_flag(num_job, false);
////array of cut lefthand sides and bool indicators
//IloExprArray cut_expr(env, num_job);
//for (int j = 0; j < num_job; j++)
//{
// cut_expr[j] = IloExpr(env);
//}
////separation
////if (separate_bound_y(arc, arcSol, y, ySol, job_release_time_ilo, job_frac_UB_ilo, job_frac_LB_ilo, cut_flag, cut_expr))//separation with local graphs
//if (separate_bound_y_pointer(arc, arcSol, y, ySol, job_release_time_ilo, job_frac_UB_ilo, job_frac_LB_ilo, cut_flag, cut_expr))//separation with the global pointer
//{
// for (int j = 0; j < num_job; j++)
// {
// if (cut_flag[j] == true)
// {
// add(cut_expr[j] >= 0).end();
// //vio_cuts.add(cut_expr[j] >= 0);
// CUT_NUM++;
// }
// }
//}
//expr containing the cut lefthand side
for (int j = 0; j < num_job; j++)
{
IloExpr cut_expr(env);
if (separate_bound_y_pointer_j(arc, arcSol, y, ySol, job_release_time_ilo, job_frac_UB_ilo, job_frac_LB_ilo, cut_flag, cut_expr, j))
{
add(cut_expr >= 0).end();
// //vio_cuts.add(cut_expr[j] >= 0);
CUT_NUM++;
}
cut_expr.end();
}
//release the memory
for (int j = 0; j < num_job; j++)
{
ySol[j].end();
arcSol[j].end();
//cut_expr[j].end();
}
ySol.end();
arcSol.end();
//cut_expr.endElements();
//release the vector
cut_flag.clear();
cut_flag.shrink_to_fit();
vector<bool>().swap(cut_flag);
return;
}
else
{
return;
}
}