Decision Optimization

Decision Optimization

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

 View Only
Expand all | Collapse all

Passing Script Value to the Model

  • 1.  Passing Script Value to the Model

    Posted Mon July 07, 2008 10:35 PM

    Originally posted by: SystemAdmin


    [rastogi said:]

    I am currently using OPL 3.7 where I am using a script file to pass values to the model.  The model uses the 'import' function to pull the data from the script.  Is there a way to do this in OPL 6.0? 


    #DecisionOptimization
    #OPLusingCPLEXOptimizer


  • 2.  Re: Passing Script Value to the Model

    Posted Tue July 08, 2008 09:10 PM

    Originally posted by: SystemAdmin


    [Didier Vidal said:]

    Yes, there's a way to do this in OPL 6.0.

    For instance, the vellino example, in OPL 3.7 starts like that

    Model bin("genBin.mod","genBin.dat");
    import enum Colors bin.Colors;
    import enum Components bin.Components;



    This is translated in OPL 6.0 by a transfer of datasource from one run configuration to an other.


    include "vellinocommon.mod";

    main {
      var master = thisOplModel;
      master.generate();
      var data = master.dataElements;
         
      var genBin = new IloOplRunConfiguration("vellinogenBin.mod");
      genBin.oplModel.addDataSource(data);


    Didier.
    #DecisionOptimization
    #OPLusingCPLEXOptimizer


  • 3.  Re: Passing Script Value to the Model

    Posted Tue July 08, 2008 10:42 PM

    Originally posted by: SystemAdmin


    [rastogi said:]

    Thanks Didier
    That was helpful, but I am trying to pass a script value to the model as I am trying to solve the model multiple times with new data each time.


    In OPL3.7, I am passing a variable from the script to the model
    e.g.

    int Loc :=5; //(this is read from the database)
    forall( n in 1..Loc) {
    int Node:=n;

    Model mod("modfile.mod")editmode;

    mod.solve();
    }

    ----
    In Model file  I am using the value of Node iteratively to read data from the database.
    e.g.

    DBconnection db("odbc","WHJAst//");

    import string node;

    struct sSCInfo { string level1;string level2; string level3; int minl3sku ; int maxl3sku;};
    setof (sSCInfo) tSCInfo from DBread(db, "Select AssortWorld, AssortCat, AssortGroup, minsku, maxsku
          from tmpAstin_AGInfo Where  txtLocationNumber=? ")([b]node[/b]);

    setof(string) Level1 = {i.level1 | i in tSCInfo};


    #DecisionOptimization
    #OPLusingCPLEXOptimizer


  • 4.  Re: Passing Script Value to the Model

    Posted Wed July 09, 2008 05:30 PM

    Originally posted by: SystemAdmin


    [Didier Vidal said:]

    OK. In OPL 6, you will have to separate a little more the data and the model. One advantage of this separation is that you can test the submodel independently of the main model that creates the loop.

    I made a small example that uses the database of the example 'oil' in the OPL distribution.
    The submodel (model.mod) in your case looks like this:

    int Node = ...;


    {string} Gasolines = ...;


    tuple gasType {
      string name;
      float demand;
      float price;
      float octane;
      float lead;
    }

    {gasType} GasData = ...;


    execute {
      writeln("Node " + Node);
      writeln("GasData " + GasData );
    }


    Then, there is a .dat file that contains the SQL query. In the example, I named it query.dat

    DBConnection db("access","oilDB.mdb");
    Gasolines from DBRead(db,"SELECT name FROM GasData");
    GasData from DBRead(db,"SELECT * FROM GasData where octane >= ?") (Node);


    Note that the data Node is not initialized here. If you want to test model.mod alone for debugging, you need an additional dat file that initializes Node.

    Finally, the main model that includes the loop goes like that (I haven't added a solve statement, nor constraints in model... I assum you will find this easily by looking at exampels in the OPL distributions that have a main function). This file is named loop.mod (the important fact is that in OPL 6, it has a .mod extension)

    int Loc =5; //(this is read from the database)


    main {
      var master = thisOplModel;
      master.generate();
      for (var n = 1; n <= master.Loc; n++) {<br />    var subModel = new IloOplRunConfiguration("model.mod");
        // Creating the data
        var data1= new IloOplDataElements();
        data1.Node=n*2;
        subModel.oplModel.addDataSource(data1);
        var data2 = new IloOplDataSource("query.dat");
        subModel.oplModel.addDataSource(data2);
        subModel.oplModel.generate();

      }
    }


    And here is the output I get when I run loop.mod :

    Node 2
    GasData  {<" 3000 70 10 1> <" 2000 60 8 2>
        <" 1000 50 6 1>}
    Node 4
    GasData  {<" 3000 70 10 1> <" 2000 60 8 2>
        <" 1000 50 6 1>}
    Node 6
    GasData  {<" 3000 70 10 1> <" 2000 60 8 2>
        <" 1000 50 6 1>}
    Node 8
    GasData  {<" 3000 70 10 1> <" 2000 60 8 2>}
    Node 10
    GasData  {<" 3000 70 10 1>}



    Hope this helps.

    Didier.
    #DecisionOptimization
    #OPLusingCPLEXOptimizer


  • 5.  Re: Passing Script Value to the Model

    Posted Wed July 09, 2008 08:47 PM

    Originally posted by: SystemAdmin


    [NDHU said:]

    Hi!Didier~

    could i ask you the same concept but usinge the decision variables from one model passing to another model?

    Thanks!!
    #DecisionOptimization
    #OPLusingCPLEXOptimizer


  • 6.  Re: Passing Script Value to the Model

    Posted Wed July 09, 2008 09:42 PM

    Originally posted by: SystemAdmin


    [Didier Vidal said:]


    could i ask you the same concept but usinge the decision variables from one model passing to another model?


    I recommend that you look at the cutstock example in the OPL distribution. For example, the variant cutstock_main.mod contains many interesting code samples to use the variable values, the objective value, the dual values etc... in this context of model chaining.

    Didier.
    #DecisionOptimization
    #OPLusingCPLEXOptimizer


  • 7.  Re: Passing Script Value to the Model

    Posted Wed July 09, 2008 09:48 PM

    Originally posted by: SystemAdmin


    [rastogi said:]

    Didier mentioned this in the previous post.  var "data" reads the inputs from the first model and is fed to model2 using genBin.oplModel.addDataSource(data)

    Didier,
    Thanks for your help.  Your explanation was very helpful and makes sense. the logic worked in the example I had. I can now start migrating my codes from OPL 3.7 to OPL6.  I have been trying to get this answer from OPL helpdesk since OPL4 came out.. .  Thanks again.

    include "vellinocommon.mod";

    main {
      var master = thisOplModel;
      master.generate();
      var data = master.dataElements;
         
      var genBin = new IloOplRunConfiguration("vellinogenBin.mod");
      genBin.oplModel.addDataSource(data);

    #DecisionOptimization
    #OPLusingCPLEXOptimizer


  • 8.  Re: Passing Script Value to the Model

    Posted Thu July 10, 2008 08:18 PM

    Originally posted by: SystemAdmin


    [NDHU said:]

    hi~ i had tried it again. but there is a error message appeared. Can anybody help me to check. my code described as follow:

    in the master model
    int n=...; // number of customers
    int d=...; // length of one period
    dvar boolean v[1..n][1..d];

    in the submodel
    int d=...;
    int n=...;
    int c[1..n][1..d]=...;

    in the main function
    //transfer the v to the submodel
    var subData = subOpl0.dataElements;
    for(var t in masterOpl.d){
    for(var i in masterOpl.n)
    subData.c[i][t] = masterOpl.v[i][t];

    The error message is :Scripting runtime error: Index out of bound for array "c":, "toString".

    The n and d is the same value in the master and submodel~
    #DecisionOptimization
    #OPLusingCPLEXOptimizer


  • 9.  Re: Passing Script Value to the Model

    Posted Tue July 15, 2008 10:08 PM

    Originally posted by: SystemAdmin


    [rastogi said:]

    Didier,
    I was able to solve the model as per your example, iteratively. When I solve the model independently, the output is written to the database, but when I am solving the model through the script, the output is not written in the database. I am using following code
    [b]For Looping [/b]
    main {

    for(var i = 0; i <= 4; i++) {<br />
      var source = new IloOplModelSource("modelFile.mod");
      var cplex = new IloCplex();
      var def = new IloOplModelDefinition(source);
      var opl = new IloOplModel(def,cplex);

      var data = new IloOplDataSource("dataFile.dat");

      var data1 = new IloOplDataElements();
    data1.loc=i;

      opl.addDataSource(data1);
      opl.addDataSource(data);
     
      opl.generate();
      if (cplex.solve()) {
     
          writeln("OBJ = " + cplex.getObjValue());
      } else {
          writeln("No solution");
      }
     
      opl.end();
      data.end();
      data1.end();
      def.end();
      cplex.end();
      source.end();
      }
    }

    [b]Model File[/b]

    int loc=...;

    {string} Gasolines = ...;
    {string} Oils = ...;
    tuple gasType {
      string name;
      float demand;
      float price;
      float octane;
      float lead;
    }

    tuple oilType {
      string name;
      float capacity;
      float price;
      float octane;
      float lead;
    }
    {gasType} GasData = ...;
    execute {
      writeln("Node " + loc);
      writeln("GasData " + GasData );
    }
    tuple result {
      string oil;
      string gas;
      float blend;
      float a;
    }
    {oilType} OilData = ...;
    gasType Gas[Gasolines] = [ g.name : g | g in GasData ];
    oilType Oil[Oils] = [ o.name : o | o in OilData ];
    /* Alternate way to initialize the indexing arrays 'Gas', 'Oil':
    gasType Gas[Gasolines];
    execute {
      for(var g in GasData) {
          Gas[g.name] = g
      }
    }
    oilType Oil[Oils];
    execute {
      for(var o in OilData) {
          Oil[o.name] = o
      }
    }
    */
    float MaxProduction = ...;
    float ProdCost = ...;

    dvar float+ a[Gasolines];
    dvar float+ Blend[Oils][Gasolines];


    maximize
      sum( g in Gasolines , o in Oils )
            (Gas[g].price - Oil[o].price - ProdCost) * Blend[o][g]
            - sum( g in Gasolines ) a[g]+5;

    subject to {
     
      ctDemand:  forall( g in Gasolines )
                  sum( o in Oils )
                    Blend[o][g] == Gas[g].demand + 10 * a[g];
     
      ctCapacity:  forall( o in Oils ) 
                    sum( g in Gasolines )
                      Blend[o][g] <= Oil[o].capacity;<br />
      ctMaxProd:  sum( o in Oils , g in Gasolines )
                    Blend[o][g] <= MaxProduction;<br />
      ctOctane:  forall( g in Gasolines )
                  sum( o in Oils )
                    (Oil[o].octane - Gas[g].octane) * Blend[o][g] >= 0;
      ctLead:  forall( g in Gasolines )
                sum( o in Oils )
                  (Oil[o].lead - Gas[g].lead) * Blend[o][g] <= 0;<br />}


    {result} Result =
      { <o,g,Blend&#91;o&#93;&#91;g&#93;,a&#91;g&#93;> | o in Oils, g in Gasolines };

    execute DISPLAY_RESULT{
      writeln("Result = ",Result)
    }

    [b]Data File[/b]


    DBConnection db("odbc","OPT//");


    Gasolines from DBRead(db,"SELECT name FROM GasData  " );
    Oils from DBRead(db,"SELECT name FROM OilData WHere Octane>=?")(loc);
    GasData from DBRead(db,"SELECT Name,demand, price, Octane,Lead FROM GasData WHere  Octane>=?")(loc);
    OilData from DBRead(db,"SELECT Name,capacity, price, Octane,Lead FROM OilData WHere Octane>=?")(loc);

    MaxProduction = 14000;
    ProdCost = 4;
    DBExecute(db,"drop table Result");
    DBExecute(db,"create table Result(oil varchar(10), gas varchar(10), blend real, a real)");
    Result to DBUpdate(db,"INSERT INTO Result(oil,gas,blend,a) VALUES(?,?,?,?)");


    #DecisionOptimization
    #OPLusingCPLEXOptimizer


  • 10.  Re: Passing Script Value to the Model

    Posted Wed July 16, 2008 12:46 AM

    Originally posted by: SystemAdmin


    [Didier Vidal said:]

    The call that would write to the database is opl.postProcess()
    If you want to write the intermediate results in a database, you should add this call in the loop, after the solve, in case it is successful.

    Didier.
    #DecisionOptimization
    #OPLusingCPLEXOptimizer


  • 11.  Re: Passing Script Value to the Model

    Posted Wed July 16, 2008 09:07 PM

    Originally posted by: SystemAdmin


    [rastogi said:]

    It worked.

    Thanks
    #DecisionOptimization
    #OPLusingCPLEXOptimizer


  • 12.  Re: Passing Script Value to the Model

    Posted Fri March 20, 2009 10:22 AM

    Originally posted by: SystemAdmin


    [researcher_or said:]

    Hi Guys,

    Your posts ae really helpful to a newbie such as me :) .

    I have a problem at hand-
    1)1model file with multiple data files. In the above snippeT u r adding a singel data file to the dataelements.... is there any class to which i can add all the data files for my model in one statement  and associate that data element to my IloOplModel?

    Ideally I would like all these datafile locations to reside in my .dat and iterate and add the datafiles for each model in the main using a for loop....
    any sample snippet or suggestions for these; kindly ignore any obvious things as am new to OPL.



    Cheers,

    #DecisionOptimization
    #OPLusingCPLEXOptimizer


  • 13.  Re: Passing Script Value to the Model

    Posted Mon December 02, 2019 10:42 PM

    Originally posted by: Mathsg


    hello, i am getting an error "Scripting runtime error; not of type 'Ilo Tuple', "1" while passing dual variable value from master problem to sub problem in for loop of OPL Cplex. the for loop is for getting the value of dual variable from master problem to sub problem as soon as there is no new variable genereted by sub problem which can improve the objective of master problem (As i am implementing Column generation). I have attached the error part of my code. Can you help me to fix it? i willl be very thankful. thank you


    #DecisionOptimization
    #OPLusingCPLEXOptimizer