1 # PROD, a multiperiod production model
4 # Robert Fourer, David M. Gay and Brian W. Kernighan, "A Modeling Language
5 # for Mathematical Programming." Management Science 36 (1990) 519-554.
7 ### PRODUCTION SETS AND PARAMETERS ###
9 set prd 'products'; # Members of the product group
11 param pt 'production time' {prd} > 0;
13 # Crew-hours to produce 1000 units
15 param pc 'production cost' {prd} > 0;
17 # Nominal production cost per 1000, used
18 # to compute inventory and shortage costs
20 ### TIME PERIOD SETS AND PARAMETERS ###
22 param first > 0 integer;
23 # Index of first production period to be modeled
25 param last > first integer;
27 # Index of last production period to be modeled
29 set time 'planning horizon' := first..last;
31 ### EMPLOYMENT PARAMETERS ###
33 param cs 'crew size' > 0 integer;
37 param sl 'shift length' > 0;
39 # Regular-time hours per shift
41 param rtr 'regular time rate' > 0;
43 # Wage per hour for regular-time labor
45 param otr 'overtime rate' > rtr;
47 # Wage per hour for overtime labor
49 param iw 'initial workforce' >= 0 integer;
51 # Crews employed at start of first period
53 param dpp 'days per period' {time} > 0;
55 # Regular working days in a production period
57 param ol 'overtime limit' {time} >= 0;
59 # Maximum crew-hours of overtime in a period
61 param cmin 'crew minimum' {time} >= 0;
63 # Lower limit on average employment in a period
65 param cmax 'crew maximum' {t in time} >= cmin[t];
67 # Upper limit on average employment in a period
69 param hc 'hiring cost' {time} >= 0;
71 # Penalty cost of hiring a crew
73 param lc 'layoff cost' {time} >= 0;
75 # Penalty cost of laying off a crew
77 ### DEMAND PARAMETERS ###
79 param dem 'demand' {prd,first..last+1} >= 0;
81 # Requirements (in 1000s)
82 # to be met from current production and inventory
84 param pro 'promoted' {prd,first..last+1} logical;
86 # true if product will be the subject
87 # of a special promotion in the period
89 ### INVENTORY AND SHORTAGE PARAMETERS ###
91 param rir 'regular inventory ratio' >= 0;
93 # Proportion of non-promoted demand
94 # that must be in inventory the previous period
96 param pir 'promotional inventory ratio' >= 0;
98 # Proportion of promoted demand
99 # that must be in inventory the previous period
101 param life 'inventory lifetime' > 0 integer;
103 # Upper limit on number of periods that
104 # any product may sit in inventory
106 param cri 'inventory cost ratio' {prd} > 0;
108 # Inventory cost per 1000 units is
109 # cri times nominal production cost
111 param crs 'shortage cost ratio' {prd} > 0;
113 # Shortage cost per 1000 units is
114 # crs times nominal production cost
116 param iinv 'initial inventory' {prd} >= 0;
118 # Inventory at start of first period; age unknown
120 param iil 'initial inventory left' {p in prd, t in time}
121 := iinv[p] less sum {v in first..t} dem[p,v];
123 # Initial inventory still available for allocation
126 param minv 'minimum inventory' {p in prd, t in time}
127 := dem[p,t+1] * (if pro[p,t+1] then pir else rir);
129 # Lower limit on inventory at end of period t
133 var Crews{first-1..last} >= 0;
135 # Average number of crews employed in each period
137 var Hire{time} >= 0; # Crews hired from previous to current period
139 var Layoff{time} >= 0; # Crews laid off from previous to current period
141 var Rprd 'regular production' {prd,time} >= 0;
143 # Production using regular-time labor, in 1000s
145 var Oprd 'overtime production' {prd,time} >= 0;
147 # Production using overtime labor, in 1000s
149 var Inv 'inventory' {prd,time,1..life} >= 0;
151 # Inv[p,t,a] is the amount of product p that is
152 # a periods old -- produced in period (t+1)-a --
153 # and still in storage at the end of period t
155 var Short 'shortage' {prd,time} >= 0;
157 # Accumulated unsatisfied demand at the end of period t
163 sum {t in time} rtr * sl * dpp[t] * cs * Crews[t] +
164 sum {t in time} hc[t] * Hire[t] +
165 sum {t in time} lc[t] * Layoff[t] +
166 sum {t in time, p in prd} otr * cs * pt[p] * Oprd[p,t] +
167 sum {t in time, p in prd, a in 1..life} cri[p] * pc[p] * Inv[p,t,a] +
168 sum {t in time, p in prd} crs[p] * pc[p] * Short[p,t];
170 # Full regular wages for all crews employed, plus
171 # penalties for hiring and layoffs, plus
172 # wages for any overtime worked, plus
173 # inventory and shortage costs
175 # (All other production costs are assumed
176 # to depend on initial inventory and on demands,
177 # and so are not included explicitly.)
181 rlim 'regular-time limit' {t in time}:
183 sum {p in prd} pt[p] * Rprd[p,t] <= sl * dpp[t] * Crews[t];
185 # Hours needed to accomplish all regular-time
186 # production in a period must not exceed
187 # hours available on all shifts
189 olim 'overtime limit' {t in time}:
191 sum {p in prd} pt[p] * Oprd[p,t] <= ol[t];
193 # Hours needed to accomplish all overtime
194 # production in a period must not exceed
195 # the specified overtime limit
197 empl0 'initial crew level': Crews[first-1] = iw;
199 # Use given initial workforce
201 empl 'crew levels' {t in time}: Crews[t] = Crews[t-1] + Hire[t] - Layoff[t];
203 # Workforce changes by hiring or layoffs
205 emplbnd 'crew limits' {t in time}: cmin[t] <= Crews[t] <= cmax[t];
207 # Workforce must remain within specified bounds
209 dreq1 'first demand requirement' {p in prd}:
211 Rprd[p,first] + Oprd[p,first] + Short[p,first]
212 - Inv[p,first,1] = dem[p,first] less iinv[p];
214 dreq 'demand requirements' {p in prd, t in first+1..last}:
216 Rprd[p,t] + Oprd[p,t] + Short[p,t] - Short[p,t-1]
217 + sum {a in 1..life} (Inv[p,t-1,a] - Inv[p,t,a])
218 = dem[p,t] less iil[p,t-1];
220 # Production plus increase in shortage plus
221 # decrease in inventory must equal demand
223 ireq 'inventory requirements' {p in prd, t in time}:
225 sum {a in 1..life} Inv[p,t,a] + iil[p,t] >= minv[p,t];
227 # Inventory in storage at end of period t
228 # must meet specified minimum
230 izero 'impossible inventories' {p in prd, v in 1..life-1, a in v+1..life}:
232 Inv[p,first+v-1,a] = 0;
234 # In the vth period (starting from first)
235 # no inventory may be more than v periods old
236 # (initial inventories are handled separately)
238 ilim1 'new-inventory limits' {p in prd, t in time}:
240 Inv[p,t,1] <= Rprd[p,t] + Oprd[p,t];
242 # New inventory cannot exceed
243 # production in the most recent period
245 ilim 'inventory limits' {p in prd, t in first+1..last, a in 2..life}:
247 Inv[p,t,a] <= Inv[p,t-1,a-1];
249 # Inventory left from period (t+1)-p
250 # can only decrease as time goes on
256 set prd := 18REG 24REG 24PRO ;
271 param : pt pc cri crs iinv :=
273 18REG 1.194 2304. 0.015 1.100 82.0
274 24REG 1.509 2920. 0.015 1.100 792.2
275 24PRO 1.509 2910. 0.015 1.100 0.0 ;
277 param : dpp ol cmin cmax hc lc :=
279 1 19.5 96.0 0.0 8.0 7500 7500
280 2 19.0 96.0 0.0 8.0 7500 7500
281 3 20.0 96.0 0.0 8.0 7500 7500
282 4 19.0 96.0 0.0 8.0 7500 7500
283 5 19.5 96.0 0.0 8.0 15000 15000
284 6 19.0 96.0 0.0 8.0 15000 15000
285 7 19.0 96.0 0.0 8.0 15000 15000
286 8 20.0 96.0 0.0 8.0 15000 15000
287 9 19.0 96.0 0.0 8.0 15000 15000
288 10 20.0 96.0 0.0 8.0 15000 15000
289 11 20.0 96.0 0.0 8.0 7500 7500
290 12 18.0 96.0 0.0 8.0 7500 7500
291 13 18.0 96.0 0.0 8.0 7500 7500 ;
306 10 470.0 118.0 1102.0