Hi Rob
I am trying to solve this problem. I have used sparse modeling approach based on your recommendation an year ago to reduce the number of variables. Basically I have like 20 ports from which goods are produced. 608 final destinations. In between these ports and DC are ICs that are 15 in number. There is a production cost that is indexed over ports. There is an outbound cost that is indexed over IC and DC. I am trying to solve for minimizing the total cost = production + outbound, thereby picking which ICs it should flow. I have some constraints as to how much quantity can be produced at each port. and how much flow in terms of Kgs and Units can traverse via IC. Specifically, i have a constraint saying, the total Kgs and Units flowing via any IC with O suffix(indicates ocean) can be only x% of total kgs and wt. Similarly for FTL, LTL and Parcel there is a cut off. eg. Parcel is any shipment (a shipment is defined as a flow from Ports to IC to DC) shd not be more than 75 kgs. this seems to be working fine. FTL it needs to be atleast 3K kgs and LTL shd be between 75 and 3K Kgs. Another thing that I should tell is that there is a binary variable called LogicalValue that is indexed over Ports, IC and DC. There are like 20x15x608= 182,400 combinations out of which, almost 97% of that is 0. I have only 5,514 out of 182,400 values of that variable that are really valid for consideration. I have created a set as below to reduce
set PortstoICtoDC_SET = {p in Ports, c in IC, d in DC: LogicalValue[p,c,d] > 0};
I have my code along with. The IC is structured in a way that the last letter of it tells the actual mode (A for air, P for parcel, F for Fulltruckload, L for Lessthantruckload and O for Ocean. The model seems to be solving. My questions are (a) I am not sure why the model does not pick any FTL or LTL mode for any lane. It chooses ocean, air and parcel. As an experiment, I tried to close out Air so that the model can play between FTL, LTL , Ocean and Parcel. The model becomes infeasible. So I am not sure if I am doing something wrong about it here. (b) Am i missing/ overlooking something in the code apart from this? (c) Lastly, in the create data step, can i cull out the last digit from IC to get the Unique mode. I tried to do right and substring but it did not work. appreciate your help.
proc optmodel;
set<str> DC; /* this is a set of DCs*/
set<str> Ports;
set IC={'BUD_A','BUD_O','BUD_F','BUD_L','BUD_P','MTY_A','MTY_O','MTY_F','MTY_L','MTY_P','HKG_A','HKG_O','HKG_F','HKG_L','HKG_P'};
set UniqueMode={'A','O','F','L','P'};
/*read data into the DC*/
read data STDOPT.PN11299_Destcode into DC=[dest_code];
read data STDOPT.PN11299_Origincode into Ports=[Origin_Code];
num Units {DC};
num Kgs {DC};
NUM BigMKgs;
NUM BigMUnits;
read data STDOPT.PN11299_BigM into BigMKgs=Kgs;
read data STDOPT.PN11299_BigM into BigMUnits=Units;
read data STDOPT.PN11299 into [dest_code] Units=Units;
read data STDOPT.PN11299 into [dest_code] Kgs=Kgs;
/* declare Constants*/
num MinQty_IC=0;
num MinKgs_IC=0;
num Max_Per_at_IC_Ocean=0.1;
num FTL_Max = 3000;
num MTY_SY_MaxQty=5000000;
num BUD_SY_MaxQty=5000000;
num HKG_SY_MaxQty=5000000;
num MTY_RA_MaxQty=5000000;
num BUD_RA_MaxQty=5000000;
num HKG_RA_MaxQty=5000000;
var Build {IC} binary;
var BuildUniqueMode{UniqueMode} binary;
/*Declaring an Array of Costs - THIS IS INPUT data */
num Production_Cost {Ports};
read data STDOPT.PN11299_PRODUCTION_COST into [Origin_Code] Production_Cost=Inbound_Rate;
num OutboundLinehaul {IC,DC}; /*This is an array of OutboundLinehaul Costs indexed over IC and DC*/
/*read data into the OutboundLinehaul parameter*/
read data STDOPT.PN11299_RATEOUTBOUND into [mot1 Dest_Code] OutboundLinehaul=Outbound_Rate;
num LogicalValue {Ports,IC,DC}; /*This is an array of OutboundLinehaul Costs indexed over IC and DC*/
read data STDOPT.PN11299_PortsICDC into [Origin_code mot1 Dest_Code]LogicalValue=LogicalValue;
set PortstoICtoDC_SET = {p in Ports, c in IC, d in DC: LogicalValue[p,c,d] > 0};
/*set KgsfromPortstoICtoDC_SET = {p in Ports, c in IC, d in DC: LogicalValue[p,c,d] > 0};*/
/*set IsIC_SET = {c in IC: LogicalValue[c] > 0};*/
/* Declaring an Array of Decision Variables*/
var UnitsfromPortstoICtoDC {PortstoICtoDC_SET}>=0;
var KgsfromPortstoICtoDC {PortstoICtoDC_SET}>=0;
/* Binary Variables */
var IsIC {IC} binary;
var IsPortsIC {Ports,IC} binary;
var ISPortsDC {Ports,DC} binary;
var IsPortsICDC {Ports,IC,DC} binary;
/*var UnitsfromPortstoICtoDC {Ports,IC,DC}>=0;
var KgsfromPortstoICtoDC {Ports,IC,DC}>=0;*/
/*Declaring Implicit Variables*/
impvar UnitsatIC{c in IC}=sum{<p,(c),d> in PortstoICtoDC_SET} UnitsfromPortstoICtoDC [p,c,d];
/*Print UnitsatIC;*/
impvar KgsatIC{c in IC}=sum{<p,(c),d> in PortstoICtoDC_SET} KgsfromPortstoICtoDC [p,c,d];
impvar Production_Costs=sum{<p,c,d> in PortstoICtoDC_SET} Production_Cost [p] * UnitsfromPortstoICtoDC[p,c,d];
impvar Outbound_Linehaul_Costs = sum {<p,c,d> in PortstoICtoDC_SET} OutboundLinehaul [c,d] * KgsfromPortstoICtoDC [p,c,d];
/* declare Objective Function*/
Min TotalCost = Production_Costs+Outbound_Linehaul_Costs;
/* declare General Constraints for units*/
con Min_Qty_at_IC_is_Respected {c in IC}:
sum{<p,(c),d> in PortstoICtoDC_SET} UnitsfromPortstoICtoDC [p,c,d]>=MinQty_IC*IsIC[c];
/*expand Min_Qty_at_IC_is_Respected;*/
con Link_Units_Kgs {p in Ports, d in DC}:
sum{<(p),c,(d)> in PortstoICtoDC_SET} UnitsfromPortstoICtoDC [p,c,d]=Units[d]*ISPortsDC[p,d];
con UnitsFlows_from_Ports_to_DC_Modelequals_FlowFromPortstoDC_inInputData {d in DC}:
sum {<p,c,(d)> in PortstoICtoDC_SET} UnitsfromPortstoICtoDC[p, c, d] = Units[d]; /*the flow from p to d that goes through ALL ICs*/
con BigM_Units {c in IC,d in DC}: UnitsatIC[c] <= BigMUnits*IsIC[c];
con MakeSure_RightFlowsHappen_Units{<p,c,d> in PortstoICtoDC_SET}:
UnitsfromPortstoICtoDC[p,c,d] <= BigMUnits*IsPortsICDC[p,c,d]; /*All binary variables with 0 IsPortsIC will be taken care here */
/* declare General Constraints for Kgs*/
con Min_Kgs_at_IC_is_Respected {c in IC}:
sum{<p,(c),d> in PortstoICtoDC_SET} KgsfromPortstoICtoDC [p,c,d]>=MinKgs_IC*IsIC[c];
con Link_Kgs_Units {p in Ports, d in DC}:
sum{<(p),c,(d)> in PortstoICtoDC_SET} KgsfromPortstoICtoDC [p,c,d]=Kgs[d]*ISPortsDC[p,d];
con KgsFlows_from_Ports_to_DC_Modelequals_FlowFromPortstoDC_inInputData {d in DC}:
sum {<p,c,(d)> in PortstoICtoDC_SET} KgsfromPortstoICtoDC[p, c, d] =Kgs[d]; /*the flow from p to d that goes through ALL ICs*/
con BigM_Kgs {c in IC,d in DC}: KgsatIC[c] <= BigMKgs*IsIC[c];
con MakeSure_RightFlowsHappen_Kgs{<p,c,d> in PortstoICtoDC_SET}:
KgsfromPortstoICtoDC[p,c,d] <= BigMKgs* IsPortsICDC[p,c,d]; /*All binary variables with 0 IsPortsIC will be taken care here */
/* Restricting Ocean to only x% of Weight */
con OceanMaxKgs{u in {'O'},c in {'BUD_O','MTY_O','HKG_O'}, d in DC}: sum{<p,(c),(d)> in PortstoICtoDC_SET} KgsfromPortstoICtoDC [p,c,d]
<=BuildUniqueMode['O']*Kgs[d]*Max_Per_at_IC_Ocean;
/* Expand OceanMaxKgs; */
/* Restricting Ocean to only x% of Units */
con OceanMaxUnits{u in {'O'},c in {'BUD_O','MTY_O','HKG_O'},d in DC}: sum{<p,(c),(d)> in PortstoICtoDC_SET} UnitsfromPortstoICtoDC [p,c,d]
<=BuildUniqueMode['O']*Units[d]*Max_Per_at_IC_Ocean;
/* Restricting FTL to Min 3000 Kg of Weight */
con FTLMinKgs {c in {'BUD_F','MTY_F','HKG_F'}, d in DC}:
sum{<p,(c),(d)> in PortstoICtoDC_SET} KgsfromPortstoICtoDC [p,c,d]>=3001*IsIC[c];
con LTLMaxKgs {c in {'BUD_L','MTY_L','HKG_L'}, d in DC}:
sum{<p,(c),(d)> in PortstoICtoDC_SET} KgsfromPortstoICtoDC [p,c,d]<=3000*IsIC[c];
con LTLMinKgs {c in {'BUD_L','MTY_L','HKG_L'}, d in DC}:
sum{<p,(c),(d)> in PortstoICtoDC_SET} KgsfromPortstoICtoDC [p,c,d]>=75*IsIC[c];
con ParcelMaxKgs {c in {'BUD_P','MTY_P','HKG_P'}, d in DC}:
sum{<p,(c),(d)> in PortstoICtoDC_SET} KgsfromPortstoICtoDC [p,c,d]<=75*IsIC[c];
/* Restricting Production Capacities */
con ProductionMTYSY{p in ports: p in {'MTY_SY_3','MTY_SY_2'}} :
sum{<(p),c,d> in PortstoICtoDC_SET} UnitsfromPortstoICtoDC[p,c,d]<=MTY_SY_MaxQty;
con ProductionBUDSY{p in ports: p in {'BUD_SY_3','BUD_SY_2'}} :
sum{<(p),c,d> in PortstoICtoDC_SET} UnitsfromPortstoICtoDC[p,c,d]<=BUD_SY_MaxQty;
con ProductionHKGSY{p in ports: p in {'HKG_SY_3','HKG_SY_2'}} :
sum{<(p),c,d> in PortstoICtoDC_SET} UnitsfromPortstoICtoDC[p,c,d]<=HKG_SY_MaxQty;
con ProductionMTYRA{p in ports: p in {'MTY_RA_3'}} :
sum{<(p),c,d> in PortstoICtoDC_SET} UnitsfromPortstoICtoDC[p,c,d]<=MTY_RA_MaxQty;
con ProductionBUDRA{p in ports: p in {'BUD_RA_3'}} :
sum{<(p),c,d> in PortstoICtoDC_SET} UnitsfromPortstoICtoDC[p,c,d]<=BUD_RA_MaxQty;
con ProductionHKGRA{p in ports: p in {'HKG_RA_3'}} :
sum{<(p),c,d> in PortstoICtoDC_SET} UnitsfromPortstoICtoDC[p,c,d]<=HKG_RA_MaxQty;
solve with milp / allcuts=aggressive;
/*Outputs*/
create data STDOPT.PN11299_Output (where=(OhWeightChrg > 0.0000001)) from
[Ports=p IC=c DC=d]
ScenarioName='PN11299-Alt1'
OhWeightChrg=KgsfromPortstoICtoDC
Percentage = Kgs[d]
Units= Units[d]
Production_Cost = Production_Cost[p]
Production_Costs=(Production_Cost [p] * SUM(UnitsfromPortstoICtoDC[p,c,d]))
Outbound_Linehaul_Costs = (OutboundLinehaul [c,d] * sum (KgsfromPortstoICtoDC [p,c,d]))
;
It sounds to me like you want to enforce a constraint on individual variables rather than on a sum. For example, if you want to enforce that either KgsfromPortstoICtoDC[p,c,d] = 0 or KgsfromPortstoICtoDC[p,c,d] >= 75, make the following change:
*con LTLMinKgs {c in {'BUD_L','MTY_L','HKG_L'}}:
sum{<p,(c),d> in PortstoICtoDC_SET} KgsfromPortstoICtoDC[p,c,d] >= 75*IsIC[c];
con LTLMinKgs {<p,c,d> in PortstoICtoDC_SET: c in {'BUD_L','MTY_L','HKG_L'}}:
KgsfromPortstoICtoDC[p,c,d] >= 75*IsPortsICDC[p,c,d];
You already have these constraints:
con MakeSure_RightFlowsHappen_Kgs{<p,c,d> in PortstoICtoDC_SET}:
KgsfromPortstoICtoDC[p,c,d] <= BigMKgs* IsPortsICDC[p,c,d]; /*All binary variables with 0 IsPortsIC will be taken care here */
So the two possibilities are:
i have attached the sample dataset in the previous one(it is an excel attachment)
The Excel file contains only a portion of the required data. Please instead provide the SAS data sets that match your code.
Rob.
Sorry about that. Here is all the data sets that I have used in the model. It is in 7 sheets in this excel file.
Can you please let me know if this works?
Rob - I would like to add / clarify one thing that for Ocean that is (MTY_O, BUD_O,HKG_O) the total kgs that flows through the combined all three ICs together should not exceed 10% of Total Wt and 10% of Total Units. This seems to be respecting.
For other modes, specifically LTL/FTL, what I found is that the model respects the Max constraint, i.e. I want the LTL shipment to have a max of 3000 Kgs. A shipment is defined as combination of PortsICDC. This seems to be fine.
But the model does not work for Min constraint. , ie. If I want to restrict LTL shipment to have atleast 75 kgs it does not work. Same for LTL. For Parcel, i have only 75 kgs Max so that is fine, but had I had Parcel min constraint this would have not worked as well. So underlying pattern is I am doing something wrong about Min constraints that I am not sure. I am not sure if what I figured out is right but this is what I could dig further. Appreciate your support Rob.
quick update Rob: I was able to get through culling out the required elements in create data step. that part is sorted.
So the only part that remains to be take care is how to I get the model to respect the constraints that imposes a minimum Kgs for a given mode. Appreciate your support.
If you add a constraint that at least one unit of FTL or LTL must be used, even the LP relaxation is infeasible:
str mode {c in IC} = substr(c,length(c),1);
con AtLeastOneFTLorLTL:
sum{<p,c,d> in PortstoICtoDC_SET: mode[c] in /F L/} UnitsfromPortstoICtoDC[p,c,d] >= 1;
solve relaxint;
You can diagnose the infeasibility by using the IIS= option:
solve with lp relaxint / iis=1;
expand / iis;
On my machine, the resulting IIS includes the following constraints:
Constraint FTLMinKgs[BUD_F,BUE_N_CH_3]: - 3001*IsIC[BUD_F] >= 0 Constraint FTLMinKgs[MTY_F,MCI_N_CH_3]: - 3001*IsIC[MTY_F] >= 0 Constraint FTLMinKgs[HKG_F,MSY_N_SY_2]: - 3001*IsIC[HKG_F] >= 0 Constraint LTLMinKgs[BUD_L,IAH_N_OP_3]: - 75*IsIC[BUD_L] >= 0 Constraint LTLMinKgs[MTY_L,SAV_N_RA_3]: - 75*IsIC[MTY_L] >= 0 Constraint LTLMinKgs[HKG_L,SLC_N_OP_2]: - 75*IsIC[HKG_L] >= 0 |
All six of those IsIC variables must therefore be 0.
I suspect you might have meant to sum over d, as in the following changes:
* con FTLMinKgs {c in {'BUD_F','MTY_F','HKG_F'}, d in DC}:
sum{<p,(c),(d)> in PortstoICtoDC_SET} KgsfromPortstoICtoDC[p,c,d] >= 3001*IsIC[c];
con FTLMinKgs {c in {'BUD_F','MTY_F','HKG_F'}}:
sum{<p,(c),d> in PortstoICtoDC_SET} KgsfromPortstoICtoDC[p,c,d] >= 3001*IsIC[c];
* con LTLMinKgs {c in {'BUD_L','MTY_L','HKG_L'}, d in DC}:
sum{<p,(c),(d)> in PortstoICtoDC_SET} KgsfromPortstoICtoDC[p,c,d] >= 75*IsIC[c];
con LTLMinKgs {c in {'BUD_L','MTY_L','HKG_L'}}:
sum{<p,(c),d> in PortstoICtoDC_SET} KgsfromPortstoICtoDC[p,c,d] >= 75*IsIC[c];
With these changes, the solution uses both FTL and LTL, even without the AtLeastOneFTLorLTL constraint.
I recommend also reviewing your LTLMaxKgs and ParcelMaxKgs constraints in case you really wanted to sum over d.
Rob
I tried your approach of summing acorss DC. I don't think i want that except Ocean.
For all modes except ocean, I want to make sure that a given shipment (which is a combination of Ports, IC and DC) does not exceed or meet atleast the weight constraints given in the constraints.
The model picks LTL and FTL. but it does not respect the constraint that a FTL shipment should atleast be 3000 kgs or more and LTL shd be atleast 75 or more. It does respect the Max constraint but not the min constraints. Thats where I am not sure why the model is not right or how to fix it. Here is my modified code with your changes. I have also attached the data files that I have used. Just that we have 599 dest_codes instead of 608 earlier and rates, kgs and units are different by a factor across the board. Appreciate your support as always Rob. I am now confused.
proc optmodel;
set<str> DC; /* this is a set of DCs*/
set<str> Ports;
set IC={'BUD_A','BUD_O','BUD_F','BUD_L','BUD_P','MTY_A','MTY_O','MTY_F','MTY_L','MTY_P','HKG_A','HKG_O','HKG_F','HKG_L','HKG_P'};
set UniqueMode={'A','O','F','L','P'};
/*read data into the DC*/
read data STDOPT.PN11299_Destcode into DC=[dest_code];
read data STDOPT.PN11299_Origincode into Ports=[Origin_Code];
num Units {DC};
num Kgs {DC};
NUM BigMKgs;
NUM BigMUnits;
read data STDOPT.PN11299_BigM into BigMKgs=Kgs;
read data STDOPT.PN11299_BigM into BigMUnits=Units;
/*read data into the Containers parameter*/
read data STDOPT.PN11299 into [dest_code] Units=Units;
read data STDOPT.PN11299 into [dest_code] Kgs=Kgs;
/* declare Constants*/
num MinQty_IC=0;
num MinKgs_IC=0;
num Max_Per_at_IC_Ocean=0.1;
num FTL_Max = 3000;
num MTY_SY_MaxQty=796068;
num BUD_SY_MaxQty=442260;
num HKG_SY_MaxQty=1326780;
num MTY_RA_MaxQty=26536;
num BUD_RA_MaxQty=8845;
num HKG_RA_MaxQty=6634;
var Build {IC} binary;
var BuildUniqueMode{UniqueMode} binary;
/*Declaring an Array of Costs - THIS IS INPUT data */
num Production_Cost {Ports};
read data STDOPT.PN11299_PRODUCTION_COST into [Origin_Code] Production_Cost=Inbound_Rate;
print Production_Cost;
num OutboundLinehaul {IC,DC}; /*This is an array of OutboundLinehaul Costs indexed over IC and DC*/
/*read data into the OutboundLinehaul parameter*/
read data STDOPT.PN11299_RATEOUTBOUND into [mot1 Dest_Code] OutboundLinehaul=Outbound_Rate;
/*print OutboundLinehaul; */
num LogicalValue {Ports,IC,DC}; /*This is an array of OutboundLinehaul Costs indexed over IC and DC*/
read data STDOPT.PN11299_PortsICDC into [Origin_code mot1 Dest_Code]LogicalValue=LogicalValue;
set PortstoICtoDC_SET = {p in Ports, c in IC, d in DC: LogicalValue[p,c,d] > 0};
/*set KgsfromPortstoICtoDC_SET = {p in Ports, c in IC, d in DC: LogicalValue[p,c,d] > 0};*/
/*set IsIC_SET = {c in IC: LogicalValue[c] > 0};*/
/* Declaring an Array of Decision Variables*/
var UnitsfromPortstoICtoDC {PortstoICtoDC_SET}>=0;
var KgsfromPortstoICtoDC {PortstoICtoDC_SET}>=0;
/* Binary Variables */
var IsIC {IC} binary;
var IsPortsIC {Ports,IC} binary;
var ISPortsDC {Ports,DC} binary;
var IsPortsICDC {Ports,IC,DC} binary;
/*var UnitsfromPortstoICtoDC {Ports,IC,DC}>=0;
var KgsfromPortstoICtoDC {Ports,IC,DC}>=0;*/
/*for {p in Ports,c in IC,d in DC} do;
fix IsPortsICDC[p,c,d]= 0;
end;*/
/*Declaring Implicit Variables*/
impvar UnitsatIC{c in IC}=sum{<p,(c),d> in PortstoICtoDC_SET} UnitsfromPortstoICtoDC [p,c,d];
/*Print UnitsatIC;*/
impvar KgsatIC{c in IC}=sum{<p,(c),d> in PortstoICtoDC_SET} KgsfromPortstoICtoDC [p,c,d];
impvar Production_Costs=sum{<p,c,d> in PortstoICtoDC_SET} Production_Cost [p] * UnitsfromPortstoICtoDC[p,c,d];
impvar Outbound_Linehaul_Costs = sum {<p,c,d> in PortstoICtoDC_SET} OutboundLinehaul [c,d] * KgsfromPortstoICtoDC [p,c,d];
/* declare Objective Function*/
Min TotalCost = Production_Costs+Outbound_Linehaul_Costs;
/* declare General Constraints for units*/
con Min_Qty_at_IC_is_Respected {c in IC}:
sum{<p,(c),d> in PortstoICtoDC_SET} UnitsfromPortstoICtoDC [p,c,d]>=MinQty_IC*IsIC[c];
/*expand Min_Qty_at_IC_is_Respected;*/
con Link_Units_Kgs {p in Ports, d in DC}:
sum{<(p),c,(d)> in PortstoICtoDC_SET} UnitsfromPortstoICtoDC [p,c,d]=Units[d]*ISPortsDC[p,d];
con UnitsFlows_from_Ports_to_DC_Modelequals_FlowFromPortstoDC_inInputData {d in DC}:
sum {<p,c,(d)> in PortstoICtoDC_SET} UnitsfromPortstoICtoDC[p, c, d] = Units[d]; /*the flow from p to d that goes through ALL ICs*/
con BigM_Units {c in IC,d in DC}: UnitsatIC[c] <= BigMUnits*IsIC[c];
con MakeSure_RightFlowsHappen_Units{<p,c,d> in PortstoICtoDC_SET}:
UnitsfromPortstoICtoDC[p,c,d] <= BigMUnits*IsPortsICDC[p,c,d]; /*All binary variables with 0 IsPortsIC will be taken care here */
/* declare General Constraints for Kgs*/
con Min_Kgs_at_IC_is_Respected {c in IC}:
sum{<p,(c),d> in PortstoICtoDC_SET} KgsfromPortstoICtoDC [p,c,d]>=MinKgs_IC*IsIC[c];
con Link_Kgs_Units {p in Ports, d in DC}:
sum{<(p),c,(d)> in PortstoICtoDC_SET} KgsfromPortstoICtoDC [p,c,d]=Kgs[d]*ISPortsDC[p,d];
con KgsFlows_from_Ports_to_DC_Modelequals_FlowFromPortstoDC_inInputData {d in DC}:
sum {<p,c,(d)> in PortstoICtoDC_SET} KgsfromPortstoICtoDC[p, c, d] =Kgs[d]; /*the flow from p to d that goes through ALL ICs*/
con BigM_Kgs {c in IC,d in DC}: KgsatIC[c] <= BigMKgs*IsIC[c];
con MakeSure_RightFlowsHappen_Kgs{<p,c,d> in PortstoICtoDC_SET}:
KgsfromPortstoICtoDC[p,c,d] <= BigMKgs* IsPortsICDC[p,c,d]; /*All binary variables with 0 IsPortsIC will be taken care here */
/* Restricting Ocean to only x% of Weight */
con OceanMaxKgs{u in {'O'},c in {'BUD_O','MTY_O','HKG_O'}, d in DC}: sum{<p,(c),(d)> in PortstoICtoDC_SET} KgsfromPortstoICtoDC [p,c,d]
<=BuildUniqueMode['O']*Kgs[d]*Max_Per_at_IC_Ocean;
/* Expand OceanMaxKgs; */
/* Restricting Ocean to only x% of Units */
con OceanMaxUnits{u in {'O'},c in {'BUD_O','MTY_O','HKG_O'},d in DC}: sum{<p,(c),(d)> in PortstoICtoDC_SET} UnitsfromPortstoICtoDC [p,c,d]
<=BuildUniqueMode['O']*Units[d]*Max_Per_at_IC_Ocean;
/* Restricting Modes by Min and Max of Wt*/
con FTLMinKgs {c in {'BUD_F','MTY_F','HKG_F'}}:
sum{<p,(c),d> in PortstoICtoDC_SET} KgsfromPortstoICtoDC[p,c,d] <= 10001*IsIC[c];
con LTLMaxKgs {c in {'BUD_L','MTY_L','HKG_L'}}:
sum{<p,(c),d> in PortstoICtoDC_SET} KgsfromPortstoICtoDC [p,c,d]<=3000*IsIC[c];
con LTLMinKgs {c in {'BUD_L','MTY_L','HKG_L'}}:
sum{<p,(c),d> in PortstoICtoDC_SET} KgsfromPortstoICtoDC[p,c,d] >= 75*IsIC[c];
con ParcelMaxKgs {c in {'BUD_P','MTY_P','HKG_P'}}:
sum{<p,(c),d> in PortstoICtoDC_SET} KgsfromPortstoICtoDC [p,c,d]<=75*IsIC[c];
/* Restricting Production Capacities */
con ProductionMTYSY{p in ports: p in {'MTY_SY_3','MTY_SY_2'}} :
sum{<(p),c,d> in PortstoICtoDC_SET} UnitsfromPortstoICtoDC[p,c,d]<=MTY_SY_MaxQty;
con ProductionBUDSY{p in ports: p in {'BUD_SY_3','BUD_SY_2'}} :
sum{<(p),c,d> in PortstoICtoDC_SET} UnitsfromPortstoICtoDC[p,c,d]<=BUD_SY_MaxQty;
con ProductionHKGSY{p in ports: p in {'HKG_SY_3','HKG_SY_2'}} :
sum{<(p),c,d> in PortstoICtoDC_SET} UnitsfromPortstoICtoDC[p,c,d]<=HKG_SY_MaxQty;
con ProductionMTYRA{p in ports: p in {'MTY_RA_3'}} :
sum{<(p),c,d> in PortstoICtoDC_SET} UnitsfromPortstoICtoDC[p,c,d]<=MTY_RA_MaxQty;
con ProductionBUDRA{p in ports: p in {'BUD_RA_3'}} :
sum{<(p),c,d> in PortstoICtoDC_SET} UnitsfromPortstoICtoDC[p,c,d]<=BUD_RA_MaxQty;
con ProductionHKGRA{p in ports: p in {'HKG_RA_3'}} :
sum{<(p),c,d> in PortstoICtoDC_SET} UnitsfromPortstoICtoDC[p,c,d]<=HKG_RA_MaxQty;
solve with milp / allcuts=aggressive;
It sounds to me like you want to enforce a constraint on individual variables rather than on a sum. For example, if you want to enforce that either KgsfromPortstoICtoDC[p,c,d] = 0 or KgsfromPortstoICtoDC[p,c,d] >= 75, make the following change:
*con LTLMinKgs {c in {'BUD_L','MTY_L','HKG_L'}}:
sum{<p,(c),d> in PortstoICtoDC_SET} KgsfromPortstoICtoDC[p,c,d] >= 75*IsIC[c];
con LTLMinKgs {<p,c,d> in PortstoICtoDC_SET: c in {'BUD_L','MTY_L','HKG_L'}}:
KgsfromPortstoICtoDC[p,c,d] >= 75*IsPortsICDC[p,c,d];
You already have these constraints:
con MakeSure_RightFlowsHappen_Kgs{<p,c,d> in PortstoICtoDC_SET}:
KgsfromPortstoICtoDC[p,c,d] <= BigMKgs* IsPortsICDC[p,c,d]; /*All binary variables with 0 IsPortsIC will be taken care here */
So the two possibilities are:
Rob
Thank you. That is what I wanted and the model works fine now after the changes that you mentioned.
Wonderful . Thank you again always.
Are you ready for the spotlight? We're accepting content ideas for SAS Innovate 2025 to be held May 6-9 in Orlando, FL. The call is open until September 16. Read more here about why you should contribute and what is in it for you!
Learn how to run multiple linear regression models with and without interactions, presented by SAS user Alex Chaplin.
Find more tutorials on the SAS Users YouTube channel.