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