Decision Optimization

Decision Optimization

Delivers prescriptive analytics capabilities and decision intelligence to improve decision-making.


#Analytics
#DecisionOptimization
#DecisionOptimization
 View Only
  • 1.  Migrating implemented callbacks from Cplex v12.1 to Cplex v12.3

    Posted 07/13/12 12:29 AM

    Originally posted by: Soheilmn


    Hi all,

    I have a C++ code with some implemented callbacks using ILOCUTCALLBACKn macros. The code was fully functional when I had Cplex 12.1 with Visual Studio 2005 installed on my system. After migrating to Cplex v12.3 with Visual Studio 2010, I got compiler error with the above macros. I did a quick online search and it seemed to me that on the newer version of Cplex, the same macros are called ILOUSERCALLBACKn. So I changed all my implemented macros accordingly and although the code gets compiled successfully, I see that callbacks are never called when cplex.solve is called. I even tried ILOMIPCALLBACKn and I got compiler error for using .add method inside my callback. Anyone can shed some light on the issue that I faced?

    Thanks,
    Soheil
    #CPLEXOptimizers
    #DecisionOptimization


  • 2.  Re: Migrating implemented callbacks from Cplex v12.1 to Cplex v12.3

    Posted 07/13/12 02:36 AM

    Originally posted by: SystemAdmin


    Just to be sure: You used ILOUSERCUTCALLBACKn and not ILOUSERCALLBACKn (which you wrote in your post and which I think does not exist)?
    So the only thing you changed is the name of this macro? And then the callback is never invoked? That sounds weird. Could you show us the CPLEX log output?
    BTW: Since you are upgrading anyway, why not upgrade to the most recent version, which is 12.4.0.1?
    #CPLEXOptimizers
    #DecisionOptimization


  • 3.  Re: Migrating implemented callbacks from Cplex v12.1 to Cplex v12.3

    Posted 07/13/12 11:11 PM

    Originally posted by: Soheilmn


    Thanks Daniel for your reply. You are right, so I changed ILOCUTCALLBACK4 in my old code to ILOUSERCUTCALLBACK4, and that was the only change that I made in the code. The callback is never invoked, and Cplex terminates immediately by declaring 0 as the optimal objective value, which makes sense because my initial model has no non-trivial constraints, and it's callback's job to add constraints gradually.
    About your second question, I was worried that the last version may not be yet stable, and as general rule I always avoid upgrading to the last version. Do you really think if I would switch to v12.4, it would solve the above issue?

    By the way, the following is my code. I thought that it might be helpful.

    Best,
    Soheil
    // ****************************************************************************************************************
    // ************************************************* The function that invokes the callback ***********************
    // ****************************************************************************************************************
    void runSimplePenalty_V_W_Callback( char* fileData, char* fileResultPath, char flw_formulation_type, bool myInequalityToBeAdded)
    {
    clock_t clockCPLEX_Begin, clockCPLEX_End;

    ofstream fileResult;
    fileResult.open(fileResultPath,ios::out);
    fileResult.close();

    IloEnv env;
    DATA data(env);
    data.readData(fileData);

    MASTERP masterp(env, data);
    masterp.buildModel(data);

    IloCplex cplexM(masterp.masterModel);
    //cplexM.setOut( env.getNullStream() );
    //cplexM.setParam (IloCplex::TiLim, 1200);

    if (flw_formulation_type == 'v')
    cplexM.use( V_MODELCUTCALLBACK(env, data, masterp.TAU, masterp.X, myInequalityToBeAdded) );
    else
    cplexM.use( W_MODELCUTCALLBACK(env, data, masterp.TAU, masterp.X, myInequalityToBeAdded) );

    clockCPLEX_Begin=clock();
    cplexM.solve();
    clockCPLEX_End=clock();
    double global_numClockSpentAtCPLEXSolver = clockCPLEX_End - clockCPLEX_Begin;

    // *******************************************
    // Writing the output in a file
    // *******************************************
    cout << "Optimal objective value is:" << cplexM.getObjValue() << "\n";
    }

    // ****************************************************************************************************************
    // ***************************** Callback Macro *******************************************************************
    // ****************************************************************************************************************

    ILOUSERCUTCALLBACK4 (V_MODELCUTCALLBACK,
    DATA &, data,
    IloNumVar, TAU,
    IloNumVarArray, X,
    bool, myInequalityToBeAdded)
    {
    // **************************************************************************************
    // This ILOCUTCALLBACK implements the penalty cuts using V formulation for the follower
    // problem with penalty coefficients in the objective function.
    // **************************************************************************************

    bool integerSolution=true;
    for (int i=0; i<data.n; i++)
    if ( getFeasibility(X[i]) == Infeasible )
    {
    integerSolution=false;
    break;
    }

    if (integerSolution)
    {
    IloEnv env=getEnv();
    IloEnv env1;

    IloNumArray x(env1, data.n);
    for (int i=0; i<data.n; i++)
    if ( getValue(X[i]) < EPS )
    x[i] = 0;
    else
    x[i] = 1;
    FLW4BIGM flw4bigm(env1, data);
    flw4bigm.buildModel(data, x);

    IloCplex cplex(flw4bigm.flw4Model);
    cplex.setParam (IloCplex::TiLim, 1200);
    cplex.setOut( env.getNullStream() );
    cplex.solve();

    double subproblem_objective = cplex.getObjValue();
    double tau_value=getValue(TAU);
    if (tau_value==4051)
    cout << "tau_value==4051\n";
    if ( (tau_value + EPS) <subproblem_objective )
    {
    NumMatrix y(env1, data.n);
    for (int i=0; i<data.n; i++)
    {
    y[i]=IloNumArray(env1, data.T);
    if (cplex.getValue(flw4bigm.Y[i][0]) < EPS )
    y[i][0] = 0;
    else
    y[i][0] = 1;
    }
    calcYmatrix (y, data);

    int RHS=0;
    IloExpr expr1(env);
    for (int i=0; i<data.n; i++)
    {
    RHS += ( data.r[i][0] ) * y[i][0];
    for (int t=1; t<data.T; t++)
    RHS += data.r[i][t] * (y[i][t] - y[i]t-1);
    expr1 += y[i][0] * data.bigMvector[i] * X[i];
    }
    add( TAU + expr1 >= RHS );

    // *******************************************************
    ofstream outFile;
    outFile.open("c:/DSI/XY_V.txt",ios::app);
    outFile << "[" << x[0];
    for (int i=1; i<data.n; i++)
    outFile << ", " << x[i];
    outFile << "]\n";
    for (int i=0; i<data.n; i++)
    outFile << y[i] << "\n";
    outFile << tau_value << "\n";
    outFile << subproblem_objective << "\n";
    outFile << "**\n";
    outFile.close();
    // *******************************************************
    // *******************************************************
    // Here we add (the aggregated form of) my inequality if
    // myInequalityToBeAdded is set to be TRUE.
    // *******************************************************

    if (myInequalityToBeAdded)
    {
    IloExpr expr2(env);
    IloExpr expr3(env);
    int UminusP_size=0; // This will store the size of the set U\P where U:Uninfected, P=Protected.

    for (int i=0; i<data.n; i++)
    {
    if (x[i]==1)
    expr3 += 1 - X[i];

    else
    if (y[i]http://data.T-1==0 ) // that is the node is unprotected and uninfected
    {
    expr2 += X[i];
    UminusP_size++;
    }
    }

    if ( UminusP_size > 0) //i.e., if we have any unproteced and uninfected node
    add ( expr2 - UminusP_size * expr3 <= 0);

    expr2.end();
    expr3.end();
    }

    expr1.end();
    for (int i=0; i<data.n; i++)
    y[i].end();
    }
    cplex.end();
    flw4bigm.flw4Model.end();
    for (int i=0; i<data.n; i++)
    for (int t=1; t<data.T; t++)
    for (int m=1; m<data.AA[i].getSize()+1; m++)
    flw4bigm.C1[i][t][m].end();

    for (int i=0; i<data.n; i++)
    for (int t=1; t<data.T; t++)
    for (int m=2; m<data.AA[i].getSize()+1; m++)
    flw4bigm.C2[i][t][m].end();

    for (int i=0; i<data.n; i++)
    flw4bigm.C3[i].end();

    flw4bigm.flw4ObjFixedTerm.end();
    flw4bigm.flw4Obj.end();
    x.end();
    env1.end();
    }
    }
    #CPLEXOptimizers
    #DecisionOptimization


  • 4.  Re: Migrating implemented callbacks from Cplex v12.1 to Cplex v12.3

    Posted 07/14/12 02:45 AM

    Originally posted by: SystemAdmin


    Aha, so your callback produces cuts that cut off integer feasible solutions?
    In that case your are not adding cuts but lazy constraints. This means you should use ILOLAZYCONSTRAINTCALLBACKn instead of ILOUSERCUTCALLBACKn.
    You should have used ILOLAZYCONSTRATINCALLBACKn already in 12.1. Your code only worked due to some inconsistencies in CPLEX's callback implementations. These inconsistencies have been rectified since then.
    Maybe also read about the difference between cuts and lazy constraints in the User Manual.
    #CPLEXOptimizers
    #DecisionOptimization