Decision Optimization

Decision Optimization

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

 View Only
  • 1.  Gap for solution pool solutions

    Posted Fri January 09, 2015 04:39 AM

    Originally posted by: davidoff


    Hi

    Since CPLEX natively access to its own solution pool, we can iterate on the different solutions stored in it and get access to their objective value and value of expressions or variables for any incumbent stored in the pool.

    Is there a direct access to relative gap for each intermediate incumbent stored in the pool ?

    Thanks

    David


    #CPLEXOptimizers
    #DecisionOptimization


  • 2.  Re: Gap for solution pool solutions

    Posted Fri January 09, 2015 07:58 AM

    Hi

    let me give you an example of what could be done with the OPL API and can be done with all other APIs.

     

    include "scalableWarehouse.mod";

     

    main{

    thisOplModel.generate();

    cplex.solve();

    if (cplex.populate()) {

    var nsolns = cplex.solnPoolNsolns;

    writeln("Number of solutions found = ",nsolns);

    writeln();

    for (var s=0; s<nsolns; s++) {

    thisOplModel.setPoolSolution(s);

    writeln("solution #", s, ": objective = ", cplex.getObjValue(s));

    writeln("solution #", s, ": best objective = ", cplex.getBestObjValue());

    writeln("solution #", s, ": gap = ", cplex.getObjValue(s)-cplex.getBestObjValue());

    write("Open = [ ");

    for (var i in thisOplModel.Warehouses)

    write(thisOplModel.Open[i], " ");

    writeln("]");

    writeln("---------");

    }

    }

    }

     

    in

    CPLEX_Studio1261\opl\examples\opl\warehouse

     

    will give for all solutions in the pool the gap.

    Regards


    #CPLEXOptimizers
    #DecisionOptimization


  • 3.  Re: Gap for solution pool solutions

    Posted Fri January 09, 2015 08:57 AM

    Originally posted by: davidoff


    I wrote a similar model in Java but without populate method since I simply want to use the current solution pool natively available at the end of a solve

     

    int nsolns = cplex.getSolnPoolNsolns();
                System.out.println("Number of solutions found = "+nsolns);
                System.out.println();
                for (int s=0; s<nsolns; s++) {
                    System.out.println("solution #" + s + ": objective = "+ cplex.getObjValue(s)+ ": gap = "+ (cplex.getObjValue(s)-cplex.getBestObjValue()));
    

    Here is the MIP log and the output

     

      Node  Left     Objective  IInf  Best Integer    Best Bound    ItCnt     Gap
    
    *     0+    0                           85.0000        0.0000      115  100.00%
    *     0+    0                           71.2500        0.0000      115  100.00%
    *     0+    0                           64.5833        0.0000      115  100.00%
          0     0       38.3333    32       64.5833       38.3333      115   40.65%
    *     0+    0                           55.0000       38.3333      115   30.30%
          0     0       38.3333    38       55.0000       Cuts: 3      142   30.30%
          0     0       38.3333    32       55.0000      Fract: 3      150   30.30%
          0     0       38.3333    32       55.0000     Covers: 1      160   30.30%
    *     0+    0                           51.6667       38.3333      160   25.81%
          0     0        cutoff             51.6667       51.6667      160    0.00%
    Elapsed time = 0.23 sec. (32.11 ticks, tree = 0.00 MB, solutions = 5)
    
    Cover cuts applied:  1
    Lift and project cuts applied:  1
    Gomory fractional cuts applied:  2
    
    Root node processing (before b&c):
      Real time             =    0.23 sec. (32.12 ticks)
    Parallel b&c, 4 threads:
      Real time             =    0.00 sec. (0.00 ticks)
      Sync time (average)   =    0.00 sec.
      Wait time (average)   =    0.00 sec.
                              ------------
    Total (root+branch&cut) =    0.23 sec. (32.12 ticks)
    
    INFO: CPLEX status = Optimal
    Objective function = 51.66666666666666
    Number of solutions found = 5
    
    solution #0: objective = 51.66666666666666: gap = 0.0
    solution #1: objective = 71.24999999999999: gap = 19.58333333333333
    solution #2: objective = 64.58333333333331: gap = 12.916666666666657
    solution #3: objective = 54.99999999999999: gap = 3.3333333333333357
    solution #4: objective = 85.0: gap = 33.33333333333334
    

    With this method , the gap of each incumbent is based on the best objective value at the very end, which differs a little bit from what we see in the MIP log since the best bound will be improving too. 


    #CPLEXOptimizers
    #DecisionOptimization


  • 4.  Re: Gap for solution pool solutions

    Posted Fri January 09, 2015 09:32 AM

    There is no direct way to query the gap for a solution in the pool. The best thing you can do is what you did in your example code.

    As you already noted, it is not even exactly clear what "gap" should mean for a solution that is not the incumbent: Should it be the gap with respect to the final dual bound or should it be the gap at the time the solution was found? The former is what you get by your code, the latter is much harder to get (especially when using multiple threads) and that information does not make too much sense in my opinion. If you really need the latter you would have to use an incumbent callback and query the dual bound at the point the incumbent is found.


    #CPLEXOptimizers
    #DecisionOptimization


  • 5.  Re: Gap for solution pool solutions

    Posted Sun January 11, 2015 02:14 PM

    Originally posted by: davidoff


    Thanks Daniel

    I agree with your answer. I thought first of avoiding writing an incumbent callback since we have direct access to the pool of these incumbents after cplex.solve()


    #CPLEXOptimizers
    #DecisionOptimization