Decision Optimization

Decision Optimization

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


#Analytics
#DecisionOptimization
#DecisionOptimization
 View Only
  • 1.  Using result of one optimization in another - best practise?

    Posted 07/19/18 09:58 AM

    Originally posted by: OndrejKral


    Hi, I have few questions. Part of my flow control code looks like this:

    for(var task in preSolveModel.PP){
                                    for(var lz in preSolveModel.LZ){
                                            if (preSolveModel.Y[task][lz][1] == 0 && preSolveModel.Y[task][lz][2] == 0 && preSolveModel.Y[task][lz][3] == 0 && preSolveModel.Y[task][lz][4] == 0 && preSolveModel.Y[task][lz][5] == 0){
                                                    for(var task2 in preSolveModel.PP) { activeModel.XC[task][task2][lz].UB = 0; activeModel.XC[task2][task][lz].UB = 0;}
                                                    activeModel.XC[task][task][lz].UB = 0;
                                                    filteredTasks++;
                                                    writeln(filteredTasks);                         
                                            }                             
                                    }                     
                            }    
    

    I'm basically using result of presolve model to tighten search space of main model by modifying main model constraint of binary decision variable X:

    X[i][j][k] <= 1, setting XC[i][j][k].UB = 0 should yield X[i][j][k] <= 0

    Is there another way to fixing some variable before optimization starts? (fixed value, not starting value)

    Is there some known best practice to "connect" these two phases? (presolve and main solve)

     

    The problem is that for-loop above is really slow. I don't know how to use batch operations here, could I set UB for all elements in array to 0 in batch? And is there some syntax for parallel execution in ILOG script?

    Thanks,

    Ondrej.


    #DecisionOptimization
    #OPLusingCPLEXOptimizer


  • 2.  Re: Using result of one optimization in another - best practise?

    Posted 07/19/18 11:21 AM

    Hi,

    in the CPLEX Virtual User Groups archives you have good advice

    https://www.ibm.com/developerworks/community/wikis/home?lang=en#!/wiki/W1a790e980a7d_49c5_963d_2965e5d01401/page/Virtual%20User%20Group%20Meetings

    Try to do computation in the modeling parts rather than huge loops in the scripting part.

    Many how to at https://www.linkedin.com/pulse/how-opl-alex-fleischer/

    regards


    #DecisionOptimization
    #OPLusingCPLEXOptimizer


  • 3.  Re: Using result of one optimization in another - best practise?

    Posted 07/23/18 08:21 AM

    Originally posted by: OndrejKral


    Hi, thank you for the links above. I went through the relevant examples and that helped me identify another possible solution. Instead of rewriting constraints, one could use "warm start". I studied most of the documentation for warm starting and decided to do following: Adding starting point (addMIPStart()) based on presolve model run. That is incomplete solution (I'm setting few variables to zero and nothing else). To really narrow the search space, I set cplex.repairtries = -1; (this should force cplex solver to do not change values I've just set by addMIPStart()). Default MIP start effort  should be 4 = "attempts to repair the MIP start if it is infeasible" (and is fine with partial solution defined in addMIPStart()).

     

    When I run the main optimization, engine log says: "Warning:  No solution found from 1 MIP starts." and continue with computation. So two things I don't understand:

     

    1) why is the computation not aborted? (I set zero repair tries, so if there is no feasible extension of my partial solution I would expect solver to abort hence it cannot repair my provided start)

    2) is there something I'm missing in general? (because the MIP start I provided - if I did it right - has a feasible extension )

     

    Thanks for any hint or advice,

    Ondrej.


    #DecisionOptimization
    #OPLusingCPLEXOptimizer


  • 4.  Re: Using result of one optimization in another - best practise?

    Posted 07/23/18 08:32 AM

    Hi,

    why is the computation not aborted? (I set zero repair tries, so if there is no feasible extension of my partial solution I would expect solver to abort hence it cannot repair my provided start)

    ==> If cplex cannot repair then it won t abort but solve without any warm start

    you could also have a look at the MIPStartEffort setting.

    You have a warmstart example in CPLEX_Studio128\opl\examples\opl\warmstart

    You could also have a look at

    https://www.ibm.com/developerworks/community/forums/html/topic?id=72359501-c169-4215-9dc0-1c87e653b584&ps=25

    regards


    #DecisionOptimization
    #OPLusingCPLEXOptimizer


  • 5.  Re: Using result of one optimization in another - best practise?

    Posted 07/24/18 03:55 AM

    Originally posted by: OndrejKral


    Hi, thanks. I went through the warmstart example. Two things I couldn't find out:

    1) is attach vector approach equivalent to addMIPStart? (is for example MIPStartEffort setting applied to starting point set by attach vector function?)

    2) I couldn't find what type of objects function attach(vars, vals) accepts. As I said before, I only want to attach value to some variables and hence I'm dynamically creating array (by new Array()) of references to specific variables in the model. So I'm giving attach() method two arrays (new Array()), one filled with constants, other referencing variables and I get error about bad arguments: object Object.

     

    Thanks again for any hint or advice,

    Ondrej.


    #DecisionOptimization
    #OPLusingCPLEXOptimizer


  • 6.  Re: Using result of one optimization in another - best practise?

    Posted 07/24/18 06:16 AM

    Hi

    same approaches.

    You mix scripting array and OPL arrays I guess.

    https://www.ibm.com/developerworks/community/forums/html/topic?id=cbefff10-5006-439e-8a73-f7f7d0af05a5&ps=25

    Let me share a 2D warm start example:

    range r = 1..10;
    dvar int+ x[r][r];
    dvar int+ y[r][r];
    // The following array of values (defined as data) will be used as
    // a starting solution to warm-start the CPLEX search.
    float values[i in r][j in r] = ((i==5) &&(j==5))? 10 : 0;


    minimize
      sum( i in r ) x[i][i] + sum( j in r ) y[j][j];
    subject to{
      ctSum:    
        sum( i in r ) x[i][i] >= 10;
      forall( j in r )
        ctEqual:
          y[j][j] == j;
          
          forall(i,j in r : i != j)
            x[i][j] == 0;
          
    }

    main{
      thisOplModel.generate();  
      var def = thisOplModel.modelDefinition;   
      // Default behaviour
      writeln("Default Behaviour");
      var cplex1 = new IloCplex();
      var opl1 = new IloOplModel(def, cplex1);
      opl1.generate();
      cplex1.solve();   
      writeln(opl1.printSolution());
      // Setting initial solution
      writeln("Setting initial solution");
      var cplex2 = new IloCplex();
      var opl2 = new IloOplModel(def, cplex2);
      opl2.generate();
      //var vectors = new IloOplCplexVectors();
      // We attach the values (defined as data) as starting solution
      // for the variables x.
      //vectors.attach(opl2.x,opl2.values);
      //vectors.setStart(cplex2);
      cplex2.addMIPStart(opl2.x,opl2.values) ;
     
      cplex2.solve();   
      writeln(opl2.printSolution());

      opl1.end();
      cplex1.end();
      opl2.end();
      cplex2.end();
      0;
    }

     

    regards


    #DecisionOptimization
    #OPLusingCPLEXOptimizer


  • 7.  Re: Using result of one optimization in another - best practise?

    Posted 07/24/18 08:49 AM

    Originally posted by: OndrejKral


    Hi again, thanks again, I think I got it now.

     

    Lets use your example above. I want set values only to the variables on the diagonal of x. How to do it?

    1) Setting cplex2.addMIPStart(opl2.x[1,1],opl2.values[1,1]) ; cplex2.addMIPStart(opl2.x[2,2],opl2.values[2,2]) ; and so on isn't the way because I'm setting multiple MIP starts instead one with diagonal variables set to some value. That is why I was mixing script and OPL arrays because I thought I will just store the references in them and then do cplex2.addMIPStart(ScriptArrayOfReferencesToModelVariables,ScriptArrayOfReferencesToModelValues). But they are Object type and that rise the error when using vecotr.attach()  and won't working when using addMIPStart() I assume.

     

    2) Is setting multiple times vector.attach(opl2.x[1,1],opl2.values[1,1]); vector.attach(opl2.x[2,2],opl2.values[2,2]); the way? (is this creating one or multiple CPLEX starting points?)

     

    EDIT: Actually both approaches need arrays as arguments so not a good example.

     

    Best regards,

    Ondrej.

     

     


    #DecisionOptimization
    #OPLusingCPLEXOptimizer


  • 8.  Re: Using result of one optimization in another - best practise?

    Posted 07/24/18 10:26 AM

    Hi,

    for the diagonal I see 2 ways:

    a) Use additional decision variables to do the warmstart on those:

    range r = 1..10;
    int v[1..2];

    dvar int+ x[r][r];
    dvar int+ y[r][r];

    dvar int diagx[r];
    // The following array of values (defined as data) will be used as
    // a starting solution to warm-start the CPLEX search.
    float values[i in r][j in r] = ((i==5) &&(j==5))? 10 : 0;
    float diagvalues[i in r] = ((i==5))? 10 : 0;

    minimize
      sum( i in r ) x[i][i] + sum( j in r ) y[j][j];
    subject to{
      ctSum:    
        sum( i in r ) x[i][i] >= 10;
      forall( j in r )
        ctEqual:
          y[j][j] == j;
          
          forall(i,j in r : i != j)
            x[i][j] == 0;
            
     forall(i in r)  diagx[i]==x[i][i];   
    }

    main{
      thisOplModel.generate();  
      var def = thisOplModel.modelDefinition;   
      // Default behaviour
      writeln("Default Behaviour");
      var cplex1 = new IloCplex();
      var opl1 = new IloOplModel(def, cplex1);
      opl1.generate();
      cplex1.solve();   
      writeln(opl1.printSolution());
      // Setting initial solution
      writeln("Setting initial solution");
      var cplex2 = new IloCplex();
      var opl2 = new IloOplModel(def, cplex2);
      opl2.generate();
      //var vectors = new IloOplCplexVectors();
      // We attach the values (defined as data) as starting solution
      // for the variables x.
      //vectors.attach(opl2.x,opl2.values);
      //vectors.setStart(cplex2);
      //cplex2.addMIPStart(opl2.x,opl2.values) ;
      cplex2.addMIPStart(opl2.diagx,opl2.diagvalues);
      cplex2.solve();   
      writeln(opl2.printSolution());

      opl1.end();
      cplex1.end();
      opl2.end();
      cplex2.end();
      0;
    }

    b) Use IloOplOutputFile to generate the file .mst that fits your exact needs

    https://www.ibm.com/support/knowledgecenter/SSSA5P_12.7.1/ilog.odms.cplex.help/CPLEX/FileFormats/topics/MST.html

    describes .mst format

    regards


    #DecisionOptimization
    #OPLusingCPLEXOptimizer


  • 9.  Re: Using result of one optimization in another - best practise?

    Posted 07/24/18 10:54 AM

    Originally posted by: OndrejKral


    Hi, thanks. Yeah, that diagonal was just an example, I need general subset of x[r][r] entries. The second approach looks promising (first I need to find out how name and index property of <variable> tag corresponds to individual entries of x[r][r] in the model, but this is not related to this topic).

     

    Thank you again. I really appreciate your help and fast responses!

     

    Best regards,

    Ondrej.


    #DecisionOptimization
    #OPLusingCPLEXOptimizer


  • 10.  Re: Using result of one optimization in another - best practise?

    Posted 07/24/18 11:12 AM

    Hi,

    but without writing a file you could use incrementalism within OPL ( https://www.linkedin.com/pulse/how-opl-alex-fleischer/ )

    and write

    range r = 1..10;


    dvar int+ x[r][r];
    dvar int+ y[r][r];

    dvar int x2[r][r];
    // The following array of values (defined as data) will be used as
    // a starting solution to warm-start the CPLEX search.
    float values[i in r][j in r] = ((i==5) &&(j==5))? 10 : 0;
    dvar boolean eqxandx2[r][r];

    minimize
      sum( i in r ) x[i][i] + sum( j in r ) y[j][j];
    subject to{
      ctSum:    
        sum( i in r ) x[i][i] >= 10;
      forall( j in r )
        ctEqual:
          y[j][j] == j;
          
          forall(i,j in r : i != j)
            x[i][j] == 0;
            
     forall(i,j in r)  eqxandx2[i][j]==1 => x2[i][j]==x[i][i];   
    }

    main{
      thisOplModel.generate();  
      var def = thisOplModel.modelDefinition;   
      // Default behaviour
      writeln("Default Behaviour");
      var cplex1 = new IloCplex();
      var opl1 = new IloOplModel(def, cplex1);
      opl1.generate();
      cplex1.solve();   
      writeln(opl1.printSolution());
      // Setting initial solution
      writeln("Setting initial solution");
      var cplex2 = new IloCplex();
      var opl2 = new IloOplModel(def, cplex2);
      opl2.generate();
      //var vectors = new IloOplCplexVectors();
      // We attach the values (defined as data) as starting solution
      // for the variables x.
      //vectors.attach(opl2.x,opl2.values);
      //vectors.setStart(cplex2);
      //cplex2.addMIPStart(opl2.x,opl2.values) ;
     
      for(var i in thisOplModel.r) for(var j in thisOplModel.r) opl2.eqxandx2[i][j].UB=0;
      opl2.eqxandx2[1][1].UB=1;
      opl2.eqxandx2[1][1].LB=1;
       opl2.eqxandx2[2][2].UB=1;
      opl2.eqxandx2[2][2].LB=1;
      cplex2.addMIPStart(opl2.x2,opl2.values);
      cplex2.solve();   
      writeln(opl2.printSolution());

      opl1.end();
      cplex1.end();
      opl2.end();
      cplex2.end();
      0;
    }

     

     

    which will do warmstart with only 2 values within the array

     

    regards


    #DecisionOptimization
    #OPLusingCPLEXOptimizer


  • 11.  Re: Using result of one optimization in another - best practise?

    Posted 07/25/18 05:56 AM

    Originally posted by: OndrejKral


    Hi, this seems very similar to the one I've used in the original solution on the top of this thread (just rewriting right side of constraints). Problem is that I'm setting UB and LB properties of too many variables (X has dimensions like 800x800x5) and the resulting loop is slow (maybe modifying UB/LB property is linked with some postprocessing - e.g. some matrix normalization, i think it isn't just memory write operation otherwise it would be fast and looping with only write to output is fast so it is not a fault of the script interpreter or whatever is cplex doing with script file)

     

    Best regards,

    Ondrej.


    #DecisionOptimization
    #OPLusingCPLEXOptimizer