Originally posted by: BrunoAsiv
Hi,
I have a user cut callback in which I create a LP. When I solve this LP, some of the variables take values that are outside the bounds I have set for them: they have negative values even though they are supposed to be >= 0.
I have tested their bounds with getLB() just before and after solving the problem and the bounds seem to be in place. I check the variable values right after solving the problem so I don't think it's possible for them to be changed from their optimal solution values. Also, when I use cplex "interactively" to read the .lp file which I export right before solving the problem in my c++ code, I get a solution where the variables do respect their bounds. The problem described in the .lp file matches the theoretical formulation I'm aiming for.
Any ideas on what could be the cause of this problem?
Here is a condensed version of my usercut callback code up to where I solve the LP. I have removed the irrelevant parts:
ILOUSERCUTCALLBACK4(UserCutCallback2, IloModel, model_cb, IloNumVarArray, var_cb, IloBoolVarArray, bool_var_cb, adjacency_list_t, adjacency_list5)
{
IloEnv masterEnv = getEnv();
IloEnv env_uccb;
IloModel model_uccb(env_uccb);
IloObjective objec_uccb = IloMinimize(env_uccb);
IloNumVarArray var_gamma_uccb(env_uccb);
IloNumVarArray var_gamma_y_uccb(env_uccb);
IloNumVarArray var_gamma_1y_uccb(env_uccb);
IloNumVarArray var_theta_uccb(env_uccb);
IloRangeArray con_1_uccb(env_uccb);
IloRangeArray con_2_uccb(env_uccb);
IloRangeArray con_3_uccb(env_uccb);
for(int i = 0; i < number_of_y; i++)
{
stringstream sss;
sss << "gamma_" << i;
var_gamma_uccb.add(IloNumVar(env_uccb, 0.0, IloInfinity));
var_gamma_uccb[i].setName(sss.str().c_str());
sss.str(std::string());
sss << "gamma_Y_" << i;
var_gamma_y_uccb.add(IloNumVar(env_uccb, 0.0, IloInfinity));
var_gamma_y_uccb[i].setName(sss.str().c_str());
sss.str(std::string());
sss << "gamma_1-Y_" << i;
var_gamma_1y_uccb.add(IloNumVar(env_uccb, 0.0, IloInfinity));
var_gamma_1y_uccb[i].setName(sss.str().c_str());
}
for(int i = 0; i < number_of_nodes; i++)
{
stringstream sss;
sss << "theta_" << i;
var_theta_uccb.add(IloNumVar(env_uccb));
var_theta_uccb[i].setName(sss.str().c_str());
}
for(int mg = 0; mg < number_of_y; mg++)
{
objec_uccb.setLinearCoef(var_gamma_y_uccb[mg], getValue(bool_var_cb[mg]));
objec_uccb.setLinearCoef(var_gamma_1y_uccb[mg], (1 - getValue(bool_var_cb[mg])));
}
model_uccb.add(objec_uccb);
for( int b = 0; b < links.size(); b++ )
{
//building the benders subproblem dual (1)
IloExpr expa(env_uccb); //building part of constraints group #1
cout << "orii: " << links[b][0] << " dest: " << links[b][1] << "\n";
expa += (1) * var_theta_uccb[links[b][0] - 1]; //add theta i
expa += (-1) * var_theta_uccb[links[b][1] - 1]; //add theta j
con_1_uccb.add(expa >= -(omega * adjacency_list5[link_order[b][0]][link_order[b][1]].weight2)); //add rht (base utility * omega)
expa.end();
}
for ( int mg = 0; mg < number_of_y; mg++)
{
//building the benders subproblem dual (2)
cout << "This res is on arc: " << whys[mg][0] << "\n";
IloExpr expa(env_uccb); //building constraints group #2
expa += (1) * var_gamma_uccb[mg]; //add gamma
expa += (1) * var_gamma_y_uccb[mg]; //add gamma y
expa += (-1) * var_gamma_1y_uccb[mg]; //add gamma 1 - y
con_2_uccb.add(expa >= bigeps[mg][d]);
expa.end();
//completing constraints group #1
con_1_uccb[whys[mg][0]].setLinearCoef(var_gamma_uccb[mg], -1); //add gamma
con_1_uccb[whys[mg][0]].setLinearCoef(var_gamma_1y_uccb[mg], 1); //add gamma 1 - y
model_uccb.add(con_1_uccb); //add con 1 to model
model_uccb.add(con_2_uccb); //add con 2 to model
}
if(odpairs[f][(d+1) * 2] > 0)
{
//building the benders subproblem dual (3)
cout << " od pair: " << f << endl << endl;
cout << "ori: " << odpairs[f][0] << " desti: " << odpairs[f][1] << "\n";
objec_uccb.setLinearCoef(var_theta_uccb[odpairs[f][1] - 1], (-1));
IloExpr expa(env_uccb);
expa += (1) * var_theta_uccb[odpairs[f][0] - 1];
con_3_uccb.add(expa == 0);
expa.end();
model_uccb.add(con_3_uccb);
IloCplex cplex_uccb(model_uccb);
std::stringstream p_name;
nb_iter2++;
p_name << "uccb_prob_" << usercut_call_back_counter - 1 << "_" << nb_iter2 << ".lp";
cplex_uccb.exportModel(p_name.str().c_str());
float obj_value = 0;
for(int i = 0; i < number_of_y; i++)
{
cout << var_gamma_uccb[i].getLB() << "\n";
cout << var_gamma_y_uccb[i].getLB() << "\n";
cout << var_gamma_1y_uccb[i].getLB() << "\n";
}
if(1 == 1) //change to proper check later
{
// Optimize the problem and obtain solution.
if ( !cplex_uccb.solve() ) {
env_uccb.error() << "Failed to optimize UCCB" << endl;
throw(-1);
}
obj_value = cplex_uccb.getObjValue();
cout << "\n\nprint out of gammas\n\n";
cout << "gamma gamma y gamma 1-y\n";
for( int vv = 0; vv < number_of_y; vv++)
{
cout << cplex_uccb.getValue(var_gamma_uccb[vv]) << " " << getValue(var_gamma_y_uccb[vv]) << " " << getValue(var_gamma_1y_uccb[vv]) << "\n";
}
cout << "\n\n";
}
#CPLEXOptimizers#DecisionOptimization