### SHIPPING SETS AND PARAMETERS ### set whse 'warehouses'; # Locations from which demand is satisfied set dctr 'distribution centers' within whse; # Locations from which product may be shipped param sc 'shipping cost' {dctr,whse} >= 0; # Shipping costs, to whse from dctr, in $ / 100 lb param huge 'largest shipping cost' > 0; # Largest cost allowed for a usable shipping route param msr 'minimum size restriction' {dctr,whse} logical; # True indicates a minimum-size restriction on # direct shipments using this dctr --> whse route param dsr 'direct shipment requirement' {dctr} >= 0; # Minimum total demand, in pallets, needed to # allow shipment on routes subject to the # minimum size restriction ### PLANT SETS AND PARAMETERS ### set fact 'factories' within dctr; # Locations where product is manufactured param rtmin 'regular-time total minimum' >= 0; # Lower limit on (average) total regular-time # crews employed at all factories param rtmax 'regular-time total maximum' >= rtmin; # Upper limit on (average) total regular-time # crews employed at all factories param otmin 'overtime total minimum' >= 0; # Lower limit on total overtime hours at all factories param otmax 'overtime total maximum' >= otmin; # Upper limit on total overtime hours at all factories param rmin 'regular-time minimums' {fact} >= 0; # Lower limits on (average) regular-time crews param rmax 'regular-time maximums' {f in fact} >= rmin[f]; # Upper limits on (average) regular-time crews param omin 'overtime minimums' {fact} >= 0; # Lower limits on overtime hours param omax 'overtime maximums' {f in fact} >= omin[f]; # Upper limits on overtime hours param hd 'hours per day' {fact} >= 0; # Regular-time hours per working day param dp 'days in period' {fact} > 0; # Working days in the current planning period ### PRODUCT SETS AND PARAMETERS ### set prod 'products'; # Elements of the product group param wt 'weight' {prod} > 0; # Weight in 100 lb / 1000 cases param cpp 'cases per pallet' {prod} > 0; # Cases of product per shipping pallet param tc 'transshipment cost' {prod} >= 0; # Transshipment cost in $ / 1000 cases param pt 'production time' {prod,fact} >= 0; # Crew-hours to produce 1000 cases param rpc 'regular-time production cost' {prod,fact} >= 0; # Cost of production on regular time, # in $ / 1000 cases param opc 'overtime production cost' {prod,fact} >= 0; # Cost of production on overtime, in $ / 1000 cases ### DEMAND SETS AND PARAMETERS ### param dt 'total demand' {prod} >= 0; # Total demands for products, in 1000s param ds 'demand shares' {prod,whse} >= 0.0, <= 1.0; # Historical demand data, from which each # warehouse's share of total demand is deduced param dstot {p in prod} := sum {w in whse} ds[p,w]; # Total of demand shares; should be 1, but often isn't param dem 'demand' {p in prod, w in whse} := dt[p] * ds[p,w] / dstot[p]; # Projected demands to be satisfied, in 1000s set rt 'shipping routes available' := {d in dctr, w in whse: d <> w and sc[d,w] < huge and (w in dctr or sum {p in prod} dem[p,w] > 0) and not (msr[d,w] and sum {p in prod} 1000*dem[p,w]/cpp[p] < dsr[d]) }; # List of ordered pairs that represent routes # on which shipments are allowed ### OBJECTIVE ### minimize cost; # Total cost: regular production, overtime # production, shipping, and transshipment ### NODES ### node RT: rtmin <= net_out <= rtmax; # Source of all regular-time crews allocated node OT: otmin <= net_out <= otmax; # Source of all overtime hours allocated node P_RT {fact}; # Sources of regular-time crews at factories node P_OT {fact}; # Sources of overtime hours at factories node M {prod,fact}; # Sources of manufacturing: # send to factory's W node for local demand; # send to factory's D node for distribution node D {prod,dctr}; # Sources of distribution: # receive transshipped goods from center's W node; # receive manufactured goods from center's M node; # send to W nodes elsewhere node W {p in prod, w in whse}: net_in = dem[p,w]; # Locations of warehousing: # receive from D nodes and local M node (if any), # to satisfy local demand; # send to local D node (if any) for transshipment ### ARCS ### arc Work_RT {f in fact} from RT to P_RT[f] >= rmin[f], <= rmax[f]; # Regular-time crews allocated to each factory arc Work_OT {f in fact} from OT to P_OT[f] >= omin[f], <= omax[f]; # Overtime hours allocated to each factory arc Manu_RT {p in prod, f in fact: rpc[p,f] <> 0} >= 0 from P_RT[f] to M[p,f] (dp[f] * hd[f] / pt[p,f]) obj cost (rpc[p,f] * dp[f] * hd[f] / pt[p,f]); # Regular-time crews allocated to # manufacture of each product at each factory arc Manu_OT {p in prod, f in fact: opc[p,f] <> 0} >= 0 from P_OT[f] to M[p,f] (1 / pt[p,f]) obj cost (opc[p,f] / pt[p,f]); # Overtime hours allocated to # manufacture of each product at each factory arc Prod_L {p in prod, f in fact} >= 0 from M[p,f] to W[p,f]; # Manufacture of each product at each factory # to satisfy local demand, in 1000s of units arc Prod_D {p in prod, f in fact} >= 0 from M[p,f] to D[p,f]; # Manufacture of each product at each factory, # for distribution elsewhere, in 1000s of units arc Ship {p in prod, (d,w) in rt} >= 0 from D[p,d] to W[p,w] obj cost (sc[d,w] * wt[p]); # Shipments of each product on each allowed route arc Trans {p in prod, d in dctr} >= 0 from W[p,d] to D[p,d] obj cost (tc[p]); # Transshipments of each product at each # distribution center