|
1 /* File: shiftcover.mod */ |
|
2 |
|
3 /* WORKFORCE SHIFT COVERAGE assignment problem */ |
|
4 |
|
5 /* Written by Larry D'Agostino <larrydag -at- sbcglobal -dot- com> |
|
6 |
|
7 Maximize Productivity with Industrial Engineer and Operations Research Tools |
|
8 http://industrialengineertools.blogspot.com |
|
9 |
|
10 |
|
11 /* The WORKFORCE SHIFT COVERAGE is an assigment problem that determines |
|
12 the schedule of crew given available time and shifts. |
|
13 |
|
14 The objective is to cover the available time given hourly demand with the minimum |
|
15 number of crew members. |
|
16 |
|
17 This is a set covering problem that is very common among finding crew |
|
18 and shift allocations. Notice in the data section the workforce shift allocation |
|
19 per day of the week.*/ |
|
20 |
|
21 |
|
22 /* ----- Model PARAMTERS and SETS -----*/ |
|
23 |
|
24 param numhrs; |
|
25 /* number of hours of operations in a given day */ |
|
26 |
|
27 param dys; |
|
28 /* number of days in a week */ |
|
29 |
|
30 set S; |
|
31 /* set of crew shifts */ |
|
32 |
|
33 set H := 1..numhrs; |
|
34 /* set of hours of a day*/ |
|
35 |
|
36 set D; |
|
37 /* set of days of a week*/ |
|
38 |
|
39 param dmnd{h in H, d in D}; |
|
40 /* demand for crew members given h hour and d day */ |
|
41 |
|
42 param shifts{d in D, h in H, s in S}; |
|
43 /* shifts to assign to crew members given d day, h hour, and s shift schedule |
|
44 |
|
45 /*----- Model VARIABLES -----*/ |
|
46 |
|
47 var crew{s in S}, integer, >=0; |
|
48 /* number of crew assigned to shift S */ |
|
49 |
|
50 |
|
51 /*----- Model CONSTRAINTS -----*/ |
|
52 |
|
53 s.t. Coverage{h in H, d in D}: sum{s in S} crew[s]*shifts[d,h,s] >= dmnd[h,d]; |
|
54 /* number of crew to cover with a shift given hourly demand and day */ |
|
55 |
|
56 |
|
57 /*----- Model OBJECTIVE -----*/ |
|
58 |
|
59 minimize obj: sum{s in S} crew[s]; |
|
60 /* minimize number of crew to cover demand*/ |
|
61 |
|
62 solve; |
|
63 display crew; |
|
64 |
|
65 printf "\n"; |
|
66 printf "Total Crew: %3d\n\n", sum{s in S} crew[s]; |
|
67 |
|
68 |
|
69 |
|
70 printf "\n\n"; |
|
71 printf "Weekly Crew Schedule\n\n"; |
|
72 printf "Hour "; |
|
73 printf{d in D} " %s ", d; |
|
74 printf "\n"; |
|
75 for {h in H} { |
|
76 printf " %2s ",h; |
|
77 printf{d in D} " %3d ", sum{s in S} crew[s]*shifts[d,h,s]; |
|
78 printf "\n"; |
|
79 } |
|
80 printf"\n"; |
|
81 |
|
82 |
|
83 |
|
84 data; |
|
85 |
|
86 param numhrs := 16; |
|
87 |
|
88 set D := SUN, MON, TUE, WED, THU, FRI, SAT; |
|
89 |
|
90 set S := Sh1, Sh2, Sh3, Sh4, Sh5, Sh6, Sh7, Sh8, Sh9; |
|
91 |
|
92 param dmnd : SUN MON TUE WED THU FRI SAT := |
|
93 1 0 3 3 4 3 2 0 |
|
94 2 0 14 14 16 14 12 12 |
|
95 3 0 24 24 27 24 20 15 |
|
96 4 0 28 28 32 28 23 15 |
|
97 5 0 33 33 37 33 24 16 |
|
98 6 0 34 34 38 34 24 15 |
|
99 7 0 35 35 39 35 25 11 |
|
100 8 0 35 35 40 35 27 0 |
|
101 9 0 34 34 39 34 25 0 |
|
102 10 0 31 31 35 31 24 0 |
|
103 11 2 24 24 27 24 25 0 |
|
104 12 3 19 19 21 19 21 0 |
|
105 13 2 24 24 27 24 13 0 |
|
106 14 2 16 16 18 16 0 0 |
|
107 15 0 7 7 7 7 0 0 |
|
108 16 0 5 5 5 5 0 0; |
|
109 |
|
110 |
|
111 param shifts := |
|
112 ['SUN',*,*]: |
|
113 Sh1 Sh2 Sh3 Sh4 Sh5 Sh6 Sh7 Sh8 Sh9 := |
|
114 1 0 0 0 0 0 0 0 0 0 |
|
115 2 0 0 0 0 0 0 0 0 0 |
|
116 3 0 0 0 0 0 0 0 0 0 |
|
117 4 0 0 0 0 0 0 0 0 0 |
|
118 5 0 0 0 0 0 0 0 0 0 |
|
119 6 0 0 0 0 0 0 0 0 0 |
|
120 7 0 0 0 0 0 0 0 0 0 |
|
121 8 0 0 0 0 0 0 0 0 0 |
|
122 9 0 0 0 0 0 0 0 0 0 |
|
123 10 0 0 0 0 0 0 0 0 0 |
|
124 11 0 0 0 0 0 0 0 0 1 |
|
125 12 0 0 0 0 0 0 0 0 1 |
|
126 13 0 0 0 0 0 0 0 0 1 |
|
127 14 0 0 0 0 0 0 0 0 1 |
|
128 15 0 0 0 0 0 0 0 0 0 |
|
129 16 0 0 0 0 0 0 0 0 0 |
|
130 |
|
131 |
|
132 ['MON',*,*]: |
|
133 Sh1 Sh2 Sh3 Sh4 Sh5 Sh6 Sh7 Sh8 Sh9 := |
|
134 1 1 0 0 0 0 0 0 0 0 |
|
135 2 1 1 0 0 0 0 0 0 0 |
|
136 3 1 1 1 0 0 0 0 0 0 |
|
137 4 1 1 1 1 0 0 0 0 0 |
|
138 5 0 1 1 1 1 0 0 0 0 |
|
139 6 1 0 1 1 1 1 0 0 1 |
|
140 7 1 1 0 1 1 1 1 0 1 |
|
141 8 1 1 1 0 1 1 1 1 1 |
|
142 9 1 1 1 1 0 1 1 1 1 |
|
143 10 0 1 1 1 1 0 1 1 1 |
|
144 11 0 0 1 1 1 1 0 1 0 |
|
145 12 0 0 0 1 1 1 1 0 1 |
|
146 13 0 0 0 0 1 1 1 1 1 |
|
147 14 0 0 0 0 0 1 1 1 1 |
|
148 15 0 0 0 0 0 0 1 1 1 |
|
149 16 0 0 0 0 0 0 0 1 1 |
|
150 |
|
151 ['TUE',*,*]: |
|
152 Sh1 Sh2 Sh3 Sh4 Sh5 Sh6 Sh7 Sh8 Sh9 := |
|
153 1 1 0 0 0 0 0 0 0 0 |
|
154 2 1 1 0 0 0 0 0 0 0 |
|
155 3 1 1 1 0 0 0 0 0 0 |
|
156 4 1 1 1 1 0 0 0 0 0 |
|
157 5 0 1 1 1 1 0 0 0 0 |
|
158 6 1 0 1 1 1 1 0 0 1 |
|
159 7 1 1 0 1 1 1 1 0 1 |
|
160 8 1 1 1 0 1 1 1 1 1 |
|
161 9 1 1 1 1 0 1 1 1 1 |
|
162 10 0 1 1 1 1 0 1 1 1 |
|
163 11 0 0 1 1 1 1 0 1 0 |
|
164 12 0 0 0 1 1 1 1 0 1 |
|
165 13 0 0 0 0 1 1 1 1 1 |
|
166 14 0 0 0 0 0 1 1 1 1 |
|
167 15 0 0 0 0 0 0 1 1 1 |
|
168 16 0 0 0 0 0 0 0 1 1 |
|
169 |
|
170 ['WED',*,*]: |
|
171 Sh1 Sh2 Sh3 Sh4 Sh5 Sh6 Sh7 Sh8 Sh9 := |
|
172 1 1 0 0 0 0 0 0 0 0 |
|
173 2 1 1 0 0 0 0 0 0 0 |
|
174 3 1 1 1 0 0 0 0 0 0 |
|
175 4 1 1 1 1 0 0 0 0 0 |
|
176 5 0 1 1 1 1 0 0 0 0 |
|
177 6 1 0 1 1 1 1 0 0 1 |
|
178 7 1 1 0 1 1 1 1 0 1 |
|
179 8 1 1 1 0 1 1 1 1 1 |
|
180 9 1 1 1 1 0 1 1 1 1 |
|
181 10 0 1 1 1 1 0 1 1 1 |
|
182 11 0 0 1 1 1 1 0 1 0 |
|
183 12 0 0 0 1 1 1 1 0 1 |
|
184 13 0 0 0 0 1 1 1 1 1 |
|
185 14 0 0 0 0 0 1 1 1 1 |
|
186 15 0 0 0 0 0 0 1 1 1 |
|
187 16 0 0 0 0 0 0 0 1 1 |
|
188 |
|
189 ['THU',*,*]: |
|
190 Sh1 Sh2 Sh3 Sh4 Sh5 Sh6 Sh7 Sh8 Sh9 := |
|
191 1 1 0 0 0 0 0 0 0 0 |
|
192 2 1 1 0 0 0 0 0 0 0 |
|
193 3 1 1 1 0 0 0 0 0 0 |
|
194 4 1 1 1 1 0 0 0 0 0 |
|
195 5 0 1 1 1 1 0 0 0 0 |
|
196 6 1 0 1 1 1 1 0 0 0 |
|
197 7 1 1 0 1 1 1 1 0 0 |
|
198 8 1 1 1 0 1 1 1 1 0 |
|
199 9 1 1 1 1 0 1 1 1 0 |
|
200 10 0 1 1 1 1 0 1 1 0 |
|
201 11 0 0 1 1 1 1 0 1 0 |
|
202 12 0 0 0 1 1 1 1 0 0 |
|
203 13 0 0 0 0 1 1 1 1 0 |
|
204 14 0 0 0 0 0 1 1 1 0 |
|
205 15 0 0 0 0 0 0 1 1 0 |
|
206 16 0 0 0 0 0 0 0 1 0 |
|
207 |
|
208 ['FRI',*,*]: |
|
209 Sh1 Sh2 Sh3 Sh4 Sh5 Sh6 Sh7 Sh8 Sh9 := |
|
210 1 1 0 0 0 0 0 0 0 0 |
|
211 2 1 1 0 0 0 0 0 0 0 |
|
212 3 1 1 1 0 0 0 0 0 0 |
|
213 4 1 1 1 1 0 0 0 0 0 |
|
214 5 0 1 1 1 1 0 0 0 0 |
|
215 6 1 0 1 1 1 1 0 0 0 |
|
216 7 1 1 0 1 1 1 1 0 0 |
|
217 8 1 1 1 0 1 1 1 1 0 |
|
218 9 1 1 1 1 0 1 1 1 0 |
|
219 10 0 1 1 1 1 0 1 1 0 |
|
220 11 0 0 1 1 1 1 0 1 0 |
|
221 12 0 0 0 1 1 1 1 0 0 |
|
222 13 0 0 0 0 1 1 1 1 0 |
|
223 14 0 0 0 0 0 1 1 1 0 |
|
224 15 0 0 0 0 0 0 1 1 0 |
|
225 16 0 0 0 0 0 0 0 1 0 |
|
226 |
|
227 ['SAT',*,*]: |
|
228 Sh1 Sh2 Sh3 Sh4 Sh5 Sh6 Sh7 Sh8 Sh9 := |
|
229 1 0 0 0 0 0 0 0 0 0 |
|
230 2 0 0 0 0 0 0 0 0 1 |
|
231 3 0 0 0 0 0 0 0 0 1 |
|
232 4 0 0 0 0 0 0 0 0 1 |
|
233 5 0 0 0 0 0 0 0 0 1 |
|
234 6 0 0 0 0 0 0 0 0 1 |
|
235 7 0 0 0 0 0 0 0 0 1 |
|
236 8 0 0 0 0 0 0 0 0 0 |
|
237 9 0 0 0 0 0 0 0 0 0 |
|
238 10 0 0 0 0 0 0 0 0 0 |
|
239 11 0 0 0 0 0 0 0 0 0 |
|
240 12 0 0 0 0 0 0 0 0 0 |
|
241 13 0 0 0 0 0 0 0 0 0 |
|
242 14 0 0 0 0 0 0 0 0 0 |
|
243 15 0 0 0 0 0 0 0 0 0 |
|
244 16 0 0 0 0 0 0 0 0 0; |