This commit is contained in:
Ross
2022-01-30 21:23:58 +00:00
parent dcb79a30c2
commit cbe99ea3d8
4 changed files with 217 additions and 74 deletions
+160 -22
View File
@@ -23,8 +23,6 @@ class TestDemoRota:
Rota.constraint_options["max_shifts_per_week"] = 5
Rota.constraint_options["max_shifts_per_month"] = 31
Rota.constraint_options["ensure_derriford_reg_for_nights"] = False
Rota.constraint_options["limit_to_1_st2_on_nights"] = False
Rota.constraint_options["ensure_1_st4_plus_on_nights"] = False
Rota.constraint_options["constrain_time_off_after_nights"] = False
Rota.constraint_options["balance_nights_across_site"] = False
Rota.constraint_options["balance_shifts"] = True
@@ -190,7 +188,6 @@ class TestDemoRotaNights:
Rota.constraint_options["max_shifts_per_month"] = 31
Rota.constraint_options["ensure_derriford_reg_for_nights"] = False
Rota.constraint_options["limit_to_1_st2_on_nights"] = False
Rota.constraint_options["ensure_1_st4_plus_on_nights"] = False
Rota.constraint_options["constrain_time_off_after_nights"] = False
Rota.constraint_options["balance_nights_across_site"] = False
Rota.constraint_options["balance_shifts"] = True
@@ -292,18 +289,8 @@ class TestDemoRotaClear:
balance_offset_modifier=1,
max_weekend_frequency=1,
)
#Rota.constraint_options["max_shifts_per_week"] = 5
Rota.constraint_options["max_shifts_per_month"] = 20
#Rota.constraint_options["ensure_derriford_reg_for_nights"] = False
#Rota.constraint_options["limit_to_1_st2_on_nights"] = False
#Rota.constraint_options["ensure_1_st4_plus_on_nights"] = False
#Rota.constraint_options["constrain_time_off_after_nights"] = False
#Rota.constraint_options["balance_nights_across_site"] = False
#Rota.constraint_options["balance_shifts"] = True
#Rota.constraint_options["balance_shifts_over_workers"] = True
#Rota.constraint_options["balance_nights"] = False
#Rota.constraint_options["minimise_shift_diffs"] = False
#Rota.constraint_options["balance_blocks"] = False
worker1 = Worker(Rota, "worker1", "group1", 1)
worker2 = Worker(Rota, "worker2", "group1", 1)
@@ -549,12 +536,12 @@ class TestLimitConstraints:
)
#Rota.constraint_options["max_shifts_per_week"] = 5
#Rota.constraint_options["max_shifts_per_month"] = 20
worker1 = Worker(Rota, "worker1", "group1", 2)
worker2 = Worker(Rota, "worker2", "group1", 2)
worker3 = Worker(Rota, "worker3", "group1", 2)
worker4 = Worker(Rota, "worker4", "group3", 3)
worker5 = Worker(Rota, "worker5", "group3", 3)
worker6 = Worker(Rota, "worker6", "group3", 3)
worker1 = Worker(Rota, "worker1", "group1", 2, home_site="group1")
worker2 = Worker(Rota, "worker2", "group1", 2, home_site="group1")
worker3 = Worker(Rota, "worker3", "group1", 2, home_site="group1")
worker4 = Worker(Rota, "worker4", "group3", 3, home_site="group2")
worker5 = Worker(Rota, "worker5", "group3", 3, home_site="group2")
worker6 = Worker(Rota, "worker6", "group3", 3, home_site="group2")
Rota.add_workers((worker1, worker2, worker3, worker4))
Rota.add_workers((worker5, worker6))
@@ -673,9 +660,160 @@ class TestLimitConstraints:
self.Rota.constraint_options["balance_shifts_quadratic"] = True
self.Rota.build_and_solve(options={"ratio": 0.1})
assert self.Rota.results.solver.termination_condition == "infeasible"
def test_constraint_minimum_grades(self):
self.Rota.shifts = []
self.Rota.add_shifts(
SingleShift(("group1", "group2", "group3"), "weekday_night", 12.5, days, balance_offset=40,
workers_required=1,
force_as_block=True,
constraints=[("minimum_grade_number", (3, 1))]
),
)
self.Rota.constraint_options["balance_shifts_quadratic"] = True
self.Rota.build_and_solve(options={"ratio": 0.1})
self.Rota.export_rota_to_html("test9")
assert self.Rota.results.solver.termination_condition == "infeasible"
grade_workers = self.Rota.get_workers_by_grade()
for grade in grade_workers:
shift_patterns = []
for w in grade_workers[grade]:
shift_patterns.append(self.Rota.get_worker_shift_list(w))
zipped_lists = list(zip(*shift_patterns))
limit = 0
if grade > 2:
limit = 1
for day_shifts in zipped_lists:
assert day_shifts.count("weekday_night") == limit
assert self.Rota.results.solver.status == "ok"
def test_constraint_minimum_grades2(self):
self.Rota.shifts = []
self.Rota.add_shifts(
SingleShift(("group1", "group2", "group3"), "weekday_night", 12.5, days, balance_offset=40,
workers_required=4,
force_as_block=True,
constraints=[("minimum_grade_number", (3, 3))]
),
)
self.Rota.constraint_options["balance_shifts_quadratic"] = True
self.Rota.build_and_solve(options={"ratio": 0.1})
self.Rota.export_rota_to_html("test9")
grade_workers = self.Rota.get_workers_by_grade()
for grade in grade_workers:
shift_patterns = []
for w in grade_workers[grade]:
shift_patterns.append(self.Rota.get_worker_shift_list(w))
zipped_lists = list(zip(*shift_patterns))
limit = 1
if grade > 2:
limit = 3
for day_shifts in zipped_lists:
assert day_shifts.count("weekday_night") == limit
assert self.Rota.results.solver.status == "ok"
def test_constraint_minimum_grades3(self):
self.Rota.shifts = []
self.Rota.add_shifts(
SingleShift(("group1", "group2", "group3"), "weekday_night", 12.5, days, balance_offset=40,
workers_required=4,
force_as_block=True,
constraints=[("minimum_grade_number", (3, 0))]
),
)
self.Rota.constraint_options["balance_shifts_quadratic"] = True
self.Rota.build_and_solve(options={"ratio": 0.1})
self.Rota.export_rota_to_html("test9")
assert self.Rota.results.solver.status == "ok"
def test_constraint_minimum_grades_no_valid_worker(self):
self.Rota.shifts = []
self.Rota.add_shifts(
SingleShift(("group1", "group2", "group3"), "weekday_night", 12.5, days, balance_offset=40,
workers_required=4,
force_as_block=True,
constraints=[("minimum_grade_number", (4, 1))]
),
)
self.Rota.constraint_options["balance_shifts_quadratic"] = True
with pytest.raises(ValueError):
self.Rota.build_and_solve(options={"ratio": 0.1})
def test_constraint_require_home_site_presence(self):
self.Rota.shifts = []
self.Rota.add_shifts(
SingleShift(("group1", "group2", "group3"), "weekday_night", 12.5, days, balance_offset=40,
workers_required=2,
force_as_block=True,
constraints=[("require_home_site_presence", ("group1", 2))]
),
)
self.Rota.build_and_solve(options={"ratio": 0.00})
self.Rota.export_rota_to_html("test9")
group_workers = self.Rota.get_workers_by_group()
for group in group_workers:
shift_patterns = []
for w in group_workers[group]:
shift_patterns.append(self.Rota.get_worker_shift_list(w))
zipped_lists = list(zip(*shift_patterns))
limit = 2
if group != "group1":
limit = 0
for day_shifts in zipped_lists:
assert day_shifts.count("weekday_night") == limit
assert self.Rota.results.solver.status == "ok"
assert self.Rota.results.solver.termination_condition == "optimal"
def test_constraint_require_home_site_presence2(self):
self.Rota.shifts = []
self.Rota.add_shifts(
SingleShift(("group1", "group2", "group3"), "weekday_night", 12.5, days, balance_offset=40,
workers_required=3,
force_as_block=True,
constraints=[("require_home_site_presence", ("group2", 2))]
),
)
self.Rota.build_and_solve(options={"ratio": 0.00})
self.Rota.export_rota_to_html("test9")
group_workers = self.Rota.get_workers_by_group()
for group in group_workers:
shift_patterns = []
for w in group_workers[group]:
shift_patterns.append(self.Rota.get_worker_shift_list(w))
zipped_lists = list(zip(*shift_patterns))
if group == "group2":
for day_shifts in zipped_lists:
assert day_shifts.count("weekday_night") >= 2
assert self.Rota.results.solver.status == "ok"
assert self.Rota.results.solver.termination_condition == "optimal"
#class TestNoWorkerRota:
# weeks_to_rota = 10
@@ -693,4 +831,4 @@ class TestLimitConstraints:
if __name__ == "__main__":
t = TestLimitConstraints()
t.test_constraint_limit_grades4()
t.test_constraint_require_home_site_presence()