Decision Optimization

Decision Optimization

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


#Analytics
#DecisionOptimization
#DecisionOptimization
 View Only
  • 1.  Please help regarding tuples initialization

    Posted 06/09/20 03:15 AM

    Dear Community members,

    I am relatively new to OPL that is why I need your help regarding tuples initialization, which is a completely new topic to me. 
    I am currently working on a time-space network. Unfortunately, I am stuck at implementing one of constraints. The idea behind the time-space network is that each node(vertice) is replicated once for each period. Nodes are connected into arcs: service arcs, where the flow is in time and in space, and waiting arcs, where the flow is only in time. Both arcs I declared as tuples with their costs and capacity. I also have demand at some of the nodes, which I also declared as a tuple, with an origin, destination and actual volume of products to be transported to nodes. I have a problem implementing one of constraints (flow conservation, ct5), which says that the difference between an outflow and an inflow for a source node is a positive demand and for a sink node is a negative demand. Unfortunately, with my declaration of a demand as a tuple, I cannot write properly this constraint. I attached the mathematical formulation of the constraint. 
    Could you please advise, how I can change my model or how to formulate this constraint properly? Your advice is much appreciated. 


    int NumNodes = 5; // Number of nodes, where 1 is the stock and 2 to 5 are customers
    range Nodes = 1..NumNodes;

    int Tmax = 7; // Number of periods aka planning horizon
    range T = 1..Tmax;

    {int} Vehicle={1,2,3}; //Vehicles
    float FixCost=50; //fixed cost for using vehicles


    tuple StaticArc { // defining physical arcs
    int fromnode;
    int tonode;

    }
    {StaticArc} arcs ={<f,t> | f in Nodes, t in Nodes};

    tuple TimeNode { //Defining a node replicated in time
    int node;
    int time;
    }
    {TimeNode} tnodes = { <n,t> | n in Nodes, t in T };


    tuple ServiceArc {                 //Defining a Service Arc in time in space
    TimeNode FromNode;          //from
    TimeNode ToNode;               //to
    float cost;               //equals 1 for all service arcs
    int capacity;//capacity equals 1000 for all service arcs
    }
    {ServiceArc} sarcs = { <<i,s>,<j,e>,1.0,100> | <i,j> in arcs, s in T, e in T : e > s};

    tuple HoldingArc{               //Defining a Holding Arc, only in time, aka waiting times at nodes
    TimeNode FromNode;               //from
    TimeNode ToNode;               //to
    float cost;               //equals 0.15 for all holding arcs
    int capacity;               //capacity equals 100 for all holding arcs
    }
    {HoldingArc} harcs = { <<i,s>,<i,e>,0.15,100> | <i,i> in arcs, s in T, e in T : e > s};

    tuple Arcs{               //Union of both service & holding arcs
    TimeNode FromNode;               //from
    TimeNode ToNode;               //to
    float cost;
    int capacity;               
    }

    tuple DemandInfo{               //deterministic demand with origin and destination
    TimeNode Origin;               //origin node in time
    TimeNode Destination;               //destination node in time
    int vol;               // demand volume
    }

    {Arcs} allarcs = { <a.FromNode, a.ToNode, a.cost, a.capacity>| a in sarcs } union { <a.FromNode, a.ToNode, a.cost,a.capacity>| a in harcs};

    {Arcs} ij [ FromNode in tnodes] = {a| a in allarcs:a.FromNode==FromNode};               //ij for ct4&2
    {Arcs} ji [ FromNode in tnodes]= {a| a in allarcs:a.ToNode==FromNode};               //ji for ct4&2
    {DemandInfo} demand={<<1,1>,<2,2>,6>,<<1,3>,<3,5>,6>,<<1,6>,<4,7>,4>,<<1,2>,<5,4>,4>};               //od

    //Variables
    dvar boolean theta [Vehicle];               // binary variable if a vehicle v is utilized
    dvar boolean y [allarcs][Vehicle];               //binary var for arc selection indexed by vehicles
    dvar float x[allarcs];               //packages flows between nodes

    //Objective
    dexpr float TotalCost = sum (v in Vehicle)FixCost*theta[v]+sum(a in allarcs) a.cost*x[a];
    minimize TotalCost;

    //Constraints
    subject to{

    //ct2
    forall (v in Vehicle)               //if n asset is utilized, it should engage in only one activity
    sum(a in allarcs) y[a][v]==theta[v];
    //ct3
    forall (FromNode in tnodes, v in Vehicle)              

    //number of incoming&outgoing arcs for each node is equal
    sum (a in ij[FromNode]) y[a][v]==sum (a in ji[FromNode]) y[a][v];
    //ct4
    forall (s in sarcs) //only one asset operates a selected service
    sum(v in Vehicle) y[s][v] <= 1;

    //ct5 flow conservation
    forall (FromNode==Origin in tnodes)
    sum (a in ij[FromNode]) x[a]-sum (a in ji[FromNode]) x[a]==??demand??;
    forall (FromNode==Destination in tnodes)
    sum (a in ij[FromNode]) x[a]-sum (a in ji[FromNode]) x[a]==??-demand??;
    forall (FromNode in tnodes)
    sum (a in ij[FromNode]) x[a]-sum (a in ji[FromNode]) x[a]==0;

    //ct6
    forall (s in sarcs)//service arc capacities constraint
    x[s]<=sum(v in Vehicle)y[s][v]*s.capacity;
    //ct7
    forall (s in sarcs)// flows to zero when service arc not open
    x[s]<=sum(d in demand,v in Vehicle)y[s][v]*d.vol;

    }



    ------------------------------
    Irina Tremaskina
    ------------------------------

    #DecisionOptimization


  • 2.  RE: Please help regarding tuples initialization

    Posted 06/09/20 05:00 AM
    I assume the problem is only the right-hand side of the constraint? You can get the total demand at a node by summing up all the demand arcs that enter or leave it:
    - sum(d in demand : d.Origin == i) d.vol // outgoing demand
    + sum(d in demand : d.Destination== i) d.vol

    ------------------------------
    Daniel Junglas
    ------------------------------