Decision Optimization

Decision Optimization

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

 View Only
Expand all | Collapse all

pass boolean decision variable to a second model and use it as data-Input

  • 1.  pass boolean decision variable to a second model and use it as data-Input

    Posted Fri November 11, 2011 12:49 PM

    Originally posted by: Ben87


    Hi,

    i have the following problem: I use the OplScript (Main) to solve two different models after each other. In the first model i have a boolean decision variable, which contains a two dimensional Array. This Array i want to use in my second model as a data-input with the data type "int". To pass the variables I use the "IloDataElements" function.

    While doing that, i get the following error "Internal error: dvar unexpected at ..\..\..\src\script\proxies.cpp:999".

    So my question is, if it is possible in general to use a boolean decision variable as an data-input of type int?

    here is some code to clarify the problem:

    First, this is my decision variable of the first model: "dvar boolean AllokationErsteWerkeProdukte;"

    this is the declaration of the Array in the second model, which I want to use as a data-input: "int AllokationWerkeProdukte=...;"

    the second model in the main script is introduced in following way:
    var ZweiteStufeSource = new IloOplModelSource("ZweiteStufe.mod");
    var ZweiteStufeDef = new IloOplModelDefinition(ZweiteStufeSource);
    var ZweiteStufeCplex = new IloCplex();
    var ZweiteStufeData = new IloOplDataElements();

    ZweiteStufeData.Allokation = ErsteStufeOpl.AllokationErste; //getting the boolean Array from the first model
    .......

    var ZweiteStufeOpl = new IloOplModel(ZweiteStufeDef, ZweiteStufeCplex);
    ZweiteStufeOpl.addDataSource(ZweiteStufeData);
    ZweiteStufeOpl.generate();
    ZweiteStufeCplex.solve();

    the above-described error occurs when i want to read the Array, for example in the following way:
    var test = ZweiteStufeData.Allokation;
    writeln("Array = ", test);

    Also my second model yields an incorrect objective value.

    Regards,
    Ben
    #DecisionOptimization
    #OPLusingCPLEXOptimizer


  • 2.  Re: pass boolean decision variable to a second model and use it as data-Input

    Posted Fri November 11, 2011 06:19 PM

    Originally posted by: SystemAdmin


    > ZweiteStufeData.Allokation = ErsteStufeOpl.AllokationErste; //getting
    > the boolean Array from the first model

    You should not directly assign the AllokationErste variable (which is a dvar) to the
    non-dvar variable Allokation.

    Instead, you should declare a variable to store the optimal values of the AllokationErste
    variable from the 1st model run, update it in a post-processing execute block and then
    use that to initialize the Allokation variable in the second model. This scheme could
    look like the following:

    
    <1stMODEL.mod> 
    
    int AllokationErste_Optimal; ..... [subject to>] ..... execute post_process
    { 
    
    for(var iter in WerkeProdukte) AllocationErste_Optimal[iter]=AllocationErste[iter]; 
    }   <MainScript> .... MasterOpl.postProcess(); 
    //this will make sure that the AllocationErste_Optimal gets initialized properly with the optimal values from the 1st run .... var ZweiteStufeSource = 
    
    new IloOplModelSource(
    "ZweiteStufe.mod"); var ZweiteStufeDef = 
    
    new IloOplModelDefinition(ZweiteStufeSource); var ZweiteStufeCplex = 
    
    new IloCplex(); var ZweiteStufeData = 
    
    new IloOplDataElements();   ZweiteStufeData.Allokation = ErsteStufeOpl.AllokationErste_Optimal; .... var ZweiteStufeOpl = 
    
    new IloOplModel(ZweiteStufeDef, ZweiteStufeCplex); ZweiteStufeOpl.addDataSource(ZweiteStufeData); ZweiteStufeOpl.generate(); ZweiteStufeCplex.solve();
    


    This approach seems to work for a sample on my side. If you are still having problems, please attach a sample which can reproduce the error.
    #DecisionOptimization
    #OPLusingCPLEXOptimizer


  • 3.  Re: pass boolean decision variable to a second model and use it as data-Input

    Posted Sat December 07, 2019 03:13 AM

    Originally posted by: Mathsg


    Hello, 

    I am very sorry to disturbed you in your busy time but i really need few seconds of your valueble time. i am facing the same error, i.e., passing variable elements from one model to another through scripting part of OPL Cplex. I have divided my problem into two problem i.e., Master and sub problem. In the Master problem i have dvar boolean variable which is multi dimentional array and i am interested to use it in the sub model as a input parameter for solving the sub problem and then use the solution of sub problem to update this array for next iteration. I am getting an error scripting runtime error: Data element z does not exist while z is the new array created in script to store the value of decsion variable which is used in master problem. Here is my main script part of my code.

     

    main {
         

      var status = 0;
      thisOplModel.generate();
      
      var RC_EPS = 1.0e-6;

      var masterDef = thisOplModel.modelDefinition;
      var masterCplex = cplex;
      var masterData = thisOplModel.dataElements;
       
      var subSource = new IloOplModelSource("PP_Jan.mod");
      var subDef = new IloOplModelDefinition(subSource);
      var subData = new IloOplDataElements();
      var subCplex = new IloCplex();
       
       
      var best;
      var curr = Infinity;

      while ( best != curr ) {
        best = curr;

        var masterOpl = new IloOplModel(masterDef, masterCplex);
        masterOpl.addDataSource(masterData);
        masterOpl.generate();
        masterOpl.convertAllIntVars();
            
        writeln("Solve master.");
        if ( masterCplex.solve() ) {
          curr = masterCplex.getObjValue();
          writeln();
          writeln("OBJECTIVE: ",curr);
        } 
        else {
          writeln("No solution!");
          var z =  new Array();
      for (var i in thisOplModel.flows){
        z[i] = new Array();
        for ( var j in thisOplModel.routes){
           z[i][j] = new Array();
           for (var u in thisOplModel.nodes){
        z[i][j][u] = new Array();
        for (var v in thisOplModel.nodes){
           z[i][j][u][v] = new Array();
           z[i][j][u][v] = 0;
         }}}}       
          for (j in thisOplModel.routes){
          for (u in thisOplModel.nodes){
          for (v in thisOplModel.nodes){
          for (v in thisOplModel.nodes){
          z[i][j][u][v] = masterOpl.lemda[i][j][u][v];
          masterData.z[i][j][u][v] = z[i][j][u][v];
           masterOpl.addDataSource(z[i][j][u][v]);
        }}}}    
          masterOpl.end();
         
          break;
        }
    //subData.lemda = masterOpl.lemda;
      subData.nmbr_routes = masterOpl.nmbr_routes;
      subData.nbnodes = masterOpl.nbnodes;
      subData.flows = masterOpl.flows;
      subData.Lincards = masterOpl.Lincards;
      subData.hope_count = masterOpl.hope_count;
      subData.link = masterOpl.link;
      subData.q = masterOpl.q;
      subData.ECcards = masterOpl.ECcards;
      subData.Duals = masterOpl.Duals;
            
     for (var i in masterOpl.routes) {
     subData.Duals[i] = masterOpl.Const10[i].dual;
     }
        var subOpl = new IloOplModel(subDef, subCplex);
        subOpl.addDataSource(subData);
        subOpl.generate();

        writeln("Solve sub.");
        if ( subCplex.solve() ) {
          writeln();
          writeln("OBJECTIVE: ",subCplex.getObjValue());
        }
        else {
          writeln("No solution!");
          subOpl.end();
          masterOpl.end();
          break;
        }

        if (subCplex.getObjValue() >-RC_EPS) { 
          subOpl.end();
          masterOpl.end();
          break;
        }

        
        // Prepare the next iteration:
       //masterData.routes.add(masterData.routes.size,1,subOpl.getObjValue());
      
         for ( var j in subOpl.routes){
            masterData.z[1][j][1][1].add(masterData.z[1][j][1][1],size+1,subOpl.lemda[Opl.first(subOpl.flows)][j][1][1].solutionValue); //'Here i am getting an error
         //(subOpl.f[Opl.first(subOpl.Lincards)][j][1][1].solutionValue);
         }
        //masterData.routes.add(subOpl.getObjValue());
        
      subOpl.end();
      masterOpl.end();
      }
      writeln("Relaxed model search end.");

      masterOpl = new IloOplModel(masterDef,masterCplex);
      masterOpl.addDataSource(masterData);
      masterOpl.generate();   

      writeln("Solve integer master.");  
      if ( masterCplex.solve() ) {
        writeln();
        writeln("OBJECTIVE: ",masterCplex.getObjValue());
        if (Math.abs(masterCplex.getObjValue() - 122)>=0.0001) {
          writeln("Unexpected objective value");
          status = -1;
          
        }
        /*for(i in  masterData.Patterns) {
          if (masterOpl.Cut[i].solutionValue > 0) {
            writeln("Pattern : ", i, " used ", masterOpl.Cut[i].solutionValue << " times");
          }
        }*/
      }
      masterOpl.end();
      status;
    }
      Kindly help and it would be highly appricated. I am looking forward to hearing from you. thank you


    #DecisionOptimization
    #OPLusingCPLEXOptimizer


  • 4.  Re: pass boolean decision variable to a second model and use it as data-Input

    Posted Sat November 12, 2011 05:16 AM

    Originally posted by: Ben87


    Thank you for your help. This works fine.

    Regards,
    Benjamin
    #DecisionOptimization
    #OPLusingCPLEXOptimizer


  • 5.  Re: pass boolean decision variable to a second model and use it as data-Input

    Posted Mon November 14, 2011 01:25 PM

    Originally posted by: SystemAdmin


    > Thank you for your help. This works fine.

    Am glad to note that. Thank you for letting us know.
    #DecisionOptimization
    #OPLusingCPLEXOptimizer