Decision Optimization

Decision Optimization

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

 View Only
  • 1.  Feed solution from one model to another

    Posted Sat March 21, 2015 07:05 AM

    Originally posted by: MatthiasP.


    Hi everyone, I'm relatively new to CPLEX for my thesis work.

    I've written a model for a home health care problem, but because the original model was too large to solve instances of a realistic size, my promotor suggested I decompose it into an assignment and scheduling problem. Now, I wish to feed 2 decision variables of this assignment problem to the scheduling problem so I can solve it in one go instead of having to solve one, then add the solution to the .dat-file of the second.

    The two decision variables are:

    dvar boolean z[workers][patients];

    dvar int r2[days][workers];

    The latter has to be renamed to r[days][workers]  when fed to the scheduling model.

    I've been trying to puzzle together the necessary code looking at some of the examples but not to much success.

    The 'Master model.mod' is the assignment problem, 'Subproblem.mod' is the scheduling problem which needs the solutions fed to. The code below is what I currently have in the 'Master model'-file. Running it returns a "scripting runtime error: cannot add properties to this value : [a IloOplMain.IloOplDataSource].". 

    main
    {
    var MASTERDef = thisOplModel.modelDefinition;
    var MASTERCplex = cplex;
    var MASTERData = thisOplModel.dataElements;
    var MASTEROpl = new IloOplModel(MASTERDef, MASTERCplex);
    MASTEROpl.addDataSource(MASTERData);
    MASTEROpl.generate();
     
     
    var SUBSource = new IloOplModelSource("Submodel.mod");
    var SUBDef = new IloOplModelDefinition(SUBSource);
    var SUBCplex = new IloCplex();
    var SUBOpl = new IloOplModel(SUBDef, SUBCplex);
    var SUBData = new IloOplDataSource("Submodel.dat");
    SUBData.r = MASTEROpl.r2;
    SUBData.z = MASTEROpl.z;
    SUBOpl.addDataSource(SUBData);
    SUBOpl.generate();    
     
       
     

    Does this have to do with how I define r[d][k] and z[k][p] in the Submodel's .mod and .dat files? I've tried various options, but nothing seems to work.

    Any help is much appreciated. Thanks in advance.

     


    #CPLEXOptimizers
    #DecisionOptimization


  • 2.  Re: Feed solution from one model to another

    Posted Sun March 22, 2015 03:54 AM

    Have you looked at the cutting stock example in opl/examples/opl/cutstock? I think this does exactly what you want:

    • You have a cutstock_main.mod file that gives the master model and scripting code
    • There is a cutstock-sub.mod which gives the sub model. This is used by the scripting code in cutstock_main.mod
    • The scripting code dynamically creates input data for the sub model and populates that from the results of the master (see the 'subData' variable).

    #CPLEXOptimizers
    #DecisionOptimization


  • 3.  Re: Feed solution from one model to another

    Posted Mon March 23, 2015 05:51 AM

    Originally posted by: MatthiasP.


    Thanks for your response. Yes, I have looked at the example. In fact, I based the scripting code on the one from that example. 

    If I understand the cutting stock problem correctly, you have the master problem that's solved with the existing patterns defined in the .dat file. Using the duals from solving the master problem in the subproblem gives you a new pattern to add in the master problem. In the script it says 

          subData.RollWidth = masterOpl.RollWidth;
          subData.Size = masterOpl.Size;
          subData.Duals = masterOpl.Duals;

    But none of these are decision variables. 'RollWidth' and 'Size' are set in the .dat file from the master problem and 'Duals' comes from an execute block. In my case the master is solved and I need the solutions from 2 dvar's as normal 'int' values in the sub problem. Do you think that's possible? I'm not sure this is what causes the error I receive, but it is the only thing I can come up with currently...

    I'm sorry if I'm missing something obvious here, but I'm a little out of my depth.


    #CPLEXOptimizers
    #DecisionOptimization


  • 4.  Re: Feed solution from one model to another

    Posted Tue March 24, 2015 07:03 AM

    Sorry, I missed the error message in your initial post. The following works for me (at least the created sub.lp file looks as expected):

    master.mod:

    range workers = 1..2;
    range patients = 1..2;
    range days = 1..2;
     
    dvar boolean z[workers][patients];
    
    dvar int r2[days][workers];
    
    float subZ[workers][patients];
    float subR[days][workers];
    
    maximize sum(w in workers, p in patients) z[w][p] + sum(d in days, w in workers) r2[d][w];
    subject to {}
    
     
    main {
      var MASTERDef = thisOplModel.modelDefinition;
      var MASTERCplex = cplex;
      var MASTERData = thisOplModel.dataElements;
      var MASTEROpl = new IloOplModel(MASTERDef, MASTERCplex);
      MASTEROpl.addDataSource(MASTERData);
      MASTEROpl.generate();
      MASTERCplex.solve();
      writeln("MASTERCplex.getObjValue() = " + MASTERCplex.getObjValue());
      
      for (var w in thisOplModel.workers) {
        for (var p in thisOplModel.patients) {
           MASTEROpl.subZ[w][p] = MASTEROpl.z[w][p];    
        }  
      }
      for (var d in thisOplModel.days) {
        for (var w in thisOplModel.workers) {
          MASTEROpl.subR[d][w] = MASTEROpl.r2[d][w];    
        }  
      }
     
     
      var SUBSource = new IloOplModelSource("Submodel.mod");
      var SUBDef = new IloOplModelDefinition(SUBSource);
      var SUBCplex = new IloCplex();
      var SUBOpl = new IloOplModel(SUBDef, SUBCplex);
      var SUBData = new IloOplDataSource("Submodel.dat");
      var moreData = new IloOplDataElements();
      moreData.r = MASTEROpl.subR;
      moreData.z = MASTEROpl.subZ;
      SUBOpl.addDataSource(SUBData);
      SUBOpl.addDataSource(moreData);
      SUBOpl.generate();
      SUBCplex.solve();
      SUBCplex.exportModel("sub.lp");
      writeln("SUBCplex.getObjValue() = " + SUBCplex.getObjValue());  
    }
    

    Submodel.mod:

    range workers = 1..2;
    range patients = 1..2;
    range days = 1..2;
     
    float z[workers][patients] = ...;
    float r[days][workers] = ...;
    
    dvar boolean xz[workers][patients];
    dvar boolean xr[days][workers];
    
    minimize sum(w in workers, p in patients) xz[w][p] * z[w][p] + sum(d in days, w in workers) xr[d][w] * r[d][w];
    subject to {}
    

    However, there may be better ways to do that. Can you please post this question on the OPL Forum? There you will find people who are more experienced in OPL and they should be able to help you.


    #CPLEXOptimizers
    #DecisionOptimization