Rob Today, I added the filters connecting i and w, like you recommended. Model is solving but the answers are not right. I have attached a spreadsheet which has the desired solutions. This spreadsheet should make it very clear. (a) CYS: For a given i and b, the proportion shd add up to 1. We shd be able to capture the volume inside box (b) CFS: The proportion here, I changed to [i,b,w] and if you look at the spreadhseet it adds up to 1 for a given week, across all vendors and all box types. I have changed the constraints as well. I sincerely, request your support on getting this model work. I am under pressure to get this delivered Monday. Thank you as always. 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 */
/* A Binary variable that is 0 or 1 for a given asset for a given lane, 0 indicated not available, 1- available */
num Is_BoxAvalable_for_a_lane {ORG,DES,BOX,MOL,T1,T2};
read data CASUSER.BOXSpecs into [ORG Des Box Mol T1 T2] Is_BoxAvalable_for_a_lane = BoxAvailability;
/* 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 {ISN,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[i,b,w];
impvar TotalVol {m in MOL,w in T2} = sum {i in ISN} Volume_ISN[i] * Is_ISN_MOL[i,m];
/* 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: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];
impvar TotalVolBasedCost = sum {i in ISN, b in BOX} VolBasedCost_CYS[i,b] + sum{i in ISN,b in BOX, w in T2:T2_ISN[i]=w}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 {i in ISN, b in BOX, w in T2:T2_ISN[i]=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]]*Proportion_CFS[i,b,w];
impvar TotalShipmentBasedCost = sum {i in ISN, b in BOX} ShipmentBasedCost_CYS[i,b] + sum{i in ISN,b in BOX, w in T2:T2_ISN[i]=w} ShipmentBasedCost_CFS[i,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,i in ISN:T2_ISN[i]=w} Proportion_CFS[i,b,w] = 1;
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];
expand BoxConCFS;
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 TotalBoxBasedCost;
print volShareCFS VolBasedCost_CFS VolBasedCost_CYS TotalVolBasedCost TotalVol;
print ShipmentBasedCost_CYS ShipmentBasedCost_CFS TotalShipmentBasedCost;
/* 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_ISN[i]}: BOXNeeded_CFS[b,w] > 0.5}
T1=T1_ISN[i]
MOL='CFS'
Org=Org_ISN[i]
Des=Des_ISN[i]
ShipmentVolume=Volume_ISN[i]
Proportion=Proportion_CFS[i,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;
data CASUSER.SolutionData;
set CASUSER.SolutionDataCYS CASUSER.SolutionDataCFS;
Total = BoxBasedCost + VolBasedCost + ShipmentBasedCost;
Utilization = Volume/Volume_Capacity;
run;
/*proc print data=CASUSER.SolutionData;
sum _numeric_;
run;
quit;
*/
... View more