[9] | 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; |
---|