examples/prod.mod
author Alpar Juttner <alpar@cs.elte.hu>
Sun, 05 Dec 2010 17:35:23 +0100
changeset 2 4c8956a7bdf4
permissions -rw-r--r--
Set up CMAKE build environment
alpar@1
     1
# PROD, a multiperiod production model
alpar@1
     2
#
alpar@1
     3
# References:
alpar@1
     4
# Robert Fourer, David M. Gay and Brian W. Kernighan, "A Modeling Language
alpar@1
     5
# for Mathematical Programming." Management Science 36 (1990) 519-554.
alpar@1
     6
alpar@1
     7
###  PRODUCTION SETS AND PARAMETERS  ###
alpar@1
     8
alpar@1
     9
set prd 'products';    # Members of the product group
alpar@1
    10
alpar@1
    11
param pt 'production time' {prd} > 0;
alpar@1
    12
alpar@1
    13
                        # Crew-hours to produce 1000 units
alpar@1
    14
alpar@1
    15
param pc 'production cost' {prd} > 0;
alpar@1
    16
alpar@1
    17
                        # Nominal production cost per 1000, used
alpar@1
    18
                        # to compute inventory and shortage costs
alpar@1
    19
alpar@1
    20
###  TIME PERIOD SETS AND PARAMETERS  ###
alpar@1
    21
alpar@1
    22
param first > 0 integer;
alpar@1
    23
                        # Index of first production period to be modeled
alpar@1
    24
alpar@1
    25
param last > first integer;
alpar@1
    26
alpar@1
    27
                        # Index of last production period to be modeled
alpar@1
    28
alpar@1
    29
set time 'planning horizon' := first..last;
alpar@1
    30
alpar@1
    31
###  EMPLOYMENT PARAMETERS  ###
alpar@1
    32
alpar@1
    33
param cs 'crew size' > 0 integer;
alpar@1
    34
alpar@1
    35
                        # Workers per crew
alpar@1
    36
alpar@1
    37
param sl 'shift length' > 0;
alpar@1
    38
alpar@1
    39
                        # Regular-time hours per shift
alpar@1
    40
alpar@1
    41
param rtr 'regular time rate' > 0;
alpar@1
    42
alpar@1
    43
                        # Wage per hour for regular-time labor
alpar@1
    44
alpar@1
    45
param otr 'overtime rate' > rtr;
alpar@1
    46
alpar@1
    47
                        # Wage per hour for overtime labor
alpar@1
    48
alpar@1
    49
param iw 'initial workforce' >= 0 integer;
alpar@1
    50
alpar@1
    51
                        # Crews employed at start of first period
alpar@1
    52
alpar@1
    53
param dpp 'days per period' {time} > 0;
alpar@1
    54
alpar@1
    55
                        # Regular working days in a production period
alpar@1
    56
alpar@1
    57
param ol 'overtime limit' {time} >= 0;
alpar@1
    58
alpar@1
    59
                        # Maximum crew-hours of overtime in a period
alpar@1
    60
alpar@1
    61
param cmin 'crew minimum' {time} >= 0;
alpar@1
    62
alpar@1
    63
                        # Lower limit on average employment in a period
alpar@1
    64
alpar@1
    65
param cmax 'crew maximum' {t in time} >= cmin[t];
alpar@1
    66
alpar@1
    67
                        # Upper limit on average employment in a period
alpar@1
    68
alpar@1
    69
param hc 'hiring cost' {time} >= 0;
alpar@1
    70
alpar@1
    71
                        # Penalty cost of hiring a crew
alpar@1
    72
alpar@1
    73
param lc 'layoff cost' {time} >= 0;
alpar@1
    74
alpar@1
    75
                        # Penalty cost of laying off a crew
alpar@1
    76
alpar@1
    77
###  DEMAND PARAMETERS  ###
alpar@1
    78
alpar@1
    79
param dem 'demand' {prd,first..last+1} >= 0;
alpar@1
    80
alpar@1
    81
                        # Requirements (in 1000s)
alpar@1
    82
                        # to be met from current production and inventory
alpar@1
    83
alpar@1
    84
param pro 'promoted' {prd,first..last+1} logical;
alpar@1
    85
alpar@1
    86
                        # true if product will be the subject
alpar@1
    87
                        # of a special promotion in the period
alpar@1
    88
alpar@1
    89
###  INVENTORY AND SHORTAGE PARAMETERS  ###
alpar@1
    90
alpar@1
    91
param rir 'regular inventory ratio' >= 0;
alpar@1
    92
alpar@1
    93
                        # Proportion of non-promoted demand
alpar@1
    94
                        # that must be in inventory the previous period
alpar@1
    95
alpar@1
    96
param pir 'promotional inventory ratio' >= 0;
alpar@1
    97
alpar@1
    98
                        # Proportion of promoted demand
alpar@1
    99
                        # that must be in inventory the previous period
alpar@1
   100
alpar@1
   101
param life 'inventory lifetime' > 0 integer;
alpar@1
   102
alpar@1
   103
                        # Upper limit on number of periods that
alpar@1
   104
                        # any product may sit in inventory
alpar@1
   105
alpar@1
   106
param cri 'inventory cost ratio' {prd} > 0;
alpar@1
   107
alpar@1
   108
                        # Inventory cost per 1000 units is
alpar@1
   109
                        # cri times nominal production cost
alpar@1
   110
alpar@1
   111
param crs 'shortage cost ratio' {prd} > 0;
alpar@1
   112
alpar@1
   113
                        # Shortage cost per 1000 units is
alpar@1
   114
                        # crs times nominal production cost
alpar@1
   115
alpar@1
   116
param iinv 'initial inventory' {prd} >= 0;
alpar@1
   117
alpar@1
   118
                        # Inventory at start of first period; age unknown
alpar@1
   119
alpar@1
   120
param iil 'initial inventory left' {p in prd, t in time}
alpar@1
   121
              := iinv[p] less sum {v in first..t} dem[p,v];
alpar@1
   122
alpar@1
   123
                        # Initial inventory still available for allocation
alpar@1
   124
                        # at end of period t
alpar@1
   125
alpar@1
   126
param minv 'minimum inventory' {p in prd, t in time}
alpar@1
   127
              := dem[p,t+1] * (if pro[p,t+1] then pir else rir);
alpar@1
   128
alpar@1
   129
                        # Lower limit on inventory at end of period t
alpar@1
   130
alpar@1
   131
###  VARIABLES  ###
alpar@1
   132
alpar@1
   133
var Crews{first-1..last} >= 0;
alpar@1
   134
alpar@1
   135
                        # Average number of crews employed in each period
alpar@1
   136
alpar@1
   137
var Hire{time} >= 0;    # Crews hired from previous to current period
alpar@1
   138
alpar@1
   139
var Layoff{time} >= 0;  # Crews laid off from previous to current period
alpar@1
   140
alpar@1
   141
var Rprd 'regular production' {prd,time} >= 0;
alpar@1
   142
alpar@1
   143
                        # Production using regular-time labor, in 1000s
alpar@1
   144
alpar@1
   145
var Oprd 'overtime production' {prd,time} >= 0;
alpar@1
   146
alpar@1
   147
                        # Production using overtime labor, in 1000s
alpar@1
   148
alpar@1
   149
var Inv 'inventory' {prd,time,1..life} >= 0;
alpar@1
   150
alpar@1
   151
                        # Inv[p,t,a] is the amount of product p that is
alpar@1
   152
                        # a periods old -- produced in period (t+1)-a --
alpar@1
   153
                        # and still in storage at the end of period t
alpar@1
   154
alpar@1
   155
var Short 'shortage' {prd,time} >= 0;
alpar@1
   156
alpar@1
   157
                        # Accumulated unsatisfied demand at the end of period t
alpar@1
   158
alpar@1
   159
###  OBJECTIVE  ###
alpar@1
   160
alpar@1
   161
minimize cost:
alpar@1
   162
alpar@1
   163
    sum {t in time} rtr * sl * dpp[t] * cs * Crews[t] +
alpar@1
   164
    sum {t in time} hc[t] * Hire[t] +
alpar@1
   165
    sum {t in time} lc[t] * Layoff[t] +
alpar@1
   166
    sum {t in time, p in prd} otr * cs * pt[p] * Oprd[p,t] +
alpar@1
   167
    sum {t in time, p in prd, a in 1..life} cri[p] * pc[p] * Inv[p,t,a] +
alpar@1
   168
    sum {t in time, p in prd} crs[p] * pc[p] * Short[p,t];
alpar@1
   169
alpar@1
   170
                        # Full regular wages for all crews employed, plus
alpar@1
   171
                        # penalties for hiring and layoffs, plus
alpar@1
   172
                        # wages for any overtime worked, plus
alpar@1
   173
                        # inventory and shortage costs
alpar@1
   174
alpar@1
   175
                        # (All other production costs are assumed
alpar@1
   176
                        # to depend on initial inventory and on demands,
alpar@1
   177
                        # and so are not included explicitly.)
alpar@1
   178
alpar@1
   179
###  CONSTRAINTS  ###
alpar@1
   180
alpar@1
   181
rlim 'regular-time limit' {t in time}:
alpar@1
   182
alpar@1
   183
    sum {p in prd} pt[p] * Rprd[p,t] <= sl * dpp[t] * Crews[t];
alpar@1
   184
alpar@1
   185
                        # Hours needed to accomplish all regular-time
alpar@1
   186
                        # production in a period must not exceed
alpar@1
   187
                        # hours available on all shifts
alpar@1
   188
alpar@1
   189
olim 'overtime limit' {t in time}:
alpar@1
   190
alpar@1
   191
    sum {p in prd} pt[p] * Oprd[p,t] <= ol[t];
alpar@1
   192
alpar@1
   193
                        # Hours needed to accomplish all overtime
alpar@1
   194
                        # production in a period must not exceed
alpar@1
   195
                        # the specified overtime limit
alpar@1
   196
alpar@1
   197
empl0 'initial crew level':  Crews[first-1] = iw;
alpar@1
   198
alpar@1
   199
                        # Use given initial workforce
alpar@1
   200
alpar@1
   201
empl 'crew levels' {t in time}:  Crews[t] = Crews[t-1] + Hire[t] - Layoff[t];
alpar@1
   202
alpar@1
   203
                        # Workforce changes by hiring or layoffs
alpar@1
   204
alpar@1
   205
emplbnd 'crew limits' {t in time}:  cmin[t] <= Crews[t] <= cmax[t];
alpar@1
   206
alpar@1
   207
                        # Workforce must remain within specified bounds
alpar@1
   208
alpar@1
   209
dreq1 'first demand requirement' {p in prd}:
alpar@1
   210
alpar@1
   211
    Rprd[p,first] + Oprd[p,first] + Short[p,first]
alpar@1
   212
                             - Inv[p,first,1] = dem[p,first] less iinv[p];
alpar@1
   213
alpar@1
   214
dreq 'demand requirements' {p in prd, t in first+1..last}:
alpar@1
   215
alpar@1
   216
    Rprd[p,t] + Oprd[p,t] + Short[p,t] - Short[p,t-1]
alpar@1
   217
                          + sum {a in 1..life} (Inv[p,t-1,a] - Inv[p,t,a])
alpar@1
   218
                                                  = dem[p,t] less iil[p,t-1];
alpar@1
   219
alpar@1
   220
                        # Production plus increase in shortage plus
alpar@1
   221
                        # decrease in inventory must equal demand
alpar@1
   222
alpar@1
   223
ireq 'inventory requirements' {p in prd, t in time}:
alpar@1
   224
alpar@1
   225
    sum {a in 1..life} Inv[p,t,a] + iil[p,t] >= minv[p,t];
alpar@1
   226
alpar@1
   227
                        # Inventory in storage at end of period t
alpar@1
   228
                        # must meet specified minimum
alpar@1
   229
alpar@1
   230
izero 'impossible inventories' {p in prd, v in 1..life-1, a in v+1..life}:
alpar@1
   231
alpar@1
   232
    Inv[p,first+v-1,a] = 0;
alpar@1
   233
alpar@1
   234
                        # In the vth period (starting from first)
alpar@1
   235
                        # no inventory may be more than v periods old
alpar@1
   236
                        # (initial inventories are handled separately)
alpar@1
   237
alpar@1
   238
ilim1 'new-inventory limits' {p in prd, t in time}:
alpar@1
   239
alpar@1
   240
    Inv[p,t,1] <= Rprd[p,t] + Oprd[p,t];
alpar@1
   241
alpar@1
   242
                        # New inventory cannot exceed
alpar@1
   243
                        # production in the most recent period
alpar@1
   244
alpar@1
   245
ilim 'inventory limits' {p in prd, t in first+1..last, a in 2..life}:
alpar@1
   246
alpar@1
   247
    Inv[p,t,a] <= Inv[p,t-1,a-1];
alpar@1
   248
alpar@1
   249
                        # Inventory left from period (t+1)-p
alpar@1
   250
                        # can only decrease as time goes on
alpar@1
   251
alpar@1
   252
###  DATA  ###
alpar@1
   253
alpar@1
   254
data;
alpar@1
   255
alpar@1
   256
set prd := 18REG 24REG 24PRO ;
alpar@1
   257
alpar@1
   258
param first :=  1 ;
alpar@1
   259
param last  := 13 ;
alpar@1
   260
param life  :=  2 ;
alpar@1
   261
alpar@1
   262
param cs := 18 ;
alpar@1
   263
param sl :=  8 ;
alpar@1
   264
param iw :=  8 ;
alpar@1
   265
alpar@1
   266
param rtr := 16.00 ;
alpar@1
   267
param otr := 43.85 ;
alpar@1
   268
param rir :=  0.75 ;
alpar@1
   269
param pir :=  0.80 ;
alpar@1
   270
alpar@1
   271
param :         pt       pc        cri       crs      iinv   :=
alpar@1
   272
alpar@1
   273
  18REG      1.194     2304.     0.015     1.100      82.0
alpar@1
   274
  24REG      1.509     2920.     0.015     1.100     792.2
alpar@1
   275
  24PRO      1.509     2910.     0.015     1.100       0.0   ;
alpar@1
   276
alpar@1
   277
param :     dpp        ol      cmin      cmax        hc        lc   :=
alpar@1
   278
alpar@1
   279
  1        19.5      96.0       0.0       8.0      7500      7500
alpar@1
   280
  2        19.0      96.0       0.0       8.0      7500      7500
alpar@1
   281
  3        20.0      96.0       0.0       8.0      7500      7500
alpar@1
   282
  4        19.0      96.0       0.0       8.0      7500      7500
alpar@1
   283
  5        19.5      96.0       0.0       8.0     15000     15000
alpar@1
   284
  6        19.0      96.0       0.0       8.0     15000     15000
alpar@1
   285
  7        19.0      96.0       0.0       8.0     15000     15000
alpar@1
   286
  8        20.0      96.0       0.0       8.0     15000     15000
alpar@1
   287
  9        19.0      96.0       0.0       8.0     15000     15000
alpar@1
   288
 10        20.0      96.0       0.0       8.0     15000     15000
alpar@1
   289
 11        20.0      96.0       0.0       8.0      7500      7500
alpar@1
   290
 12        18.0      96.0       0.0       8.0      7500      7500
alpar@1
   291
 13        18.0      96.0       0.0       8.0      7500      7500   ;
alpar@1
   292
alpar@1
   293
param dem (tr) :
alpar@1
   294
alpar@1
   295
          18REG     24REG     24PRO   :=
alpar@1
   296
alpar@1
   297
  1        63.8    1212.0       0.0
alpar@1
   298
  2        76.0     306.2       0.0
alpar@1
   299
  3        88.4     319.0       0.0
alpar@1
   300
  4       913.8     208.4       0.0
alpar@1
   301
  5       115.0     298.0       0.0
alpar@1
   302
  6       133.8     328.2       0.0
alpar@1
   303
  7        79.6     959.6       0.0
alpar@1
   304
  8       111.0     257.6       0.0
alpar@1
   305
  9       121.6     335.6       0.0
alpar@1
   306
 10       470.0     118.0    1102.0
alpar@1
   307
 11        78.4     284.8       0.0
alpar@1
   308
 12        99.4     970.0       0.0
alpar@1
   309
 13       140.4     343.8       0.0
alpar@1
   310
 14        63.8    1212.0       0.0   ;
alpar@1
   311
alpar@1
   312
param pro (tr) :
alpar@1
   313
alpar@1
   314
          18REG     24REG     24PRO   :=
alpar@1
   315
alpar@1
   316
  1           0         1         0
alpar@1
   317
  2           0         0         0
alpar@1
   318
  3           0         0         0
alpar@1
   319
  4           1         0         0
alpar@1
   320
  5           0         0         0
alpar@1
   321
  6           0         0         0
alpar@1
   322
  7           0         1         0
alpar@1
   323
  8           0         0         0
alpar@1
   324
  9           0         0         0
alpar@1
   325
 10           1         0         1
alpar@1
   326
 11           0         0         0
alpar@1
   327
 12           0         0         0
alpar@1
   328
 13           0         1         0
alpar@1
   329
 14           0         1         0   ;
alpar@1
   330
alpar@1
   331
end;