Decision Optimization

Decision Optimization

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


#Analytics
#DecisionOptimization
#DecisionOptimization
 View Only
Expand all | Collapse all

differentiate types in a matrix

  • 1.  differentiate types in a matrix

    Posted 08/12/16 04:11 AM

    Originally posted by: Treee


    Hello everyone!

    I am new to CPLEX/OPL and I am trying to model a container terminal. So far my model gives out the minimum distance for my container ( heavy/light NormalContainer/CoolingContainer) in a three dimensional matrix. It works so far but now I have a problem that i cannot differentiate between the different types of containers in my matrix. There should be for example a 1 for a normal heavy container in my matrix, a 2 for a heavy cooling container, a 3 for a light normal container and a 4 for a light cooling container.
    I tried a couple of things but nothing worked. How can i do it?

    my .dat so far :

    nbTypesOfContainers = 4;
    AmountOfContainers = [3,4,5,2];
    //HeavyCooling,LightCooling, HeavyNormal, LightNormal
    Types = 4;
    Rows = 4;
    Columns = 5;
    Tiers = 3;
     
    Distance =  [
                [[ 1 7 13 19 25 ], 
                   [ 3 9 15 21 27 ],
                 [ 5 11 17 23 29 ],
                   [ 7 13 19 25 31 ]],
                
                [[2 8 14 20 26]
                 [4 10 16 22 28]
                 [6 12 18 24 30]
                 [8 14 20 26 32]], 
                
                [[3 9 15 21 27]
                [5 11 17 23 29]
                [7 13 19 25 31]
                [9 15 21 27 33]]

    and my .mod:

    int nbTypesOfContainers = ...;
    range ContainerTypes = 1..nbTypesOfContainers;
    int AmountOfContainers[ContainerTypes] = ...;
    int SumOfAmountOfContainers = AmountOfContainers[1]+AmountOfContainers[2]+AmountOfContainers[3]+AmountOfContainers[4];
    int lock = ...;
    int move = ...;
    int Types = ...;
    range Type = 1..Types;
    int Rows = ...;
    range Row = 1..Rows;
    int Columns = ...;
    range CoolingColumn = 4..Columns;
    range NormalColumn = 1..Columns-2;
    range Column = 1..Columns;
    int Tiers = ...;
    range Tier = 1..Tiers;
    int Distance [Tier][Row][Column] = ...;
    dvar boolean placed[Tier][Row][Column];
    tuple ContainerData
        {
        int value;
        int y;
        int x;
        int z;
        }
     
    sorted {ContainerData} valuesCooling={<Distance[Tier,Row,Column],Tier,Row,Column> | Row in 1..Rows, Column in 4..Columns, Tier in 1..Tiers : Distance[Tier,Row,Column]!=0 };
    sorted {ContainerData} valuesNormal={<Distance[Tier,Row,Column],Tier,Row,Column> | Row in 1..Rows, Column in 1..Columns-2, Tier in 1..Tiers : Distance[Tier,Row,Column]!=0 };
    sorted {ContainerData} minimumAmountOfCoolingContainers={ item(valuesCooling,i) | i in 0..(AmountOfContainers[1]+AmountOfContainers[2])-1};
    float computeSumCooling=sum(i in minimumAmountOfCoolingContainers) i.value /AmountOfCranes+(2*lock*(AmountOfContainers[1]+AmountOfContainers[2]));
    sorted {ContainerData} minimumAmountOfNormalContainers={ item(valuesNormal,i) | i in 0..(AmountOfContainers[3]+AmountOfContainers[4])-1};
    float computeSumNormal=sum(i in minimumAmountOfNormalContainers) i.value /AmountOfCranes+(2*lock*(AmountOfContainers[3]+AmountOfContainers[4]));

    minimize
          sum( t in Tier,r in Row, c in Column)
               Distance[t][r][c]*placed[t][r][c];
                   
           
     subject to {
                    
        ctNormalContainersJustInFirstThreeRows: 
            sum(t in Tier,r in Row, c in NormalColumn)
                  placed[t][r][c] ==(AmountOfContainers[3]+AmountOfContainers[4]);
                 
         ctCoolingContainersJustInLastTwoRows:
             sum(t in Tier,r in Row, c in CoolingColumn)
                  placed[t][r][c] ==(AmountOfContainers[1]+AmountOfContainers[2]);
             
         ctPositionIsFree:    
            forall(t in Tier,r in Row, c in Column)     
                placed[t][r][c] <=1;
                 
         ctPositionInTierOneIsNotFree:
             forall(t in Tier,r in Row, c in Column)     
                placed[2][r][c] <=  placed[1][r][c];
                     
        ctPositionInTierTwoIsNotFree:
             forall(t in Tier,r in Row, c in Column)     
                placed[3][r][c] <=  placed[2][r][c];
                
        CtNoHeavyOnLightContainers:
            forall(t in Tier, r in Row, c in Column)         
     

    execute DISPLAY_RESULTS {
            writeln(placed);
    }
     
    many thanks and kind regards


    #CPLEXOptimizers
    #DecisionOptimization


  • 2.  Re: differentiate types in a matrix

    Posted 08/12/16 04:27 AM

    Note that there is a Forum dedicated to OPL. You may get better answers there.

    Not sure I understood your problem correctly. It seems you just have to use a 4-dimensional instead of a 3-dimensional matrix? The additional dimension being the container type? Or you want the elements in the distance matrix to be tuples rather than numbers?


    #CPLEXOptimizers
    #DecisionOptimization


  • 3.  Re: differentiate types in a matrix

    Posted 08/12/16 04:38 AM

    Originally posted by: Treee


    Hey,

    yes I posted my problem in this forum already, but no one answered for about 10 days...

    in my placed matrix, which will be given out, there ist just a "1" when there is a container and a "0" when there is no container. But i want a "2" for example, when there is a heavy cooling container and not a "1". I declared that the cooling containers have to be stored in the last two columns of my placed matrix, and now there should be a "2" for a heavy coolingContainer and a "4" for a light CoolingContainer.

    When i add a fourth dimension to my placed matrix, wouldnt i just get a bigger matrix displayed and not for example a "2" for a heavy cooling Container?

    kind regards


    #CPLEXOptimizers
    #DecisionOptimization


  • 4.  Re: differentiate types in a matrix

    Posted 08/12/16 05:54 AM

    As far as I can see, your model does not distinguish between container types. You have two constraints that require assignment of containers: ctNormalContainersJustInFirstThreeRows and ctCoolingContainersJustInLastTwoRows. But these constraints just require that a certain number of containers is assigned. For example, the first constraint does not say "assign n type 3 and k type 4 containers". It just says "assign n+k containers".

    So I think you need to indeed add a fourth dimension (the container type) to your placed matrix so that you can distinguish the type of containers placed. You would still get only 1s in the output matrix, but these can be interpreted as container types easily:

    places[t][r][c][1] == 1 <-> container of type 1 is placed at (t,r,c)
    ...
    places[t][r][c][4] == 1 <-> container of type 1 is placed at (t,r,c)

    You can either interpret this directly or adjust the output via oplscript (untested):

    for (var t in Tier)
      for (var r in Row)
        for (var c in Column) {
          val = 0;
          for (var tp in Type) {
            if ( placed[t][r][c][tp] > 0.5 ) val = tp;
          }
          write(val + " ");
        }


    #CPLEXOptimizers
    #DecisionOptimization


  • 5.  Re: differentiate types in a matrix

    Posted 08/15/16 09:23 AM

    Originally posted by: Treee


    thank you for your fast replay!

    yeah now i got it and it works, thanks =)

    now i want a constraint, that heavy containers cannot be stored on light containers. I tried :

    CtNoHeavyOnLightNormalContainers:
            forall( t in Tier, r in Row, c in NormalColumn)
                placedTypes[2][t][r][c] <=  placedTypes[1][t][r][c];  // [ContainerType][Tier][Row][Column]

    But that did not work. Do you have an idea, how i can do such a constraint?

     

    kind regards


    #CPLEXOptimizers
    #DecisionOptimization


  • 6.  Re: differentiate types in a matrix

    Posted 08/15/16 12:43 PM

    Your constraint states: "if there is a container of type 2 in (t,r,c) then there must also be a container of type 1 in that place". This indeed does not look correct.

    I guess what you want is: "If there is a container of type 2 in (t,r,c) then there cannot be a container of type 1 in that place". That would be

    placedTypes[1][t][r][c] <= 1 - placedTypes[2][t][r][c]

    Or maybe you only want one container type in one position:

    sum(type in Types) placedTypes[type][t][r][c] <= 1

     


    #CPLEXOptimizers
    #DecisionOptimization


  • 7.  Re: differentiate types in a matrix

    Posted 08/16/16 04:52 AM

    Originally posted by: Treee


    ah thanks!  It works, slowly i am getting into the thinking of how to formulate a constraint. It is kind of difficult to think in that way when you are new to coding.

    But many thanks for your answer.

     

    Kind regards


    #CPLEXOptimizers
    #DecisionOptimization


  • 8.  Re: differentiate types in a matrix

    Posted 08/16/16 09:03 AM

    Originally posted by: Treee


    The problem now is, that, because of the new constraints, my total distance covered sum is not correct anymore (computeSumNormal + computeSumCooling)....

    Is there a possibility to sum up alle the values of my distance matrix, where placedTypes is 1?

    It should be :

    for (var t in Tier)
      for (var r in Row)
        for (var c in Column)

          for (var t in ContainerTypes {
          val = 0;
            if ( placedTypes[t][r][c][tp] = 1 ) 

                                  //get the value from distance[t][r][c] and add it to val}
        }

     

    Sorry for the many questions but i want to get into coding and a good way for me is to have an example for many different cases, so i get a clue how you professionals think ;)

     

     

     


    #CPLEXOptimizers
    #DecisionOptimization


  • 9.  Re: differentiate types in a matrix

    Posted 08/16/16 01:34 PM

    I suggest you go through the various OPL examples and tutorials that come with CPLEX. That will tell you how to write models in OPL and how to express certain conditions.

    In your code it looks as if you wrote '=' instead of '==' to test a value? '=' is the assignment operator and since you are assigning a true value the test will always be true.


    #CPLEXOptimizers
    #DecisionOptimization


  • 10.  Re: differentiate types in a matrix

    Posted 08/19/16 08:11 AM

    Originally posted by: Treee


    I made a constraint that the totalSumOfDistances shall not be bigger than the departure time: 

        ctNotLongerThatDepartureTime:
            sum(a in ContainerTypes, t in Tier, r in Row, c in Column)
                placedTypes[a][t][r][c]*Distance[t][r][c] <= DepartureTime;

     

    This works good, i get a conflict, when the departure time is f.e. 40 and the total distance is f.e. 50.

    Is there a way, to display the sum of the total distance?

    I could not find such a case in the examples...


    #CPLEXOptimizers
    #DecisionOptimization


  • 11.  Re: differentiate types in a matrix

    Posted 08/19/16 08:48 AM

    Originally posted by: VincentBeraudier


    Something like:

    int total = sum(t in Tier, r in Row, c in Column) Distance[t][r][c];

    should work.

    or 

    execute{

    var tot = 0;

    for (var t in Tier)

        for (var r in Row)

            for (var c in Column)

                   tot += Distance[t][r][c];

    }

     

    in Javascript


    #CPLEXOptimizers
    #DecisionOptimization


  • 12.  Re: differentiate types in a matrix

    Posted 08/19/16 11:09 AM

    Originally posted by: Treee


    Thank you for your answer, but i mean the sum of distance, where placedTypes is 1.

     

    when i add placedTypes to your "int total" then CPLEX says, that a decision variable is not valid.

     

    regards


    #CPLEXOptimizers
    #DecisionOptimization


  • 13.  Re: differentiate types in a matrix

    Posted 08/22/16 03:31 AM

    Originally posted by: VincentBeraudier


    Something like:

    int total = sum(tp in Type, t in Tier, r in Row, c in Column : placedTypes[t][r][c][tp] == 1) Distance[t][r][c];

    should work.

    or 

    execute{

    var tot = 0;

    for (var tp in Type)

    for (var t in Tier)

        for (var r in Row)

            for (var c in Column)

              if (placedTypes[t][r][c][tp].solutionValue == 1)

                   tot += Distance[t][r][c][tp];

    }


    #CPLEXOptimizers
    #DecisionOptimization


  • 14.  Re: differentiate types in a matrix

    Posted 08/22/16 11:25 AM

    Originally posted by: Treee


    in the execute block it works, thanks for that! 

    int total = sum(tp in Type, t in Tier, r in Row, c in Column : placedTypes[t][r][c][tp] == 1) Distance[t][r][c];

     

    there he still says, that a decisionvariable is not valid...

    kind regards

     


    #CPLEXOptimizers
    #DecisionOptimization


  • 15.  Re: differentiate types in a matrix

    Posted 08/22/16 12:10 PM

    Originally posted by: VincentBeraudier


    To be able to use a decision variable value as a filter, it has to be in the post processing block after the constraint block (the value of the decision var needs to be resolved).

    You cannot use it in the constraint block.

    Example that works: 

    range R = 1..5;

    int X[i in R][j in R][k in R] = i+j+k;

    dvar int Y[R][R][R] in 0..1;

     

    maximize sum(i in R, j in R, k in R) Y[i][j][k];

    subject to{

    forall(i in R, j in R, k in R : i%2 == 0 && j %2 == 0 && k %2 == 0)

        Y[i][j][k] == 0;

     

    }

    int mySum = sum(i in R, j in R, k in R : Y[i][j][k] == 1) 1;

    execute{

    writeln(mySum);

    }


    #CPLEXOptimizers
    #DecisionOptimization


  • 16.  Re: differentiate types in a matrix

    Posted 08/23/16 06:20 AM

    Originally posted by: Treee


    ah yes...i oversaw a "}" and i was wondering why it does not work :D

     

    when i have in .dat : 

    Container = {<"Container1" 1 1000 5>  <"Container3" 3 1100 2> <"Container2" 2 500 1> <"Container4" 1 900 2> <"Container5" 4 550 4>
                 <"Container6" 3 800 4>  <"Container7" 2 400 4> <"Container8" 2 730 1> <"Container9" 1 1300 10> <"Container10" 4 330 3>};

    and in mod: 

    tuple ContainerDat {
    key string Containername; 
    int type;
    int weight;
    int duration;
    }

    {ContainerDaten} Container = ...;

    how can get the sum, where the type is 1? (would be container 1,4,9, so the sum would be 3)

    i tried a couple of things, but CPLEX does not give me right sum..

     

    kind regards


    #CPLEXOptimizers
    #DecisionOptimization