Decision Optimization

Decision Optimization

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

 View Only
Expand all | Collapse all

Flow Control: Change dynamic array in main

  • 1.  Flow Control: Change dynamic array in main

    Posted Sun March 03, 2019 06:22 PM

    Originally posted by: naoseinao


    Hi there,

    I have a model "sub.mod". I calculate different variables that I pass to sub.mod to solve the problem with different inputs. One of these variables is a 2 dimensional array.

    The shortened code of the flow control model calling "sub.mod" in the main:

     int n1 = ...;
     int n2 = ...;
     int a[1..n1][1..n2];
     
    main {
    var src = new IloOplModelSource("sub.mod");
    var cplex = new IloCplex();
    var def = new IloOplModelDefinition(src);
    var opl = new IloOplModel(def,cplex);
            
    //[...]
    thisOplModel.n1 = 1;
    thisOplModel.n2 = 2;
    //[...]
            
    var data = new IloOplDataElements();
            data.n1 = n1;
            data.n2 = n2;
            data.a = thisOplModel.a;
            data.a[1][1] = 1;
            data.a[1][2] = 2;
    
            opl.addDataSource(data);
            opl.generate();
            //[...]
    }
    

    The problem is: I calculate n1 and n2. As a result I cannot "redefine" them in the main model to define the array a.

    I guess I would need to change the dimensions after "data.a = thisOplModel.a;" but I do not know how to do it.

     

    Initially I tried to initialize the array like that (after that follows a calculation to fill the array with non zero values) and send it to the "sub.mod" model. Here follows what I would naturally do, but is not possible:

    main{
    var n1 = 1; // value gets calculated
    var n2 = 2; // value gets calculatet in the main script
    var a = new Array(n1);
            for (var i=0; i < n1; i++) {
                    a[i] = new Array(n2);
                    for (var j=0; j < n2; j++) {
                            a[i][j] = 0;
                    }
            }
            
            //[...]
    
    var data = new IloOplDataElements();
    data.a = a;
    }
    

    Thank you for your time.

    Regards

     


    #DecisionOptimization
    #OPLusingCPLEXOptimizer


  • 2.  Re: Flow Control: Change dynamic array in main



  • 3.  Re: Flow Control: Change dynamic array in main

    Posted Thu March 07, 2019 07:09 AM

    Originally posted by: naoseinao


    Thank you very much. Your links led me to the solution of my problem: I have to use execute in addition to the main method to be able to have an OPL array with dynamic length modified from within the main script.

    I missed to emphase on the dynamic length part that caused my problems. Now I can get rid of my former workaround. You made my day, thanks!

    Here the adjusted working example from above:

     int n1;
     int n2;
     int a[1..n1][1..n2];
     
     execute {
      //[...]
            thisOplModel.n1 = 1;
            thisOplModel.n2 = 2;
    //[...]
    
     }
     
    main {
    var src = new IloOplModelSource("sub.mod");
    var cplex = new IloCplex();
    var def = new IloOplModelDefinition(src);
    var opl = new IloOplModel(def,cplex);
            
    //[...]
            
    var data = new IloOplDataElements();
            data.n1 = thisOplModel.n1;
            data.n2 = thisOplModel.n2;
            data.a = thisOplModel.a;
            data.a[1][1] = 1;
            data.a[1][2] = 2;
    
            opl.addDataSource(data);
            opl.generate();
            //[...]
    }
    

     


    #DecisionOptimization
    #OPLusingCPLEXOptimizer


  • 4.  Re: Flow Control: Change dynamic array in main

    Posted Mon December 09, 2019 12:08 AM

    Originally posted by: Mathsg


    hi neosenio,

     

    I hope you are enjoying your day. I am facing the same problem as your passing dvar multi dimentional array array from main model to sub model, update it in submodal and then use it again in main model through script part of OPL Cplex. i have see some post on this community platform to declare new array first to store the value of array used in master problem so i have declare the new array with name t and put all elements of lemda in t but still i am getting an error. here is the script of my main code. kindly have a look and guide me in this regards, 

     

    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 subOpl = new IloOplModel(subDef, subCplex);
       
       
      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!");
        
          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());
        var t =  new Array();
      for (var i in thisOplModel.flows){
        t[i] = new Array();
        for ( var j in thisOplModel.routes){
           t[i][j] = new Array();
           for (var u in thisOplModel.nodes){
        t[i][j][u] = new Array();
        for (var v in thisOplModel.nodes){
           t[i][j][u][v] = new Array();
           t[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){
          t[i][j][u][v] = masterOpl.lemda[i][j][u][v];     
          masterData = t[i][j][u][v];
     //     masterData = t[i][j][u][v];
          
           //masterOpl.addDataSource(z[i][j][u][v]);
        }
        }
        }
        }    
        
       
        writeln("Master pattern before +++ : \n ",masterData.t[1][1][1][1]);    
        
         for ( var j in subOpl.routes){
           masterData.t[1][j][1][1].add(masterData.t[1][j][1][1],size,1,subOpl.lemda[Opl.first(masterOpl.flows)][j][1][1].solutionValue); // Here i am geeting 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;
    }
    your help will be highly appricated and i am looking forward to hearing from you. thank you


    #DecisionOptimization
    #OPLusingCPLEXOptimizer