@@ -65,7 +65,7 @@ duration/location of the slots we know some of them are unavailable for a given
6565
6666 >>> events = [Event(name='Talk 1', duration=30, tags=['beginner'], unavailability=outside_slots[:], demand=50),
6767 ... Event(name='Talk 2', duration=30, tags=['beginner'], unavailability=outside_slots[:], demand=130),
68- ... Event(name='Talk 3', duration=30, tags=['beginner'], unavailability=outside_slots[:], demand=3000 ),
68+ ... Event(name='Talk 3', duration=30, tags=['beginner'], unavailability=outside_slots[:], demand=200 ),
6969 ... Event(name='Talk 4', duration=30, tags=['beginner'], unavailability=outside_slots[:], demand=30),
7070 ... Event(name='Talk 5', duration=30, tags=['intermediate'], unavailability=outside_slots[:], demand=60),
7171 ... Event(name='Talk 6', duration=30, tags=['intermediate'], unavailability=outside_slots[:], demand=30),
@@ -75,7 +75,7 @@ duration/location of the slots we know some of them are unavailable for a given
7575 ... Event(name='Talk 10', duration=30, tags=['advanced'], unavailability=outside_slots[:], demand=30),
7676 ... Event(name='Talk 11', duration=30, tags=['advanced'], unavailability=outside_slots[:], demand=30),
7777 ... Event(name='Talk 12', duration=30, tags=['advanced'], unavailability=outside_slots[:], demand=30),
78- ... Event(name='Workshop 1', duration=60, tags=['testing'], unavailability=outside_slots[:], demand=300 ),
78+ ... Event(name='Workshop 1', duration=60, tags=['testing'], unavailability=outside_slots[:], demand=40 ),
7979 ... Event(name='Workshop 2', duration=60, tags=['testing'], unavailability=outside_slots[:], demand=40),
8080 ... Event(name='City tour', duration=90, tags=[], unavailability=talk_slots[:] + workshop_slots[:], demand=100),
8181 ... Event(name='Boardgames', duration=90, tags=[], unavailability=talk_slots[:] + workshop_slots[:], demand=20)]
@@ -137,49 +137,79 @@ Avoiding room overcrowding
137137
138138The data we input in to the model included information about demand for a talk;
139139this could be approximated from previous popularity for a talk. However, the
140- scheduler has put :code: `Talk 2 ` and :code: ` Talk 3 ` (which have high demand) in
140+ scheduler has put :code: `Talk 3 ` (which have high demand) in
141141the small room (which has capacity 50). We can include an objective function in
142142our scheduler to minimise the difference between room capacity and demand::
143143
144144 >>> from conference_scheduler.lp_problem import objective_functions
145- >>> func = objective_functions.capacity_demand_difference
145+ >>> func = objective_functions.efficiency_capacity_demand_difference
146146 >>> schedule = scheduler.schedule(events, slots, objective_function=func)
147147
148148 >>> schedule.sort(key=lambda item: item.slot.starts_at)
149149 >>> for item in schedule:
150150 ... print(f"{item.event.name} at {item.slot.starts_at} in {item.slot.venue}")
151- Talk 1 at 15-Sep-2016 09:30 in Big
152- Talk 12 at 15-Sep-2016 09:30 in Small
153- Talk 2 at 15-Sep-2016 10:00 in Big
154- Talk 6 at 15-Sep-2016 10:00 in Small
155- Talk 4 at 15-Sep-2016 12:30 in Small
156- Talk 11 at 15-Sep-2016 12:30 in Big
157- Talk 5 at 15-Sep-2016 13:00 in Small
158- Talk 10 at 15-Sep-2016 13:00 in Big
159- Talk 7 at 16-Sep-2016 09:30 in Big
151+ Talk 4 at 15-Sep-2016 09:30 in Big
152+ Talk 5 at 15-Sep-2016 09:30 in Small
153+ Talk 3 at 15-Sep-2016 10:00 in Big
154+ Talk 9 at 15-Sep-2016 10:00 in Small
155+ Talk 6 at 15-Sep-2016 12:30 in Big
156+ Talk 11 at 15-Sep-2016 12:30 in Small
157+ Talk 2 at 15-Sep-2016 13:00 in Small
158+ Talk 7 at 15-Sep-2016 13:00 in Big
159+ Talk 8 at 16-Sep-2016 09:30 in Big
160160 Workshop 2 at 16-Sep-2016 09:30 in Small
161- Talk 8 at 16-Sep-2016 10:00 in Big
162- Talk 3 at 16-Sep-2016 12:30 in Big
161+ Talk 12 at 16-Sep-2016 10:00 in Big
162+ Talk 1 at 16-Sep-2016 12:30 in Big
163163 Boardgames at 16-Sep-2016 12:30 in Outside
164- Talk 9 at 16-Sep-2016 13:00 in Big
164+ Talk 10 at 16-Sep-2016 13:00 in Big
165165 Workshop 1 at 16-Sep-2016 13:00 in Small
166166 City tour at 16-Sep-2016 13:00 in Outside
167167
168+ We see that :code: `Talk 3 ` has moved to the bigger room but that all other
169+ constraints still hold. Note however that this has also moved :code: `Talk 2 `
170+ (which has relatively high demand) to a small room. This is because we have
171+ minimised the overall overcrowding. This can have the negative effect of leaving
172+ one slot with a high overcrowding for the benefit of overall efficiency. We can
173+ however include a different objective function to minimise the maximum
174+ overcrowding in any given slot::
168175
169- We see that those talks have moved to the bigger room but that all other
170- constraints still hold.
176+ >>> from conference_scheduler.lp_problem import objective_functions
177+ >>> func = objective_functions.equity_capacity_demand_difference
178+ >>> schedule = scheduler.schedule(events, slots, objective_function=func)
179+
180+ >>> schedule.sort(key=lambda item: item.slot.starts_at)
181+ >>> for item in schedule:
182+ ... print(f"{item.event.name} at {item.slot.starts_at} in {item.slot.venue}")
183+ Talk 1 at 15-Sep-2016 09:30 in Small
184+ Talk 9 at 15-Sep-2016 09:30 in Big
185+ Talk 3 at 15-Sep-2016 10:00 in Big
186+ Talk 10 at 15-Sep-2016 10:00 in Small
187+ Talk 4 at 15-Sep-2016 12:30 in Small
188+ Talk 7 at 15-Sep-2016 12:30 in Big
189+ Talk 2 at 15-Sep-2016 13:00 in Big
190+ Talk 8 at 15-Sep-2016 13:00 in Small
191+ Talk 6 at 16-Sep-2016 09:30 in Big
192+ Workshop 2 at 16-Sep-2016 09:30 in Small
193+ Talk 12 at 16-Sep-2016 10:00 in Big
194+ Talk 11 at 16-Sep-2016 12:30 in Big
195+ Boardgames at 16-Sep-2016 12:30 in Outside
196+ Talk 5 at 16-Sep-2016 13:00 in Big
197+ Workshop 1 at 16-Sep-2016 13:00 in Small
198+ City tour at 16-Sep-2016 13:00 in Outside
199+
200+ Now, both :code: `Talk 2 ` and :code: `Talk 3 ` are in the bigger rooms.
171201
172202Coping with new information
173203---------------------------
174204
175205This is fantastic! Our schedule has now been published and everyone is excited
176206about the conference. However, as can often happen, one of the speakers now
177207informs us of a particular new constraints. For example, the speaker for
178- :code: `Talk 11 ` is unable to speak on the first day.
208+ :code: `Talk 11 ` is unable to speak on the second day.
179209
180210We can enter this new constraint::
181211
182- >>> events[10].add_unavailability(*slots[:9 ])
212+ >>> events[10].add_unavailability(*slots[9: ])
183213
184214We can now solve the problem one more time from scratch just as before::
185215
@@ -188,20 +218,20 @@ We can now solve the problem one more time from scratch just as before::
188218 >>> alt_schedule.sort(key=lambda item: item.slot.starts_at)
189219 >>> for item in alt_schedule:
190220 ... print(f"{item.event.name} at {item.slot.starts_at} in {item.slot.venue}")
191- Talk 1 at 15-Sep-2016 09:30 in Small
192- Talk 9 at 15-Sep-2016 09:30 in Big
193- Talk 5 at 15-Sep-2016 10:00 in Big
221+ Talk 3 at 15-Sep-2016 09:30 in Big
222+ Talk 12 at 15-Sep-2016 09:30 in Small
223+ Talk 2 at 15-Sep-2016 10:00 in Big
194224 Talk 10 at 15-Sep-2016 10:00 in Small
195- Talk 4 at 15-Sep-2016 12:30 in Big
196- Talk 7 at 15-Sep-2016 12:30 in Small
197- Talk 6 at 15-Sep-2016 13:00 in Big
198- Talk 12 at 15-Sep-2016 13:00 in Small
199- Talk 2 at 16-Sep-2016 09:30 in Big
225+ Talk 1 at 15-Sep-2016 12:30 in Big
226+ Talk 8 at 15-Sep-2016 12:30 in Small
227+ Talk 5 at 15-Sep-2016 13:00 in Big
228+ Talk 9 at 15-Sep-2016 13:00 in Small
229+ Talk 11 at 16-Sep-2016 09:30 in Big
200230 Workshop 2 at 16-Sep-2016 09:30 in Small
201- Talk 8 at 16-Sep-2016 10:00 in Big
202- Talk 3 at 16-Sep-2016 12:30 in Big
231+ Talk 4 at 16-Sep-2016 10:00 in Big
232+ Talk 7 at 16-Sep-2016 12:30 in Big
203233 Boardgames at 16-Sep-2016 12:30 in Outside
204- Talk 11 at 16-Sep-2016 13:00 in Big
234+ Talk 6 at 16-Sep-2016 13:00 in Big
205235 Workshop 1 at 16-Sep-2016 13:00 in Small
206236 City tour at 16-Sep-2016 13:00 in Outside
207237
@@ -210,27 +240,26 @@ completely different schedule with a number of changes. We can however solve the
210240problem with a new objective function which is to minimise the changes from the
211241old schedule::
212242
213-
214243 >>> func = objective_functions.number_of_changes
215244 >>> similar_schedule = scheduler.schedule(events, slots, objective_function=func, original_schedule=schedule)
216245
217246 >>> similar_schedule.sort(key=lambda item: item.slot.starts_at)
218247 >>> for item in similar_schedule:
219248 ... print(f"{item.event.name} at {item.slot.starts_at} in {item.slot.venue}")
220- Talk 1 at 15-Sep-2016 09:30 in Big
221- Talk 12 at 15-Sep-2016 09:30 in Small
222- Talk 2 at 15-Sep-2016 10:00 in Big
223- Talk 6 at 15-Sep-2016 10:00 in Small
249+ Talk 1 at 15-Sep-2016 09:30 in Small
250+ Talk 9 at 15-Sep-2016 09:30 in Big
251+ Talk 3 at 15-Sep-2016 10:00 in Big
252+ Talk 10 at 15-Sep-2016 10:00 in Small
224253 Talk 4 at 15-Sep-2016 12:30 in Small
225- Talk 9 at 15-Sep-2016 12:30 in Big
226- Talk 5 at 15-Sep-2016 13:00 in Small
227- Talk 10 at 15-Sep-2016 13:00 in Big
228- Talk 7 at 16-Sep-2016 09:30 in Big
254+ Talk 7 at 15-Sep-2016 12:30 in Big
255+ Talk 2 at 15-Sep-2016 13:00 in Big
256+ Talk 8 at 15-Sep-2016 13:00 in Small
257+ Talk 11 at 16-Sep-2016 09:30 in Big
229258 Workshop 2 at 16-Sep-2016 09:30 in Small
230- Talk 8 at 16-Sep-2016 10:00 in Big
231- Talk 3 at 16-Sep-2016 12:30 in Big
259+ Talk 12 at 16-Sep-2016 10:00 in Big
260+ Talk 6 at 16-Sep-2016 12:30 in Big
232261 Boardgames at 16-Sep-2016 12:30 in Outside
233- Talk 11 at 16-Sep-2016 13:00 in Big
262+ Talk 5 at 16-Sep-2016 13:00 in Big
234263 Workshop 1 at 16-Sep-2016 13:00 in Small
235264 City tour at 16-Sep-2016 13:00 in Outside
236265
@@ -246,34 +275,35 @@ with the original. Firstly, we can see which events moved to different slots::
246275 >>> event_diff = scheduler.event_schedule_difference(schedule, alt_schedule)
247276 >>> for item in event_diff:
248277 ... print(f"{item.event.name} has moved from {item.old_slot.venue} at {item.old_slot.starts_at} to {item.new_slot.venue} at {item.new_slot.starts_at}")
249- Talk 1 has moved from Big at 15-Sep-2016 09:30 to Small at 15-Sep-2016 09:30
250- Talk 10 has moved from Big at 15-Sep-2016 13:00 to Small at 15-Sep-2016 10:00
251- Talk 11 has moved from Big at 15-Sep-2016 12:30 to Big at 16-Sep-2016 13:00
252- Talk 12 has moved from Small at 15-Sep-2016 09:30 to Small at 15-Sep-2016 13:00
253- Talk 2 has moved from Big at 15-Sep-2016 10:00 to Big at 16-Sep-2016 09:30
254- Talk 4 has moved from Small at 15-Sep-2016 12:30 to Big at 15-Sep-2016 12:30
255- Talk 5 has moved from Small at 15-Sep-2016 13:00 to Big at 15-Sep-2016 10:00
256- Talk 6 has moved from Small at 15-Sep-2016 10:00 to Big at 15-Sep-2016 13:00
257- Talk 7 has moved from Big at 16-Sep-2016 09:30 to Small at 15-Sep-2016 12:30
258- Talk 9 has moved from Big at 16-Sep-2016 13:00 to Big at 15-Sep-2016 09:30
278+ Talk 1 has moved from Small at 15-Sep-2016 09:30 to Big at 15-Sep-2016 12:30
279+ Talk 11 has moved from Big at 16-Sep-2016 12:30 to Big at 16-Sep-2016 09:30
280+ Talk 12 has moved from Big at 16-Sep-2016 10:00 to Small at 15-Sep-2016 09:30
281+ Talk 2 has moved from Big at 15-Sep-2016 13:00 to Big at 15-Sep-2016 10:00
282+ Talk 3 has moved from Big at 15-Sep-2016 10:00 to Big at 15-Sep-2016 09:30
283+ Talk 4 has moved from Small at 15-Sep-2016 12:30 to Big at 16-Sep-2016 10:00
284+ Talk 5 has moved from Big at 16-Sep-2016 13:00 to Big at 15-Sep-2016 13:00
285+ Talk 6 has moved from Big at 16-Sep-2016 09:30 to Big at 16-Sep-2016 13:00
286+ Talk 7 has moved from Big at 15-Sep-2016 12:30 to Big at 16-Sep-2016 12:30
287+ Talk 8 has moved from Small at 15-Sep-2016 13:00 to Small at 15-Sep-2016 12:30
288+ Talk 9 has moved from Big at 15-Sep-2016 09:30 to Small at 15-Sep-2016 13:00
259289
260290
261291We can also look at slots to see which now have a different event scheduled::
262292
263293 >>> slot_diff = scheduler.slot_schedule_difference(schedule, alt_schedule)
264294 >>> for item in slot_diff:
265295 ... print(f"{item.slot.venue} at {item.slot.starts_at} will now host {item.new_event.name} rather than {item.old_event.name}" )
266- Big at 15-Sep-2016 09:30 will now host Talk 9 rather than Talk 1
267- Big at 15-Sep-2016 10:00 will now host Talk 5 rather than Talk 2
268- Big at 15-Sep-2016 12:30 will now host Talk 4 rather than Talk 11
269- Big at 15-Sep-2016 13:00 will now host Talk 6 rather than Talk 10
270- Big at 16-Sep-2016 09:30 will now host Talk 2 rather than Talk 7
271- Big at 16-Sep-2016 13 :00 will now host Talk 11 rather than Talk 9
272- Small at 15 -Sep-2016 09 :30 will now host Talk 1 rather than Talk 12
273- Small at 15 -Sep-2016 10 :00 will now host Talk 10 rather than Talk 6
274- Small at 15-Sep-2016 12 :30 will now host Talk 7 rather than Talk 4
275- Small at 15-Sep-2016 13:00 will now host Talk 12 rather than Talk 5
276-
296+ Big at 15-Sep-2016 09:30 will now host Talk 3 rather than Talk 9
297+ Big at 15-Sep-2016 10:00 will now host Talk 2 rather than Talk 3
298+ Big at 15-Sep-2016 12:30 will now host Talk 1 rather than Talk 7
299+ Big at 15-Sep-2016 13:00 will now host Talk 5 rather than Talk 2
300+ Big at 16-Sep-2016 09:30 will now host Talk 11 rather than Talk 6
301+ Big at 16-Sep-2016 10 :00 will now host Talk 4 rather than Talk 12
302+ Big at 16 -Sep-2016 12 :30 will now host Talk 7 rather than Talk 11
303+ Big at 16 -Sep-2016 13 :00 will now host Talk 6 rather than Talk 5
304+ Small at 15-Sep-2016 09 :30 will now host Talk 12 rather than Talk 1
305+ Small at 15-Sep-2016 12:30 will now host Talk 8 rather than Talk 4
306+ Small at 15-Sep-2016 13:00 will now host Talk 9 rather than Talk 8
277307
278308
279309We can use this facility to show how using :code: `number_of_changes ` as our objective function
@@ -282,9 +312,8 @@ resulted in far fewer changes::
282312 >>> event_diff = scheduler.event_schedule_difference(schedule, similar_schedule)
283313 >>> for item in event_diff:
284314 ... print(f"{item.event.name} has moved from {item.old_slot.venue} at {item.old_slot.starts_at} to {item.new_slot.venue} at {item.new_slot.starts_at}")
285- Talk 11 has moved from Big at 15-Sep-2016 12:30 to Big at 16-Sep-2016 13:00
286- Talk 9 has moved from Big at 16-Sep-2016 13:00 to Big at 15-Sep-2016 12:30
287-
315+ Talk 11 has moved from Big at 16-Sep-2016 12:30 to Big at 16-Sep-2016 09:30
316+ Talk 6 has moved from Big at 16-Sep-2016 09:30 to Big at 16-Sep-2016 12:30
288317
289318
290319Scheduling chairs
0 commit comments