Spaces:
Sleeping
Sleeping
Update constraint_engine.py
Browse files- constraint_engine.py +0 -33
constraint_engine.py
CHANGED
|
@@ -37,7 +37,6 @@ class ConstraintEngine:
|
|
| 37 |
self._apply_stretch_constraints()
|
| 38 |
self._apply_grouping_constraints()
|
| 39 |
self._apply_daily_subject_limit()
|
| 40 |
-
self._apply_no_first_hour_free()
|
| 41 |
|
| 42 |
def _create_task_variables(self):
|
| 43 |
for task in self.tasks:
|
|
@@ -315,35 +314,3 @@ class ConstraintEngine:
|
|
| 315 |
for lit in at_slot: self.model.AddImplication(is_active.Not(), lit.Not())
|
| 316 |
literals.append(is_active)
|
| 317 |
self.model.Add(sum(literals) <= self.max_continuous_stretch)
|
| 318 |
-
|
| 319 |
-
def _apply_no_first_hour_free(self):
|
| 320 |
-
"""
|
| 321 |
-
HARD CONSTRAINT:
|
| 322 |
-
Ensures that the first hour (slot 0) of every day is never free for any section.
|
| 323 |
-
Every section must have at least one class starting at slot 0 every day.
|
| 324 |
-
"""
|
| 325 |
-
from collections import defaultdict
|
| 326 |
-
import constants as const
|
| 327 |
-
|
| 328 |
-
tasks_by_sec = defaultdict(list)
|
| 329 |
-
for task in self.tasks:
|
| 330 |
-
tasks_by_sec[task.section.section_id].append(task)
|
| 331 |
-
|
| 332 |
-
for sec_id, sec_tasks in tasks_by_sec.items():
|
| 333 |
-
if not sec_tasks: continue
|
| 334 |
-
|
| 335 |
-
for day in range(const.NUM_WORKING_DAYS):
|
| 336 |
-
first_slot = day * const.NUM_TEACHING_SLOTS_PER_DAY
|
| 337 |
-
|
| 338 |
-
starts_at_first = []
|
| 339 |
-
for task in sec_tasks:
|
| 340 |
-
start_var = self.task_vars[task.task_id][0]
|
| 341 |
-
# We create a boolean variable that is True if start_var == first_slot
|
| 342 |
-
at_first = self.model.NewBoolVar(f"hard_at1st_{task.task_id}_d{day}")
|
| 343 |
-
self.model.Add(start_var == first_slot).OnlyEnforceIf(at_first)
|
| 344 |
-
self.model.Add(start_var != first_slot).OnlyEnforceIf(at_first.Not())
|
| 345 |
-
starts_at_first.append(at_first)
|
| 346 |
-
|
| 347 |
-
if starts_at_first:
|
| 348 |
-
# At least one task MUST start at the first slot
|
| 349 |
-
self.model.AddBoolOr(starts_at_first)
|
|
|
|
| 37 |
self._apply_stretch_constraints()
|
| 38 |
self._apply_grouping_constraints()
|
| 39 |
self._apply_daily_subject_limit()
|
|
|
|
| 40 |
|
| 41 |
def _create_task_variables(self):
|
| 42 |
for task in self.tasks:
|
|
|
|
| 314 |
for lit in at_slot: self.model.AddImplication(is_active.Not(), lit.Not())
|
| 315 |
literals.append(is_active)
|
| 316 |
self.model.Add(sum(literals) <= self.max_continuous_stretch)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|