Decision Optimization

Decision Optimization

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


#Analytics
#DecisionOptimization
#DecisionOptimization
 View Only
  • 1.  stores and regions problem - matching dynamic data to hardcoded info

    Posted 02/11/16 07:18 PM

    Originally posted by: Rodders


      I have a set of stores, each of which belongs to a region.

      BelongsTo[STOREs, REGIONs] looks like this:

    [ [ 0 1 0 0 ]  // store A

      [ 0 0 1 0 ]  // store B

      [ 0 0 1 0 ]  // store C

      [ 0 0 0 1 ]  // store D

      [ 1 0 0 0 ]  // store E

      [ 1 0 0 0 ]  // store F

      [ 0 0 1 0 ]  // store G

      [ 0 0 1 0 ]  // store H

      [ 0 1 0 0 ]  // store I

      [ 1 0 0 0 ]  // store J

      [ 1 0 0 0 ]  // store K

    ]

      In this particular example there are 11 stores and 4 regions. Each store belongs to one and only one region.

     

      Whenever a shipment is scheduled for a store, a fixed cost is assessed, associated with the region to which the store belongs.

      If more than one store in the same region is serviced on a given day, that region's fixed cost is assessed only once.

     

      I was able to successfully set the boolean decision variable WasVisited[REGIONs, DAYs] with the following constraint:

    CheckRegionsVisited =

    forall (r in REGIONs, d in DAYs, s in STOREs)

               BelongsTo[s,r] * Truck[s,d] <= WasVisited [r,d];

     

      So far, so good.

      My only problem is due to my data file being dynamically prepared by an external application. The set of stores that will be present in the data file is unknown, on any given day.

      The BelongsTo matrix mentioned in the beginning of this post contains all stores, but every time the model is executed I need to instantiate a version of that master matrix that represents only the stores that are present in the data file, in the order that they appear in the data file.

     

      My data file contains the following data element:

    STOREs = {

      D  F  K

    };

     

      Each time the model is called, this data element will look different.

      How do I dynamically (inside the "execute" preprocessing code) create a BelongsTo matrix that will correspond to the STOREs data element passed to the model?

      If my STOREs data element looked like the one above, my BelongsTo matrix would need to look like this:

    [ [ 0 0 0 1 ]  // store D

      [ 1 0 0 0 ]  // store F

      [ 1 0 0 0 ]  // store K

    ]

     

      This is what I've tried, so far:

    1. Represent the master matrix as:

     

    int BelongsTo[STOREs,REGIONs];

    tuple MyMatrix {

                int store;

                int belongs[REGIONs];

    };

    {MyMatrix} hardcoded_matrix = { < A , [0, 1, 0, 0] >, < B , [0, 0, 1, 0] >, < C , [0, 0, 1, 0] > };

     

    1. Attempt different versions of:

        BelongsTo = [ h.belongs | h.store in STOREs, h in hardcoded_matrix ];

     

    for (var x in STOREs)

        BelongsTo = [ x : h.belongs | x = h.store , h in hardcoded_matrix ];

     

     

      I believe I'm missing something in the syntax.

      Does anyone know how I can dynamically create BelongsTo[STOREs, REGIONs], based on the value of STOREs read from the data file?

      Or does anyone know of a better way to accomplish this?

     

      Changing the data file is not possible at the moment.

      Thank you very much for helping me crack this nut.

     

    Marcelo

    Solutions Architect


    #DecisionOptimization
    #OPLusingCPLEXOptimizer


  • 2.  Re: stores and regions problem - matching dynamic data to hardcoded info



  • 3.  Re: stores and regions problem - matching dynamic data to hardcoded info

    Posted 02/15/16 04:04 PM

    Originally posted by: Rodders


    Alex,

    Not really.

     

    The constraint

    forall (r in REGIONs, d in DAYs, s in STOREs)

               BelongsTo[s,r] * Truck[s,d] <= WasVisited [r,d];

     

    ... depends on a correct BelongsTo[s,r] matrix.

    I know the master matrix, involving ALL stores "s", but I never know which ones of them will be in the data file.

    The stores are presented as a set in the data file. The key question is: how to construct the BelongsTo matrix based on the master matrix and on the actual stores present in the data?

     

    BelongsTo will always be a sub-set of the master matrix. It will only contain the rows that correspond to the stores present in the data file (.dat).

     

    If doing this is not possible, I wonder what would be the best way to hardcode this in the model.

     

    Thank you, and regards.    Marcelo

     


    #DecisionOptimization
    #OPLusingCPLEXOptimizer


  • 4.  Re: stores and regions problem - matching dynamic data to hardcoded info

    Posted 02/18/16 09:01 AM

    Hi,

    so let me adapt my example a bit further to your need:

    Sub.mod

    float maxOfx = ...;
    int y[1..2][1..2]=...;

    {string} STORES=...;
    {string} openSTORES=...;

    int open[s in STORES]=(s in openSTORES)?1:0;

    execute
    {
    writeln("y=",y);
    writeln("STORES=",STORES);
    writeln("openSTORES=",openSTORES);
    writeln("open=",open);
    }

    dvar float x;

    maximize x;
    subject to {
      x<=maxOfx+sum(i in 1..2, j  in 1..2) y[i][j];
    }

    and then you write

    int a[1..2][1..2];
     {string} stores={"s1","s2"};
     {string} openSTORES[11..15];

    main {
      var source = new IloOplModelSource("sub.mod");
      var cplex = new IloCplex();
      var def = new IloOplModelDefinition(source);
      var opl = new IloOplModel(def,cplex);
     
     
      for(var k=11;k<=15;k++)
      {
      var opl = new IloOplModel(def,cplex);
     
     
        
      var data2= new IloOplDataElements();
      data2.maxOfx=k;
      thisOplModel.stores.add("s"+k);
      data2.STORES=thisOplModel.stores;
     
      for(s in thisOplModel.stores) if (Opl.ord(thisOplModel.stores,s) >=2)
         thisOplModel.openSTORES[k].add(s);
      data2.openSTORES=thisOplModel.openSTORES[k];
     
    data2.y=thisOplModel.a;
    data2.y[1][1]=k;
      opl.addDataSource(data2);
     
      opl.generate();

      if (cplex.solve()) {
         writeln("OBJ = " + cplex.getObjValue());
      } else {
         writeln("No solution");
      }
    data2.end();
     opl.end();
     
     
    }  
     
    }

     

    which will give

     

    y= [[11 0]
             [0 0]]
    STORES= {"s1" "s2" "s11"}
    openSTORES= {"s11"}
    open= [0 0 1]
    OBJ = 22
    y= [[12 0]
             [0 0]]
    STORES= {"s1" "s2" "s11" "s12"}
    openSTORES= {"s11" "s12"}
    open= [0 0 1 1]
    OBJ = 24
    y= [[13 0]
             [0 0]]
    STORES= {"s1" "s2" "s11" "s12" "s13"}
    openSTORES= {"s11" "s12" "s13"}
    open= [0 0 1 1 1]
    OBJ = 26
    y= [[14 0]
             [0 0]]
    STORES= {"s1" "s2" "s11" "s12" "s13" "s14"}
    openSTORES= {"s11" "s12" "s13" "s14"}
    open= [0 0 1 1 1 1]
    OBJ = 28
    y= [[15 0]
             [0 0]]
    STORES= {"s1" "s2" "s11" "s12" "s13" "s14" "s15"}
    openSTORES= {"s11" "s12" "s13" "s14" "s15"}
    open= [0 0 1 1 1 1 1]
    OBJ = 30

    regards

     


    #DecisionOptimization
    #OPLusingCPLEXOptimizer