Hi Rob. I was able to get one issue resolved. I am able to see both weeks (W1 and W2) in my output. But there is only calculation of PerBox costs and PerVol and PerShipment yet. That is one thing. But the most important thing is to make sure that the constraints are good according to logic and the model is working as per that. Especially, the CFS logic, where the consolidated weight and volume will be the sum of volumes and weight of all the ISNs that does not go via CYS way. For this consolidated weight and volume at the end of the week going via CFS, we need to figure out the asset mix, not for the indiviudal ISNs. To that extent, should we have another set of decision variables for CFS? Right now it is at the ISN level like below. var BoxesNeeded {ISN,BOX,MOL,T1,T2} >= 0 integer; var Proportion {ISN,BOX,MOL,T1,T2} >= 0 <= 1; But for CFS , it shd be consolidated at weekly level for all the remaining ISNs. Not sure how do we do it. Separate decision variables and wt and volume constraints for CFS and CY? I just tried it in the below code to separate CFS and CY decision variables but I am not sure If I am on the right path. I did not run the model as well. I have attached the new Unique_T2, where I bring in the weekly volume and weight to be used for CFS Constraints. I was just writing the constraints and testing. The CFS constraints especially, I am not sure if it is right. If we can formulate the model correctly and run it, that would be awesome. Create data step for output is the last piece. Thanks for your patience and appreciate your support. Thanks. 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} init 0;
num Weight_ISN {ISN} init 0;
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;
num T2_Volume{T2} init 0;
read data CASUSER.Unique_T2 into [T2] T2_Volume=T2_Volume;
num T2_Weight{T2} init 0;
read data CASUSER.Unique_T2 into [T2] T2_Weight=T2_Weight;
NUM BigM;
READ DATA CASUSER.BigM INTO BigM=Volume;
/*Read ISN Wt and Volume for a given ISN* - END*/
/*Read Wt and Volume Capacity for a given ORG, DES, BOX - START */
num Volume_Capacity {ORG,DES,BOX,MOL,T1,T2} init 0; 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]
Volume_Capacity=Volume_Capacity
Weight_Capacity=Weight_Capacity
Volume_Min=Volume_Min
Weight_Min=Weight_Min;
/*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 and Associated Impvars - START */
var BoxesNeeded_CYS {ISN,BOX,MOL,T1,T2} >= 0 integer;
var Proportion_CYS {ISN,BOX,MOL,T1,T2} >= 0 <= 1;
var BoxesNeeded_CFS {BOX,MOL,T2} >= 0 integer;
var Proportion_CFS {BOX,MOL,T2} >= 0 <= 1;
impvar VolumeInsideBox_CYS {i in ISN, b in BOX,m in {'CYS'},d in T1,w in T2} = Volume_ISN[i] * Proportion_CYS[i,b,m,d,w];
impvar WeightInsideBox_CYS {i in ISN, b in BOX,m in {'CYS'},d in T1,w in T2} = Weight_ISN[i] * Proportion_CYS[i,b,m,d,w];
impvar VolumeInsideBox_CFS {b in BOX,m in {'CFS'},w in T2} = sum {i in ISN} Volume_ISN[i] * Proportion_CFS[b,m,w];
impvar WeightInsideBox_CFS {b in BOX,m in {'CFS'},w in T2} = sum {i in ISN} Weight_ISN[i] * Proportion_CFS[b,m,w];
var Is_ISN_MOL {ISN,MOL} binary;
var Is_MOL {MOL} binary;
/* Decision Variable and Associated Impvars - END */
/*Define Rates and Implicit Variables - 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 = sum {i in ISN, b in BOX,m in MOL,d in T1,w in T2: <Org_ISN[i],Des_ISN[i],b,m,d,w> in PerBox_Based_Rate_NoZeroes}
PerBox_Based_Rate[Org_ISN[i],Des_ISN[i],b,m,d,w] * BoxesNeeded_CYS[i,b,m,d,w];
impvar PerBox_Based_Costs_CFS = sum {i in ISN, b in BOX,m in MOL,d in T1,w in T2: <Org_ISN[i],Des_ISN[i],b,m,d,w> in PerBox_Based_Rate_NoZeroes}
PerBox_Based_Rate[Org_ISN[i],Des_ISN[i],b,m,d,w] * BoxesNeeded_CFS[b,m,w];
set <str,str,str,str,str,str> PerVol_Based_Rate_NoZeroes;
num PerVol_Based_Rate {PerVol_Based_Rate_NoZeroes};
read data CASUSER.BOXRATE
(where=(RateBasis="PerVolUOM" and Ratetype='Carrier_BOL' and Rate>0))
into PerVol_Based_Rate_NoZeroes=[ORG DES MOL BOX T1 T2] PerVol_Based_Rate=Rate;
impvar PerVol_Based_Costs_CYS = sum {i in ISN, b in BOX, m in MOL,d in T1,w in T2: <Org_ISN[i],Des_ISN[i],b,m,d,w> in PerVol_Based_Rate_NoZeroes}
PerVol_Based_Rate[Org_ISN[i],Des_ISN[i],b,m,d,w] * VolumeInsideBox_CYS[i,b,m,d,w];
impvar PerVol_Based_Costs_CFS = sum {i in ISN, b in BOX, m in MOL,d in T1,w in T2: <Org_ISN[i],Des_ISN[i],b,m,d,w> in PerVol_Based_Rate_NoZeroes}
PerVol_Based_Rate[Org_ISN[i],Des_ISN[i],b,m,d,w] * VolumeInsideBox_CFS[b,m,w];
set <str,str,str,str,str,str> PerShp_Based_Rate_NoZeroes_Entry;
num PerShp_Based_Rate_Entry {PerShp_Based_Rate_NoZeroes_Entry};
read data CASUSER.BOXRATE
(where=(RateBasis="PerShipment" and Ratetype='Export_Declaration' and Rate>0))
into PerShp_Based_Rate_NoZeroes_Entry=[ORG DES MOL BOX T1 T2] PerShp_Based_Rate_Entry=Rate;
impvar PerShp_Based_Costs_Entry= sum {i in ISN, b in BOX, m in MOL,d in T1,w in T2: <Org_ISN[i],Des_ISN[i],b,m,d,w> in PerShp_Based_Rate_NoZeroes_Entry}
PerShp_Based_Rate_Entry[Org_ISN[i],Des_ISN[i],b,m,d,w];
/*Define Implicit Variables - END */
Min TotalCost =
PerBox_Based_Costs_CYS + PerVol_Based_Costs_CYS +
PerBox_Based_Costs_CFS + PerVol_Based_Costs_CFS +
PerShp_Based_Costs_Entry;
/*General Constraints */
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 InEqualOut_Volume:
sum {i in ISN, b in BOX, m in MOL, d in T1, w in T2} VolumeInsideBox_CYS[i,b,'CYS',T1_ISN[i],T2_ISN[i]] +
sum {i in ISN, b in BOX, m in MOL, w in T2} VolumeInsideBox_CFS[b,'CFS',T2_ISN[i]] =
sum {i in ISN, m in MOL}Volume_ISN[i]*Is_ISN_MOL[i,m];
con InEqualOut_Weight:
sum {i in ISN, b in BOX, m in MOL, d in T1, w in T2} WeightInsideBox_CYS[i,b,'CYS',T1_ISN[i],T2_ISN[i]] +
sum {i in ISN, b in BOX, m in MOL, w in T2} WeightInsideBox_CFS[b,'CFS',T2_ISN[i]] =
sum {i in ISN, m in MOL}Weight_ISN[i]*Is_ISN_MOL[i,m];
/*End of General Constraints */
/*CYS Specific Constraints */
for {i in ISN, b in BOX,m in MOL,d in T1,w in T2: Is_BoxAvalable_for_a_lane[Org_ISN[i],Des_ISN[i],b,m,d,w] = 0}
fix BoxesNeeded_CYS[i,b,m,d,w] = 0;
con SumProportion_ToOne_CYS {i in ISN}:
sum {b in BOX,m in {'CYS'},d in T1,w in T2} Proportion_CYS[i,b,'CYS',d,w] = 1;
con Volume_Constraint_CYS {i in ISN, b in BOX, m in {'CYS'}}:
Volume_Capacity[Org_ISN[i],Des_ISN[i],b,m,T1_ISN[i],T2_ISN[i]] * BoxesNeeded_CYS[i,b,m,T1_ISN[i],T2_ISN[i]] >= VolumeInsideBox_CYS[i,b,m,T1_ISN[i],T2_ISN[i]];
con Volume_Constraint_MinThresh_CYS {i in ISN, b in BOX, m in {'CYS'}}:
Volume_Min[Org_ISN[i],Des_ISN[i],b,m,T1_ISN[i],T2_ISN[i]] * BoxesNeeded_CYS[i,b,m,T1_ISN[i],T2_ISN[i]] <= VolumeInsideBox_CYS[i,b,m,T1_ISN[i],T2_ISN[i]];
con Weight_Constraint_CYS {i in ISN, b in BOX, m in {'CYS'}}:
Weight_Capacity[Org_ISN[i],Des_ISN[i],b,m,T1_ISN[i],T2_ISN[i]] * BoxesNeeded_CYS[i,b,m,T1_ISN[i],T2_ISN[i]] >= WeightInsideBox_CYS[i,b,m,T1_ISN[i],T2_ISN[i]];
con Weight_Constraint_MinThresh_CYS {i in ISN, b in BOX, m in {'CYS'}}:
Weight_Min[Org_ISN[i],Des_ISN[i],b,m,T1_ISN[i],T2_ISN[i]] * BoxesNeeded_CYS[i,b,m,T1_ISN[i],T2_ISN[i]] <= WeightInsideBox_CYS[i,b,m,T1_ISN[i],T2_ISN[i]];
con CYSSpecific_Volume {i in ISN,m in {'CYS'}}:
sum{b in BOX} VolumeInsideBox_CYS[i,b,m,T1_ISN[i],T2_ISN[i]]=Volume_ISN[i]*Is_ISN_MOL[i,'CYS'];
con CYSSpecific_Weight {i in ISN,m in {'CYS'}}:
sum{b in BOX} WeightInsideBox_CYS[i,b,m,T1_ISN[i],T2_ISN[i]]=Weight_ISN[i]*Is_ISN_MOL[i,'CYS'];
/* End of CYS Specific Constraints*/
/* CFS Specific Constraints*/
for {i in ISN, b in BOX,m in MOL,d in T1,w in T2: Is_BoxAvalable_for_a_lane[Org_ISN[i],Des_ISN[i],b,m,d,w] = 0}
fix BoxesNeeded_CFS[b,m,w] = 0;
con SumProportion_ToOne_CFS {w in T2}:
sum {b in BOX, m in {'CFS'}} Proportion_CFS[b,'CFS',w] = 1;
con Volume_Constraint_CFS {b in BOX, m in {'CFS'},w in T2}:
sum {i in ISN} Volume_Capacity[Org_ISN[i],Des_ISN[i],b,'CFS',T1_ISN[i],T2_ISN[i]] *
BoxesNeeded_CFS[b,'CFS',w] >= VolumeInsideBox_CFS[b,'CFS',w];
con Weight_Constraint_CFS {b in BOX, m in {'CFS'},w in T2}:
sum {i in ISN} Weight_Capacity[Org_ISN[i],Des_ISN[i],b,'CFS',T1_ISN[i],T2_ISN[i]] *
BoxesNeeded_CFS[b,'CFS',w] >= WeightInsideBox_CFS[b,'CFS',w];
con Volume_Constraint_MinThresh_CFS {b in BOX, m in {'CFS'},w in T2}:
sum{i in ISN }Volume_Min[Org_ISN[i],Des_ISN[i],b,'CFS',T1_ISN[i],T2_ISN[i]] * BoxesNeeded_CFS[b,'CFS',w] <= VolumeInsideBox_CFS[b,'CFS',w];
con Weight_Constraint_MinThresh_CFS {b in BOX, m in {'CFS'},w in T2}:
sum{i in ISN }Weight_Min[Org_ISN[i],Des_ISN[i],b,'CFS',T1_ISN[i],T2_ISN[i]] * BoxesNeeded_CFS[b,'CFS',w] <= WeightInsideBox_CFS[b,'CFS',w];
con CFSSpecific_Volume {w in T2, m in {'CFS'}}:
sum{b in BOX} VolumeInsideBox_CFS[b,'CFS',w]<=T2_Volume[w]*Is_MOL['CFS'];
con CFSSpecific_Weight {w in T2, m in {'CFS'}}:
sum{b in BOX} WeightInsideBox_CFS[b,'CFS',w]<=T2_Weight[w]*Is_MOL['CFS'];
solve with milp;
print Is_ISN_MOL;
create data OptMix_RESULTS_Vol(where=(Proportion_CYS > 0)) from
[ISN=i BOX=b MOL=m T1=d T2=w]={i in ISN, b in BOX,m in MOL,d in T1,w in T2: <Org_ISN[i],Des_ISN[i],b,m,d,w> in PerBox_Based_Rate_NoZeroes}
Org=ORG_ISN[i]
Des=DES_ISN[i]
CustomerName='xx'
ScenarioName='v'
ShipmentVolume=Volume_ISN[i]
ShipmentWeight=Weight_ISN[i]
BoxesNeeded
Volume_Capacity[Org_ISN[i],Des_ISN[i],b,m,d,w]
Weight_Capacity[Org_ISN[i],Des_ISN[i],b,m,d,w]
VolumeThresholdMinimum=Volume_Min[Org_ISN[i],Des_ISN[i],b,m,d,w]
WeightThresholdMinimum=Weight_Min[Org_ISN[i],Des_ISN[i],b,m,d,w]
Costs=(PerVol_Based_Rate[Org_ISN[i],Des_ISN[i],b,m,d,w]* VolumeInsideBox_CYS[i,b,m,d,w])
DimsType='Vol'
Proportion_CYS=Proportion_CYS[i,b,m,d,w]
VolumeInsideBox_CYS
WeightInsideBox_CYS
;
create data OptMix_RESULTS_Box(where=(Proportion_CYS > 0)) from
[ISN=i BOX=b MOL=m T1=d T2=w]={i in ISN, b in BOX,m in MOL,d in T1,w in T2: <Org_ISN[i],Des_ISN[i],b,m,d,w> in PerBox_Based_Rate_NoZeroes}
Org=ORG_ISN[i]
Des=DES_ISN[i]
CustomerName='xx'
ScenarioName='v'
ShipmentVolume=Volume_ISN[i]
ShipmentWeight=Weight_ISN[i]
BoxesNeeded
Volume_Capacity[Org_ISN[i],Des_ISN[i],b,m,d,w]
Weight_Capacity[Org_ISN[i],Des_ISN[i],b,m,d,w]
VolumeThresholdMinimum=Volume_Min[Org_ISN[i],Des_ISN[i],b,m,d,w]
WeightThresholdMinimum=Weight_Min[Org_ISN[i],Des_ISN[i],b,m,d,w]
Costs=(PerBox_Based_Rate[Org_ISN[i],Des_ISN[i],b,m,d,w]* BoxesNeeded[i,b,m,d,w])
DimsType='Box'
Proportion_CYS=Proportion_CYS[i,b,m,d,w]
VolumeInsideBox_CYS
WeightInsideBox_CYS
;
create data OptMix_RESULTS_Shipment(where=(Proportion_CYS > 0)) from
[ISN=i BOX=b MOL=m T1=d T2=w]={i in ISN, b in BOX, m in MOL,d in T1,w in T2: <Org_ISN[i],Des_ISN[i],b,m,d,w> in PerShp_Based_Rate_NoZeroes_Entry}
Org=ORG_ISN[i]
Des=DES_ISN[i]
CustomerName='xx'
ScenarioName='v'
ShipmentVolume=Volume_ISN[i]
ShipmentWeight=Weight_ISN[i]
BoxesNeeded
Volume_Capacity[Org_ISN[i],Des_ISN[i],b,m,d,w]
Weight_Capacity[Org_ISN[i],Des_ISN[i],b,m,d,w]
VolumeThresholdMinimum=Volume_Min[Org_ISN[i],Des_ISN[i],b,m,d,w]
WeightThresholdMinimum=Weight_Min[Org_ISN[i],Des_ISN[i],b,m,d,w]
Costs=(PerShp_Based_Rate_Entry[Org_ISN[i],Des_ISN[i],b,m,d,w])
DimsType='SHP'
Proportion_CYS=Proportion_CYS[i,b,m,d,w]
VolumeInsideBox_CYS
WeightInsideBox_CYS
;
... View more