Rob Thanks a lot for the comments and fixes. Here are my replies to your points. I will reply in the next thread about the model run results with these. 1) Yes. I have new BOX , Unique_T1 and Unique_T2 tables in model. 2) The binary variable " Is_BoxAvalable_for_a_lane" is not used in the model right now, but may be in future. So probably I can get rid of it as it does not get used in model. 3) I have changed to like this based on the linkage between i and w: impvar VolumeInsideBox_CFS {b in BOX, w in T2} = sum{i in ISN:T2_ISN[i]=w} Volume_ISN[i] * Proportion_CFS[b,w]; 4) Got it. Changed it. 5) Got the reason for non-linearity. Changed it. 6) Changed it like this below: The only change is adding a clause of T2_ISN[i]=w so that only relevant ISN in that week are picked. Similar to approach taken for #3 above. impvar VolBasedCost_CFS {b in BOX, w in T2} = sum{i in ISN:T2_ISN[i]=w}
sum {<Org_ISN[i],Des_ISN[i],m,T1_ISN[i],T2_ISN[i]> in PerVol_Based_Rate_NoZeroes}
PerVol_Based_Rate[Org_ISN[i],Des_ISN[i],'CFS',T1_ISN[i],T2_ISN[i]] * VolumeInsideBox_CFS[b,w]; 7) I have removed Is_ISN_MOL. 😎Changed similar to #3 and #7 by removing Is_ISN_MOL and adding T2_ISN[i]=w 9) I am good with constraint SumProportiontoOne_CYS. But the constraint SumProportionOne_CFS i am not sure why you are adding the sum and enforcing it to be 1 on the right hand side. I would think this as saying forcing it via CFS? So i tried this one below but got syntax issues:. /*sum {i in ISN:T2_ISN[i]=w,b in BOX} Proportion_CFS[b,w] = Is_ISN_MOL[i,'CFS'];*/ The idea of this constraint is to say if some ISNs are chosen by the model go via CFS, then only for those ISN's volume, when the model determines the asset mix, the proportion of the boxes should add up to 1. If CFS is not at all chosen for that week, then the proportion is 0. 10) Got it. Changed it. 11) Create Data step: Incorporated your changes Here is my full code below: proc optmodel;
set <str> ORG;
read data CASUSER.Unique_ORG into ORG = [ORG];
set <str> DES;
read data CASUSER.Unique_DES into DES = [DES];
set <str> BOX;
read data CASUSER.Unique_BOX into BOX = [BOX];
set <str> MOL;
read data CASUSER.Unique_MOL into MOL = [MOL];
set <str> T1;
read data CASUSER.Unique_T1 into T1 = [T1];
set <str> T2;
read data CASUSER.Unique_T2 into T2 = [T2];
/*Read ISN Wt and Volume for a given ISN* - START */
set <str> ISN;
str Org_ISN {ISN};
str Des_ISN {ISN};
str T1_ISN {ISN};
str T2_ISN {ISN};
num Volume_ISN {ISN};
num Weight_ISN {ISN};
read data CASUSER.InputData_AssetMix into ISN=[ISN] Org_ISN=ORG Des_ISN=DES Volume_ISN=Volume Weight_ISN=Weight T1_ISN=T1 T2_ISN=T2;
/*Read ISN Wt and Volume for a given ISN* - END*/
/*Read Wt and Volume Capacity for a given ORG, DES, BOX - START */
num Volume_Min {ORG,DES,BOX,MOL,T1,T2} init 0;
num Weight_Capacity {ORG,DES,BOX,MOL,T1,T2} init 0; num Weight_Min {ORG,DES,BOX,MOL,T1,T2} init 0;
read data CASUSER.BOXSPECS into [ORG DES BOX MOL T1 T2]
Weight_Capacity=Weight_Capacity
Volume_Min=Volume_Min
Weight_Min=Weight_Min;
num Volume_Capacity {BOX};
read data CASUSER.BOXSPECS into [BOX] Volume_Capacity=Volume_Capacity;
num Volume_Capacity_CFS{BOX,T2};
read data CASUSER.BOXSPECS into [BOX T2] Volume_Capacity_CFS=Volume_Capacity;
/*Read Wt and Volume Capacity for a given ORG, DES, BOX - END */
/* Decision Variable - START */
var BOXNeeded_CYS {i in ISN,b in BOX} >= 0 integer <= ceil(Volume_ISN[i] / Volume_Capacity[b]);
var BOXNeeded_CFS {b in BOX,w in T2} integer >=0 <= ceil(sum {i in ISN} Volume_ISN[i] / Volume_Capacity[b]);
var Is_ISN_MOL{ISN,MOL} binary;
var Proportion_CYS {ISN,BOX} >= 0 <= 1;
impvar VolumeInsideBox_CYS {i in ISN, b in BOX} = Volume_ISN[i] * Proportion_CYS[i,b];
var Proportion_CFS {BOX,T2} >= 0 <= 1;
impvar VolumeInsideBox_CFS {b in BOX, w in T2} = sum{i in ISN:T2_ISN[i]=w} Volume_ISN[i] * Proportion_CFS[b,w];
impvar TotalVol {m in MOL,w in T2} = sum {i in ISN} Volume_ISN[i] * Is_ISN_MOL[i,m];
/*impvar VolumeInsideBox_CFS {b in BOX, w in T2}=TotalVol['CFS',w]*Proportion_CFS[b,w];*/
/* Decision Variable and Associated Impvars - END */
/*Define Rates and ImplicitVariables START */
/*Box Based Costs START */
set <str,str,str,str,str,str> PerBox_Based_Rate_NoZeroes;
num PerBox_Based_Rate {PerBox_Based_Rate_NoZeroes};
read data CASUSER.BOXRATE (where=(RateBasis="PerBox" and Ratetype='Linehaul' and Rate>0))
into PerBox_Based_Rate_NoZeroes=[ORG DES BOX MOL T1 T2] PerBox_Based_Rate=Rate;
impvar PerBox_Based_Costs_CYS {i in ISN} = sum {b in BOX}
PerBox_Based_Rate[Org_ISN[i],Des_ISN[i],b,'CYS',T1_ISN[i],T2_ISN[i]] * BOXNeeded_CYS[i,b];
set <str,str> PerBox_Based_Rate_NoZeroes_CFS;
num PerBox_Based_Rate_CFS {PerBox_Based_Rate_NoZeroes_CFS};
read data CASUSER.BOXRATE (where=(RateBasis="PerBox" and Ratetype='Linehaul' and 'CFS' and Rate>0))
into PerBox_Based_Rate_NoZeroes_CFS=[BOX T2] PerBox_Based_Rate_CFS=Rate;
impvar PerBox_Based_Costs_CFS {w in T2} = sum {b in BOX} PerBox_Based_Rate_CFS[b,w] * BOXNeeded_CFS[b,w];
impvar TotalBoxBasedCost = sum {i in ISN} PerBox_Based_Costs_CYS[i] + sum {w in T2} PerBox_Based_Costs_CFS[w];
/*Box Based Costs END */
/*Vol Based Costs START*/
set <str,str,str,str,str> PerVol_Based_Rate_NoZeroes;
num PerVol_Based_Rate {PerVol_Based_Rate_NoZeroes} init 0;
read data CASUSER.BOXRATE (where=(RateBasis="PerVolUOM" and Ratetype='Origin' and Rate>=0))
into PerVol_Based_Rate_NoZeroes=[ORG DES MOL T1 T2] PerVol_Based_Rate=Rate;
impvar VolBasedCost_CYS {i in ISN, b in BOX} =
sum {<Org_ISN[i],Des_ISN[i],m,T1_ISN[i],T2_ISN[i]> in PerVol_Based_Rate_NoZeroes}
PerVol_Based_Rate[Org_ISN[i],Des_ISN[i],'CYS',T1_ISN[i],T2_ISN[i]] * VolumeInsideBox_CYS[i,b];
impvar VolBasedCost_CFS {b in BOX, w in T2} = sum{i in ISN}
sum {<Org_ISN[i],Des_ISN[i],m,T1_ISN[i],T2_ISN[i]> in PerVol_Based_Rate_NoZeroes}
PerVol_Based_Rate[Org_ISN[i],Des_ISN[i],'CFS',T1_ISN[i],T2_ISN[i]] * VolumeInsideBox_CFS[b,w];
impvar TotalVolBasedCost = sum {i in ISN, b in BOX} VolBasedCost_CYS[i,b] + sum {b in BOX, w in T2}VolBasedCost_CFS[b,w];
/*Vol Based Costs END*/
/*Shipment Based Costs START*/
set <str,str,str,str,str> PerShp_Based_Rate_NoZeroes;
num PerShp_Based_Rate {PerShp_Based_Rate_NoZeroes};
read data CASUSER.BOXRATE (where=(RateBasis="PerShipment" and Ratetype='Document' and Rate>=0))
into PerShp_Based_Rate_NoZeroes=[ORG DES MOL T1 T2] PerShp_Based_Rate=Rate;
impvar ShipmentBasedCost_CYS {i in ISN, b in BOX} = Proportion_CYS[i,b] *
sum {<Org_ISN[i],Des_ISN[i],m,T1_ISN[i],T2_ISN[i]> in PerShp_Based_Rate_NoZeroes}
PerShp_Based_Rate[Org_ISN[i],Des_ISN[i],'CYS',T1_ISN[i],T2_ISN[i]];
impvar ShipmentBasedCost_CFS {b in BOX, w in T2} = sum{i in ISN:T2_ISN[i]=w} Proportion_CFS[b,w]*
sum {<Org_ISN[i],Des_ISN[i],m,T1_ISN[i],T2_ISN[i]> in PerShp_Based_Rate_NoZeroes}
PerShp_Based_Rate[Org_ISN[i],Des_ISN[i],'CFS',T1_ISN[i],T2_ISN[i]];
impvar TotalShipmentBasedCost = sum {i in ISN, b in BOX} ShipmentBasedCost_CYS[i,b] + sum {b in BOX, w in T2}ShipmentBasedCost_CFS[b,w];
/*Shipment Based Costs END*/
/*Define Rates and ImplicitVariables END*/
Min TotalCost = TotalBoxBasedCost+ TotalVolBasedCost + TotalShipmentBasedCost;
/* Constraints START*/
con OneMOL{i in ISN}:
sum{m in MOL} Is_ISN_MOL[i,m] = 1; /* This is to make sure one ISN can go either CYS or CFS */
con SumProportionToOne_CYS {i in ISN}:
sum {b in BOX} Proportion_CYS[i,b] = IS_ISN_MOL[i,'CYS'];
con SumProportionToOne_CFS {w in T2}:
sum {b in BOX} Proportion_CFS[b,w] = 1;
/*sum {i in ISN:T2_ISN[i]=w,b in BOX} Proportion_CFS[b,w] = Is_ISN_MOL[i,'CFS'];*/
/*expand SumProportionToOne_CFS;*/
con BoxConCYS {i in ISN, b in BOX}:
Volume_Capacity[b] * BOXNeeded_CYS[i,b] >= VolumeInsideBox_CYS[i,b];
con BoxConCFS {w in T2, b in BOX}:
Volume_Capacity_CFS[b,w] * BOXNeeded_CFS[b,w] >= VolumeInsideBox_CFS[b,w];
solve with milp / decomp=(method=concomp);
num optCYSCost {ISN,BOX};
for {i in ISN, b in BOX} optCYSCost[i,b] = PerBox_Based_Costs_CYS[i] + VolBasedCost_CYS[i,b] + ShipmentBasedCost_CYS[i,b];
print PerBox_Based_Costs_CYS VolBasedCost_CYS ShipmentBasedCost_CYS optCYSCost;
num volShareCFS {i in ISN,w in T2} = Volume_ISN[i] * Is_ISN_MOL[i,'CFS'].sol / TotalVol['CFS',w].sol;
print Is_ISN_MOL;
print BOXNeeded_CYS BOXNeeded_CFS;
print PerBox_Based_Costs_CYS PerBox_Based_Costs_CFS;
print volShareCFS VolBasedCost_CFS VolBasedCost_CYS TotalVolBasedCost TotalVol;
print ShipmentBasedCost_CYS;
/* Output*/
create data CASUSER.SolutionDataCYS from [ISN=i BoxType=b]={i in ISN, b in BOX: BOXNeeded_CYS[i,b] > 0.5}
MOL='CYS'
Org=Org_ISN[i]
Des=Des_ISN[i]
T1=T1_ISN[i]
T2=T2_ISN[i]
Volume=Volume_ISN[i]
Weight=Weight_ISN[i]
BoxNeeded=BOXNeeded_CYS
ShipmentVolume=Volume_ISN[i]
Proportion=Proportion_CYS[i,b]
VolumeInsideBox=VolumeInsideBox_CYS[i,b]
VolShare=1
BoxBasedCost=(PerBox_Based_Rate[ORG_ISN[i],Des_ISN[i],b,'CYS',T1_ISN[i],T2_ISN[i]]*BOXNeeded_CYS[i,b])
VolBasedCost=VolBasedCost_CYS[i,b]
ShipmentBasedCost=PerShp_Based_Rate[Org_ISN[i],Des_ISN[i],'CYS',T1_ISN[i],T2_ISN[i]]
Volume_Capacity=(Volume_Capacity[b]*BOXNeeded_CYS[i,b])
;
create data CASUSER.SolutionDataCFS
(where=(VolShare>0)) from [ISN=i BoxType=b T2=w]={i in ISN, b in BOX, w in T2: BOXNeeded_CFS[b,w] > 0.5}
MOL='CFS'
Org=Org_ISN[i]
Des=Des_ISN[i]
T1=T1_ISN[i]
ShipmentVolume=Volume_ISN[i]
Proportion=Proportion_CFS[b,w]
VolumeInsideBox=VolumeInsideBox_CFS[b,w]
Weight=Weight_ISN[i]
BoxNeeded=(volShareCFS[i,w]*BOXNeeded_CFS[b,w])
Vol_InsideBox=Volume_ISN[i]
VolShare=volShareCFS[i,w]
BoxBasedCost=(volShareCFS[i,w]*PerBox_Based_Rate_CFS[b,w]*BOXNeeded_CFS[b,w])
VolBasedCost=VolBasedCost_CFS[b,w]
ShipmentBasedCost=PerShp_Based_Rate[Org_ISN[i],Des_ISN[i],'CFS',T1_ISN[i],T2_ISN[i]]
Volume_Capacity=(Volume_Capacity[b]*BOXNeeded_CFS[b,w]);
quit;
... View more