Decision Optimization

 View Only
Expand all | Collapse all

I have a very big LP problem that needs to be solved and must be solved many times. How to modify the existing cplex model in C++

  • 1.  I have a very big LP problem that needs to be solved and must be solved many times. How to modify the existing cplex model in C++

    Posted Tue August 10, 2021 05:35 AM
    I have a very big LP problem that needs to be solved and must be solved many times. How to modify the existing cplex model in C++

    Every time, I just need to change some coefficients and rerun.

    So my strategy is to develop a model of the basic problem and save it.

    Every time, I get a copy of the basic model and try to change the coefficients.

    The question is how to change the coefficient of the new copy.

    I know how to change the coefficients when creating a model. But I don't want to repeat the creation process because it takes a lot of time.

    My LP model was build by row. Is there a direct way to change the coefficients without creating the model again?

    ------------------------------
    Zhaojin LI
    ------------------------------

    #DecisionOptimization


  • 2.  RE: I have a very big LP problem that needs to be solved and must be solved many times. How to modify the existing cplex model in C++

    IBM Champion
    Posted Tue August 10, 2021 02:43 PM
    If you build the initial model "row-wise" (using instances of IloRange), you can use IloRange.setLinearCoef() or IloRange.setLinearCoefs() to update coefficients in the original model. You need to be careful not only to update things changing in the next version but also reset things (if any) that were changed in the previous version and need to change back to their original settings. The IloObjective class has methods of the same name, so you can update the objective function as well.

    ------------------------------
    Paul Rubin
    Professor Emeritus
    Michigan State University
    ------------------------------



  • 3.  RE: I have a very big LP problem that needs to be solved and must be solved many times. How to modify the existing cplex model in C++

    Posted Tue August 10, 2021 04:26 PM

    Dear professor,

    Thank for you reply,

    My model was build as follows, is this in "row-wise"or in "column-wise"? Can i use the commend "IloRange.setLinearCoef()"?

    model_single=IloModel (env44);
    cplex_single=IloCplex(env44);

    x_single=NumVarMatrix (env44,nEdge);
    for(int j= 0;j<nEdge;j++)
    {
    x_single[j]=IloNumVarArray(env44,nTrans);
    for(int k=0;k<nTrans;k++)
    {
    x_single[j][k] = IloNumVar(env44,0,1,ILOINT);
    }
    }

    w_single=NumVar3Matrix (env44,nVert+1);
    for(int v=0;v<=nVert;v++)
    {
    w_single[v]=NumVarMatrix(env44,nTrans);
    for(int n1=0;n1<nTrans;n1++)
    {
    w_single[v][n1]=IloNumVarArray(env44,nTrans);
    for(int n2=0;n2<nTrans;n2++)
    {
    w_single[v][n1][n2]=IloNumVar(env44,0,1,ILOINT);
    }
    }
    }


    IloExpr expr1(env44);IloExpr expr2(env44);IloExpr expr(env44);
    //part1
    for(int j=0;j<nEdge;j++)
    {
    for(int k=0;k<nTrans;k++)
    {

    expr1+=(ccustomer_capacity[i_th]*unit_cost[j][k]-lamda_1[0]*service_quality[j][k])*x_single[j][k];
    }
    }
    //part2
    for(int v=1;v<=nVert;v++)
    {
    for(int n1=0;n1<nTrans;n1++)
    {
    for(int n2=0;n2<nTrans;n2++)
    {
    expr2+=(customer_capacity[i_th]*transhipment_unitcost[n1][n2])*w_single[v][n1][n2];
    }
    }
    }

    expr+=expr1+expr2;
    model_single.add(IloMinimize(env44,expr));
    expr.end();expr1.end();expr2.end();
    //add constraints1
    for(int j=0;j<nEdge;j++)
    {
    IloExpr expr1(env44);
    IloExpr expr2(env44);
    IloExpr expr3(env44);
    for(int k=0;k<nTrans;k++)
    {
    expr1+=x_single[j][k]*service_quality[j][k];
    expr2+=x_single[j][k]*customer_service_quality[i_th];
    }
    expr3=expr2-expr1;
    model_single.add(expr3<=0);
    expr1.end();
    expr2.end();
    expr3.end();
    }
    //add constraints2
    //add constraints3
    ......
    cplex_single.solve();
    ......



    ------------------------------
    Zhaojin LI
    ------------------------------



  • 4.  RE: I have a very big LP problem that needs to be solved and must be solved many times. How to modify the existing cplex model in C++

    IBM Champion
    Posted Tue August 10, 2021 08:06 PM
    Yes, that is row-wise. When you invoke model_single.add() on a single objective expression or constraint, it returns an instance of IloExtractable, which you will need to store somewhere if you plan to modify it. When the time comes to make the modifications, I believe you will need to cast the IloExtractable to either IloRange or IloObjective (whichever is appropriate) and then use the corresponding setLinearCoef() or setLinearCoefs() method.

    In the interest of full disclosure, I haven't used the C++ API in about 30 years or so, so I might not have this completely correct. You should probably test it on a small problem first.

    ------------------------------
    Paul Rubin
    Professor Emeritus
    Michigan State University
    ------------------------------



  • 5.  RE: I have a very big LP problem that needs to be solved and must be solved many times. How to modify the existing cplex model in C++

    Posted Wed August 11, 2021 03:18 AM
    Dea Paul,

    Your answer is very helpful for my problem solving. Thank you very much.

    ------------------------------
    Zhaojin LI
    ------------------------------



  • 6.  RE: I have a very big LP problem that needs to be solved and must be solved many times. How to modify the existing cplex model in C++

    Posted Wed August 11, 2021 05:03 AM
    Edited by System Fri January 20, 2023 04:36 PM
    My code is as follow:

    void single_order()
    {
        model_single=IloModel (env44);
        cplex_single=IloCplex(env44);

        x_single=NumVarMatrix (env44,nEdge);
        for(int j= 0;j<nEdge;j++)
        {
            x_single[j]=IloNumVarArray(env44,nTrans);
            for(int k=0;k<nTrans;k++)
            {
                x_single[j][k] = IloNumVar(env44,0,1,ILOINT);
            }
        }

        w_single=NumVar3Matrix (env44,nVert+1);
        for(int v=0;v<=nVert;v++)
        {
            w_single[v]=NumVarMatrix(env44,nTrans);
            for(int n1=0;n1<nTrans;n1++)
            {
                w_single[v][n1]=IloNumVarArray(env44,nTrans);
                for(int n2=0;n2<nTrans;n2++)
                {
                    w_single[v][n1][n2]=IloNumVar(env44,0,1,ILOINT);
                }
            }
        }

        IloExpr expr1(env44);IloExpr expr2(env44);IloExpr expr(env44);
        //part1
        for(int j=0;j<nEdge;j++)
        {
            for(int k=0;k<nTrans;k++)
            {
               expr1+=(ccustomer_capacity[i_th]*unit_cost[j][k]-lamda_1[0]*service_quality[j][k])*x_single[j][k];
            }
        }
        //part2
        for(int v=1;v<=nVert;v++)
        {
            for(int n1=0;n1<nTrans;n1++)
            {
                for(int n2=0;n2<nTrans;n2++)
                {
                    expr2+=(customer_capacity[i_th]*transhipment_unitcost[n1][n2])*w_single[v][n1][n2];
                }
            }
        }

        expr+=expr1+expr2;
        model_single.add(IloMinimize(env44,expr));
        expr.end();expr1.end();expr2.end();

        //add constraints1
        for(int j=0;j<nEdge;j++)
        {
            IloExpr expr1(env44);
            IloExpr expr2(env44);
            IloExpr expr3(env44);
            for(int k=0;k<nTrans;k++)
            {
                expr1+=x_single[j][k]*service_quality[j][k];
                expr2+=x_single[j][k]*customer_service_quality[i_th];
            }
            expr3=expr2-expr1;
            model_single.add(expr3<=0);
            expr1.end();
            expr2.end();
            expr3.end();
        }
        //add constraints2
        ......
        //add constraints3
        ......
    }

    When i want to solve the model, i use the following code:

    void main()
    {
        //the first time i solve the model build;
       single_order();

      cplex_single.extract(model_single);
      cplex_single.solve();
      env44.out() << "cost1:" << cplex_single.getObjValue() << endl;
         
        // the second time i solve the model build,before i solve the model, i will modify the coefficient of the objective function;
          for(int j=0;j<nRequest;j++)
       {
          for(int k=0;k<nTrans;k++)
          {
              cplex_single.getObjective().setLinearCoef(x_single[j][k],100);//only change the coefficient of variable "x_single" in the objective function
          }
       }
        cplex_single.solve();
        env44.out() << "cost2:" << cplex_single.getObjValue() << endl;

    }

    However, when i compare these two objective function value "cost1" and "cost2", i found they are the same.
    I think the second time i solve the problem,i failed to modify the  coefficient of variable "x_single" in the objective function.
    I want to know why?




    ------------------------------
    Zhaojin LI
    ------------------------------



  • 7.  RE: I have a very big LP problem that needs to be solved and must be solved many times. How to modify the existing cplex model in C++

    IBM Champion
    Posted Wed August 11, 2021 03:06 PM
    Again, I have not used C++ in a long, long time. Is it possible that, after changing the objective, you need to re-extract the model before solving it?

    ------------------------------
    Paul Rubin
    Professor Emeritus
    Michigan State University
    ------------------------------



  • 8.  RE: I have a very big LP problem that needs to be solved and must be solved many times. How to modify the existing cplex model in C++

    Posted Thu August 12, 2021 05:09 AM
    Dear Paul,

    When  i extract the model,the coefficient of variable "x_single" in the objective function has been successfully modified.
    Thank you very much.


    ------------------------------
    Zhaojin LI
    ------------------------------



  • 9.  RE: I have a very big LP problem that needs to be solved and must be solved many times. How to modify the existing cplex model in C++

    Posted Thu August 12, 2021 11:50 AM
    Edited by System Fri January 20, 2023 04:47 PM
    Except modifying the  coefficient of variable "x_single" in the objective function,I want also to modify the Parameter (constant) "i_th" in the cplex model before i solve this model in the second time.

    The picture below shows the Parameter (constant) i want to modify before i sovle the model in the second time.
    what should i do before i extract  and solve the model?




    ------------------------------
    Zhaojin LI
    ------------------------------



  • 10.  RE: I have a very big LP problem that needs to be solved and must be solved many times. How to modify the existing cplex model in C++

    IBM Champion
    Posted Thu August 12, 2021 02:43 PM
    We are really stretching my understanding of the C++ API here. I would try the following. First, in the code that generates the constraint, I would replace
    model_single.add(expr3<=0);​

    with

    IloExtractable remember_me = model_single.add(expr3 <= 0);

    When the time came to make the proposed change, I would recompute expr3 using the same nested loops and then use

    model_single.remove(remember_me);
    remember_me = model_single.add(expr3 <= 0);
    

    (and re-extract the model before solving).



    ------------------------------
    Paul Rubin
    Professor Emeritus
    Michigan State University
    ------------------------------



  • 11.  RE: I have a very big LP problem that needs to be solved and must be solved many times. How to modify the existing cplex model in C++

    Posted Thu August 12, 2021 04:28 PM
    wow, it's cool, you can still remember so many C++ API Code and commands.

    There are 10 constraints in my cplex model. In each constraint, an input data named "i_th" is used. "i_th" is an input data of type int.  Actually, i want to modify the input data "i_th" before i solve the model in second time. "i_th" is used as the following picture:

    If I replace 

    model_single.add(expr3<=0);​
    with 
    IloExtractable remember_me = model_single.add(expr3 <= 0);​

    I may need to try this process 10 times (one time coresponding to  one constraint);  Compared with rebuildind model and solve it, this method maynot save time.

    Is there any other method to modify the input data "i_th" directly before i resolve the model?












    ------------------------------
    Zhaojin LI
    ------------------------------



  • 12.  RE: I have a very big LP problem that needs to be solved and must be solved many times. How to modify the existing cplex model in C++

    IBM Champion
    Posted Thu August 12, 2021 04:37 PM
    You can calculate the change in each coefficient (the difference between the coefficient with the old "i-th" value and the coefficient with the new "i-th" value) and then, for each affected variable, get the old coefficient, add the incremental change to that and set it as the new coefficient value. My guess is that will actually be slower than what I suggested, but it might be a bit faster. You would have to try both methods.

    There is no way to tell the CPLEX model "change the value of i_th to this" or "change the value of customer_service_quality[i_th] to this", because neither i-th nor customer_service_quality[i_th] is directly embedded in the model. The model knows the current coefficient of x_single[j][k] in expr3, but not all the individual ingredients of that coefficient.

    ------------------------------
    Paul Rubin
    Professor Emeritus
    Michigan State University
    ------------------------------



  • 13.  RE: I have a very big LP problem that needs to be solved and must be solved many times. How to modify the existing cplex model in C++

    Posted Fri August 13, 2021 02:57 AM
    Edited by System Fri January 20, 2023 04:15 PM
    Your answer is of great help to me, and i will try both method.  Thank you very much.

    ------------------------------
    Zhaojin LI
    ------------------------------