# CMND WITH LIFETIME RESTRICTIONS AND AN EXPONENTIAL QUALITY LOSS FUNCTION #
### Sets ###set N; # set of nodes set A within N cross N; # set of directed arcsset S within N; # set of suppliersset D within N; # set of demand nodesset T:= {i in N: i not in S and i not in D}; # set of transshipment pointsset P; # set of products set K; # set of commodities representing due dates
### Parameters ###param xcoord{i in N}; # x-coordinate of node iparam ycoord{i in N}; # y-coordinate of node iparam f{(i,j) in A} >=0; # fixed cost applied on arc (i,j)param u{(i,j) in A} >=0; # capacity of arc (i,j)param supply{i in S, k in K} >=0; # supply of commodity k from supplier sparam demand{i in D, p in P} >=0; # demand in node i for product pparam distance{(i,j) in A}:= round((sqrt((xcoord[i] - xcoord[j])^2 + (ycoord[i] - ycoord[j])^2))); # distance over arc (i,j)param t{(i,j) in A}:= round(distance[i,j]/1.2); # travel time over arc (i,j) in hoursparam tc:= 0.0179; # transportation cost per unit per hourparam rcf; # relative cost factorparam c{(i,j) in A, k in K}:= tc * t[i,j] * rcf; # variable transportation cost per unit over arc (i,j)param E{k in K} symbolic in P; # the product represented by commodity k param b{(i,j) in A, p in P}:= min(demand[i,p],u[i,j]); # an upper bound of the flow of product p on arc (i,j)param slmin{k in K} >=0; # point in time where commodity k starts deteriorating in daysparam slmax{k in K} >=0; # maximum shelf life of commodity k in daysparam M; # "Big M": sufficiently large number param price{k in K} >=0; # price of commodity kparam rate{k in K}; # decay rate per hour in dollars
### Decision variables ###var x{(i,j) in A, k in K} >=0 integer; # flow distribution decision variable indicating the amount of flow of commodity k on arc (i,j)var y{(i,j) in A} binary; # design variable; equals 1 if (i,j) is selected in the final design and 0 if otherwisevar z{(i,j) in A, k in K} binary; # 1 if commodity k travels on arc (i,j), 0 if otherwisevar a{i in N, k in K} >=0; # arrival time of commodity k in node i in daysvar w{i in N, k in K} >=0; # arrival time of commodity k in destination node i in days
### Objective function ###minimize TotalCost: sum{(i,j) in A, k in K} c[i,j,k] * x[i,j,k] + # transportation costs sum{(i,j) in A} f[i,j] * y[i,j] + # fixed costs sum{k in K, i in D, p in P: p = E[k]} demand[i,p] * price[k] * (1 - exp(-rate[k] * w[i,k])) + # decay costs sum{i in N, k in K} 0.0001 * w[i,k] + sum{i in N, k in K} 0.0001 * a[i,k]; ### Constraints ###s.t. DemandConstraint{p in P, i in D}: sum{k in K: E[k] = p} (sum{(j,i) in A} x[j,i,k] - sum{(i,j) in A} x[i,j,k]) = demand[i,p]; s.t. SupplyConstraint{k in K, i in S}: sum{(i,j) in A} x[i,j,k] - sum{(j,i) in A} x[j,i,k] <= supply[i,k]; s.t. FlowConservationConstraint{k in K, i in T}: sum{(i,j) in A} x[i,j,k] - sum{(j,i) in A} x[j,i,k] = 0; s.t. ArcCapacity{(i,j) in A}: sum{k in K} x[i,j,k] <= u[i,j] * y[i,j]; s.t. ArrivalTimeForEachPath{k in K, (i,j) in A}: a[i,k] + t[i,j] <= a[j,k] + M * (1 - z[i,j,k]); s.t. LifetimeRestriction{i in N, k in K}: a[i,k] <= slmax[k]; s.t. DecayPenalty{i in D, k in K}: a[i,k] <= slmin[k] + w[i,k]; s.t. MaxFlow1{k in K, (i,j) in A}: x[i,j,k] <= M * z[i,j,k];
s.t. MaxFlow2{k in K, (i,j) in A}: z[i,j,k] <= y[i,j]; s.t. Starttime{i in S, k in K}: a[i,k] = 0;
# CMND WITH LIFETIME RESTRICTIONS AND A LINEAR LOSS FUNCTION #
### Sets ###set N; # set of nodes set A within N cross N; # set of directed arcsset S within N; # set of suppliersset D within N; # set of demand nodesset T:= {i in N: i not in S and i not in D}; # set of transshipment pointsset P; # set of products set K; # set of commodities representing due dates
### Parameters ###param xcoord{i in N}; # x-coordinate of node iparam ycoord{i in N}; # y-coordinate of node iparam f{(i,j) in A}:= round(Uniform(1000,3000)) >=0; # fixed cost applied on arc (i,j)param u{(i,j) in A}:= round(Uniform(10000,50000)) >=0; # capacity of arc (i,j)param supply{i in S, k in K}:= round(Uniform(0,10000)) >=0; # supply of commodity k from supplier sparam demand{i in D, p in P}:= round(Uniform(2500,7500)) >=0; # demand in node i for product pparam tc:= 0.0179:= Uniform(0.41,0.50); # transportation cost per unit per dayparam distance{(i,j) in A}:= round((sqrt((xcoord[i] - xcoord[j])^2 + (ycoord[i] - ycoord[j])^2))); # distance over arc (i,j)param t{(i,j) in A}:= round(distance[i,j])/1.2; # travel time over arc (i,j)param rcf; # relative cost factorparam c{(i,j) in A, k in K}:= tc * t[i,j] * rcf; # variable transportation cost per unit over arc (i,j)param E{k in K}; # the product represented by commodity k param slmin{k in K} >=0; # point in time where commodity k starts deteriorating in daysparam slmax{k in K} >=0; # maximum shelf life of commodity k in daysparam M; # "Big M": sufficiently large number param price{k in K} >=0; # price of commodity kparam rate{k in K} >=0; # penalty rate per day
### Decision variables ###var x{(i,j) in A, k in K} >=0 integer; # flow distribution decision variable indicating the amount of flow of commodity k on arc (i,j)var y{(i,j) in A} binary; # design variable; equals 1 if (i,j) is selected in the final design and 0 if otherwisevar z{(i,j) in A, k in K} binary; # 1 if commodity k travels on arc (i,j), 0 if otherwisevar a{i in N, k in K} >=0; # arrival time of commodity k in node i in daysvar w{i in N, k in K} >=0; # arrival time of commodity k in destination node i in days
### Objective function ###minimize TotalCost: sum{(i,j) in A, k in K} c[i,j,k] * x[i,j,k] + # transportation costs sum{(i,j) in A} f[i,j] * y[i,j] + # fixed costs sum{k in K, i in D, p in P: p = E[k]} (rate[k] * demand[i,p] * price[k] * w[i,k]) + # decay costs sum{i in N, k in K} 0.0001 * w[i,k]; ### Constraints ###s.t. DemandConstraint{p in P, i in D}: sum{k in K: E[k] = p} (sum{(j,i) in A} x[j,i,k] - sum{(i,j) in A} x[i,j,k]) = demand[i,p]; s.t. SupplyConstraint{k in K, i in S}: sum{(i,j) in A} x[i,j,k] - sum{(j,i) in A} x[j,i,k] <= supply[i,k]; s.t. FlowConservationConstraint{k in K, i in T}: sum{(i,j) in A} x[i,j,k] - sum{(j,i) in A} x[j,i,k] = 0; s.t. ArcCapacity1{(i,j) in A}: sum{k in K} x[i,j,k] <= u[i,j] * y[i,j]; s.t. ArrivalTimeForEachPath{k in K, (i,j) in A}: a[i,k] + t[i,j] <= a[j,k] + M * (1 - z[i,j,k]); s.t. LifetimeRestriction{i in N, k in K}: a[i,k] <= slmax[k]; s.t. DecayPenalty{i in D, k in K}: a[i,k] <= slmin[k] + w[i,k]; s.t. MaxFlow1{k in K, (i,j) in A}: x[i,j,k] <= M * z[i,j,k]; s.t. MaxFlow2{k in K, (i,j) in A}: z[i,j,k] <= y[i,j]; s.t. Starttime{i in S, k in K}: a[i,k] = 0;
s.t. MaxFlow3{k in K, (i,j) in A}: y[i,j] <= x[i,j,k];
s.t. ArcCapacity1{(i,j) in A}: sum{k in K} x[i,j,k] <= u[i,j] * y[i,j];
s.t. MaxFlow1{k in K, (i,j) in A}:
x[i,j,k] <= M * z[i,j,k]; s.t. MaxFlow2{k in K, (i,j) in A}: z[i,j,k] <= y[i,j];
let y['T2','D6'] := 0;
let y['T2','D6'] := 0;
let y['T1','D3'] := 0;
let y['S1','D4'] := 0;
ampl: display y;y [*,*] (tr): S1 S2 S3 S4 S5 T1 T2 T3 :=D1 . . . . . 1 0 0D2 . . . . . 1 0 0D3 . . . . . 1 0 0D4 . . . . . 0 1 0D5 . . . . . 0 0 1D6 . . . . . 0 1 1T1 1 0 1 1 1 . . .T2 0 1 0 1 0 . . .T3 1 0 0 1 0 . . .;
let y['A','B',3] := 0;
s.t. maxflow3{k in K, (i,j) in A}:
y[i,j] <= x[i,j,k];