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