Decision Optimization

Decision Optimization

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


#Analytics
#DecisionOptimization
#DecisionOptimization
 View Only
  • 1.  How can I get access to a sequence?

    Posted 12/09/17 09:02 PM

    Originally posted by: Zefeng


    I am new to cplex. I tried to use CP to solve a problem. The solution is a sequence, defined by: 

    dvar sequence truck[t in 1..m] in all(d in Demands) tvisit[d][t] types all(d in Demands) d.id;

    How can I get access to the id of each interval in the sequence? The sequence truck[t] consists of many intervals tvisit[d][t], I want to get access to the d.id of each interval. 

    I will thank those who help me. 

     


    #DecisionOptimization
    #OPLusingCPLEXOptimizer


  • 2.  Re: How can I get access to a sequence?

    Posted 12/10/17 07:05 AM

    Hi,

    let me give you an example.

    if you run the example at

    https://www.ibm.com/developerworks/community/forums/html/topic?id=5efb1db1-c642-4877-af60-b330f959a534&ps=25

    and then you click on seq in the problem browser you ll see

     

     

    regards


    #DecisionOptimization


  • 3.  Re: How can I get access to a sequence?

    Posted 12/10/17 07:47 AM

    Originally posted by: Zefeng


    Thanks for your answer. 

    Now I am able to see these informations. But I want to get the exact value of the type of each intervals in the sequence, which is the d.id of an interval tvisit[d][t]. These values may be used in postprocessing. For example, I check each interval in the sequence, if the type>=2, then I output the type value to a file. Is this possible? I found that the function typeOfNext can get the type of the intervals, but this function can only be used when declaring a constraint. 


    #DecisionOptimization
    #OPLusingCPLEXOptimizer


  • 4.  Re: How can I get access to a sequence?

    Posted 12/10/17 11:31 AM

    Let me give you an example:

    .mod

     
    using CP;

    tuple Node {
        key string nodeID;
        int x;
        int y;
    }
    {Node} nodes = ...;    

    tuple Visit {
                key int visitID;
                string nodeID;
                int quantity;
                int minTime;
                int maxTime;
                int dropTime;
                  };
    {Visit} clientVisits = ...;   

    tuple Vehicle {
                    key string vehicleID;    
                    string firstVisitID;
                    string lastVisitID;
                    int    capacity;
                    int start;
                    int end;
                }    
    {Vehicle} vehicles = ...;                                
    int numTrucks = card(vehicles);

    dvar interval itvs_vehicle[v in vehicles] in v.start..v.end size v.end-v.start;

    execute
    {
     itvs_vehicle;
    }  
     
    int firstDepotVisitID = min(v in clientVisits) v.visitID - 1;
    int lastDepotVisitID = max(v in clientVisits) v.visitID + 1;
    Visit firstDepotVisit = <firstDepotVisitID,"depot",0,0,230,0>;
    Visit lastDepotVisit = <lastDepotVisitID,"depot",0,0,230,0>;
    {Visit} allVisits = clientVisits union
                // Needs to be generalized for multiple depots
                {firstDepotVisit, lastDepotVisit };

    int horizon = max (v in allVisits) v.maxTime;

    // Create transition distance
    tuple triplet { int c1; int c2; int d; };
    {triplet} Dist = {
          //    <v1.visitID, v2.visitID,
              <ord(allVisits,v1), ord(allVisits,v2),
              ftoi(round(sqrt(pow(n2.x-n1.x,2)+pow(n2.y-n1.y,2))))>
               | v1,v2 in allVisits, n1, n2 in nodes : v1.nodeID == n1.nodeID && v2.nodeID == n2.nodeID };
     
    dvar interval visitInterval[v in clientVisits] in v.minTime..(v.maxTime+v.dropTime) size v.dropTime;
    dvar interval wtvisitInterval [v in clientVisits] size v.dropTime..horizon;
    dvar interval tvisitInterval  [v in allVisits][veh in vehicles]
                      optional(v.visitID!=firstDepotVisitID && v.visitID!=lastDepotVisitID);
    dvar sequence route[veh in vehicles] in all(v in allVisits) tvisitInterval[v][veh]
                                      types all(v in allVisits) /*v.visitID;*/ ord(allVisits,v);
    dvar interval truck [veh in vehicles] optional;
     
    execute {
      cp.param.NoOverlapInferenceLevel = "Medium";
      cp.param.TemporalRelaxation      = "Off";
      cp.param.TimeLimit               = 10
    }

    dexpr int nonTravelTime = sum(v in clientVisits) sizeOf(wtvisitInterval[v]);
    dexpr float travelTime = sum(veh in vehicles) endOf(tvisitInterval[lastDepotVisit][veh]) - nonTravelTime;
    dexpr int nbUsed = sum(veh in vehicles) presenceOf(truck[veh]);
    dexpr int load[veh in vehicles] = sum(v in clientVisits) presenceOf(tvisitInterval[v][veh])*v.quantity;

    minimize staticLex(nbUsed,travelTime);
    subject to  {

      forall(v in clientVisits ) {
        endAtEnd(wtvisitInterval[v], visitInterval[v]);
        startBeforeStart(wtvisitInterval[v], visitInterval[v]);
      }
      forall(veh in vehicles) {
          span (truck[veh], all(v in clientVisits) tvisitInterval[v][veh]);
        noOverlap(route[veh], Dist);          // Travel time
        startOf(tvisitInterval[firstDepotVisit][veh])==0;     // Truck t starts at time 0 from depot
        last (route[veh],tvisitInterval[lastDepotVisit] [veh]); // Truck t returns at depot
        load[veh] <= veh.capacity;                       // Truck capacity
      }
      forall(v in clientVisits)
        alternative(wtvisitInterval[v], all(t in vehicles) tvisitInterval[v][t]); // Truck selection
    }
     
    execute {
      writeln(nbUsed + " vehicles are used");
      writeln("Total travelled distance is " + travelTime);
    }
    range rr=1..4;
    execute {
      for(var veh in vehicles)
      {
    var seq=route[veh];
      writeln("loop");
      var s=seq.first();
      for(var i in rr)
      {
       writeln(s);
       var ty=Opl.typeOfNext(seq,s,0);
       if (ty==0) break;
       writeln("type = ",ty);
       s=seq.next(s) ;
      }
      writeln(s);
    }   
    }  

     

     

    .dat

    nodes = {<"depot" 35 35> <"node1" 41 49> <"node2" 35 17>
             <"node3" 55 45> <"node4" 55 20> <"node5" 15 30>
             <"node6" 25 39> <"node7" 20 50> <"node8" 10 43>
             <"node9" 55 60> <"node10" 30 60> <"node11" 20 65>
             <"node12" 50 35> <"node13" 30 25> <"node14" 15 10>
             <"node15" 30 5> <"node16" 10 20> <"node17" 5 30>
             <"node18" 20 40> <"node19" 15 60> <"node20" 45 65>};
    clientVisits = {<1 "node1" 10 0 204 10>
             <2 "node2" 7 0 202 10>
             <3 "node3" 13 0 197 10>
             <4 "node4" 19 149 159 10>
             <5 "node5" 26 0 199 10>
             <6 "node6" 3 0 208 10>
             <7 "node7" 5 0 198 10>
             <8 "node8" 9 95 105 10>
             <9 "node9" 16 97 107 10>
             <10 "node10" 16 0 194 10>
             <11 "node11" 12 67 77 10>
             <12 "node12" 19 0 205 10>
             <13 "node13" 23 159 169 10>
             <14 "node14" 20 0 187 10>
             <15 "node15" 8 61 71 10>
             <16 "node16" 19 0 190 10>
             <17 "node17" 2 0 189 10>
             <18 "node18" 12 0 204 10>
             <19 "node19" 17 0 187 10>
             <20 "node20" 9 0 188 10>};
    vehicles = {<"vehicle1" "depot" "depot" 200 0 230>
             <"vehicle2" "depot" "depot" 200 0 230>
             <"vehicle3" "depot" "depot" 200 0 230>
             <"vehicle4" "depot" "depot" 200 0 230>
             <"vehicle5" "depot" "depot" 200 0 230>};

     

    regards


    #DecisionOptimization
    #OPLusingCPLEXOptimizer


  • 5.  Re: How can I get access to a sequence?

    Posted 12/10/17 07:59 PM

    Originally posted by: Zefeng


    Thanks for your generous help. Now I understand that functions like typeOfNext should be used as "Opl.typeOfNext", not just "typeOfNext", in execute or main blocks. 


    #DecisionOptimization
    #OPLusingCPLEXOptimizer