Decision Optimization

Decision Optimization

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


#Analytics
#DecisionOptimization
#DecisionOptimization
 View Only
  • 1.  SolveCallback: Problems with useSolution

    Posted 04/07/12 08:25 PM

    Originally posted by: SystemAdmin


    Hi to all,
    I am currently solving a problem using a branch-and-price scheme. Since CPLEX does not support B&P over column generation formulations (i.e., does not let you include additional variables while branching), I decided to branch over the original variables of an aggregated formulation that I have. The idea is, as in many branch and price schemes, to stop CPLEX before solving the problem at each node, then, use the information of the node to solve a reformulation of the problem via column generation (which produces a better bound), and finally, reconstruct the solution found in terms of the variables of the aggregated formulation, pass it to CPLEX, and ask it to use it instead of using the solution that would be produced if the aggregated formulation is solved. To do that, I know from the
    
    AdMIPex6
    
    example that you can use a
    
    SolveCallback
    
    .

    Basically, if I understand it correctly, in the
    
    SolveCallback
    
    what you do is set the values of the variables using
    
    setVectors
    
    . You do not even need to set all the variables, just some of them; CPLEX would find the values of the other variables (if a valid feasible solution exists with the given values). Now, if you just use
    
    setVectors
    
    , CPLEX will use the solution as an initial value, but it will try to continue solving the node. To stop CPLEX you have to include
    
    useSolution()
    
    and CPLEX will use the given solution. Am I correct?

    I try to use that but I was getting the following exception:

    Concert Error: ilog.cplex.CpxException: CPLEX Error 3019: Failure to solve MIP subproblem.

    I try several things to ensure that the solution that I was passing was feasible and correct, but all the effort was in vain, I was still getting the same exception. Then, I decided to use the same approach in a simpler problem (as a prove of concept) just to see if I was able to do it correctly. I came up with the following example:

    max x+y

    s.t.

    2x+2y<=3
    -x+y<=2

    x,y in {0,1}

    The optimal solution is x=1, y=0, but the relaxation is x=0.5,y=1.

    Using the
    
    SolveCallback
    
    I try to pass optimal solution but I still get the same problem (Concert exception caught: ilog.cplex.CpxException: CPLEX Error 3019: Failure to solve MIP subproblem.)

    The code I used follows (I use Java). I apologize for this code. I know that the way I formulated is probably the ugliest way for doing it, but I was not paying too much attention to the details, I just wanted to do it fast.

    Do you have any ideas or suggestions?

    Thanks a lot in advance.

    -Jose

    
    
    
    import ilog.concert.*; 
    
    import ilog.cplex.*;     
    
    public 
    
    class TestOfAdMIPex6 
    { 
    
    static 
    
    class Solve 
    
    extends IloCplex.SolveCallback 
    { 
    
    boolean     _done = 
    
    false; IloNumVar[] x; IloNumVar[] y; Solve(IloNumVar[] x, IloNumVar[] y) 
    { this.y = y; this.x = x; 
    }   
    
    public 
    
    void main() 
    
    throws IloException 
    { 
    
    double num[]= 
    
    new 
    
    double[1]; num[0]=1; setVectors(num, x, null, 
    
    null); num[0]=0; setVectors(num, y, null, 
    
    null); useSolution(); 
    } 
    }   
    
    public 
    
    static 
    
    void main(String[] args) 
    { 
    
    try 
    { IloCplex cplex = 
    
    new IloCplex();   IloNumVar[] x= 
    
    new IloNumVar[1]; IloNumVar[] y= 
    
    new IloNumVar[1];   x[0]=cplex.numVar(0.0, 1.0, IloNumVarType.Bool, 
    "x"); y[0]=cplex.numVar(0.0, 1.0, IloNumVarType.Bool, 
    "y");   IloLinearNumExpr lin=cplex.linearNumExpr();   
    //Constraint 1 lin.addTerm(2, x[0]); lin.addTerm(2, y[0]); cplex.addLe(lin, 3);   lin.clear(); 
    //Constraint 2 lin.addTerm(-1, x[0]); lin.addTerm(1, y[0]); cplex.addLe(lin, 2);   lin.clear(); 
    //OF lin.addTerm(1, x[0]); lin.addTerm(1, y[0]); cplex.addMaximize(lin); cplex.use(
    
    new Solve(x,y));   cplex.setParam(IloCplex.BooleanParam.PreInd, 
    
    false); cplex.setParam(IloCplex.IntParam.Threads, 1); cplex.setParam(IloCplex.IntParam.MIPSearch, IloCplex.MIPSearch.Traditional); cplex.setParam(IloCplex.IntParam.HeurFreq, -1);
    //turn off heuristic cplex.setParam(IloCplex.DoubleParam.CutsFactor , 1.0);
    //add no cuts cplex.setParam(IloCplex.IntParam.Reduce, 0);   cplex.solve(); System.out.println(
    "Relaxed solution status = " + cplex.getStatus()); System.out.println(
    "Relaxed solution value  = " + cplex.getObjValue()); System.out.println(
    "x  = " + cplex.getValue(x[0])); System.out.println(
    "y  = " + cplex.getValue(y[0])); cplex.setParam(IloCplex.IntParam.MIPSearch, IloCplex.MIPSearch.Traditional); 
    
    if ( cplex.solve() ) 
    { System.out.println(
    "Solution status = " + cplex.getStatus()); System.out.println(
    "Solution value  = " + cplex.getObjValue()); 
    } cplex.end(); 
    } 
    
    catch (IloException e) 
    { System.err.println(
    "Concert exception caught: " + e); 
    } 
    } 
    }
    

    #CPLEXOptimizers
    #DecisionOptimization


  • 2.  Re: SolveCallback: Problems with useSolution

    Posted 04/08/12 03:31 AM

    Originally posted by: SystemAdmin


    OK,

    I just figured out that you need to include the command solve() to make it work. However, I realized I have another problem and, by following other trends in this forum, I realized that some other people have experienced similar problems while using B&P and Lagrangian relaxations.

    I have a question. Is it possible to modify the lower bound of a variable inside the solveCallback?

    I am using
    x[0].setLB
    


    but I am getting:

    Invalid memory access of location 0x1c rip=0x10df24320.

    I also tried to do it inside of a Branch callback.

    Any ideas?

    Thanks a lot.
    #CPLEXOptimizers
    #DecisionOptimization


  • 3.  Re: SolveCallback: Problems with useSolution

    Posted 04/11/12 11:29 AM

    Originally posted by: SystemAdmin


    I think you misunderstood the API of the solve callback. The purpose of the solve callback is (from the reference documentation):
    It allows you to set a starting point for the solve or to select the algorithm on a per-node basis.
    

    So the only things you can do is to specify a starting point for the solve and/or select the algorithm that CPLEX should use to solve the current node. This has the following consequences:
    • You can not inject an arbitrary solution.
    • If you call useSolution() without calling solve() before then there is no solution that could be used and an error will occur.
    • Calling setVectors() multiple times will not augment the starting point information. A call to setVectors() will overwrite/invalidate all data set with a previous call to setVectors().
    • If you want to use a particular solution at a node then you have to specify the full solution using a single call to setVectors() and also have to select an algorithm for solve() that will accept this solution as optimal.
    Calling IloNumVar::setLB() or IloNumVar::setUB() from any callback on a variable that is contained in a model that is currently being solved is not allowed.
    #CPLEXOptimizers
    #DecisionOptimization