-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathinstance.py
98 lines (76 loc) · 3.75 KB
/
instance.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
from helper_classes.constants import *
from math import ceil
from helper_classes.nurse import *
from helper_classes.skills import *
from helper_classes.contract import Contract
class Instance():
def __init__(self, nurses, shifts, contracts, skills, shift_types, scheduling_period, cover_request_matrix,
day_request_matrix, shift_request_matrix):
self.nurses = nurses
self.shifts = shifts
self.contracts = contracts
self.skills = skills
self.shift_types = shift_types # set of possible shift types
self.scheduling_period = scheduling_period # ie, number of days per period
self.cover_request_matrix = cover_request_matrix
self.day_request_matrix = day_request_matrix
self.shift_request_matrix = shift_request_matrix
@classmethod
def create_test_instance(self):
# create 10 nurses, including 2 NOs
nurses = []
for i in range(8):
nurses.append(Nurse(id, contract=Contract(), last_name=str.format('Mansa{}',i), other_names=str.format('{}Yaa',i), skills=[NurseSkill]))
for i in range(2):
nurses.append(Nurse(id, contract=Contract(), last_name=str.format('Baako{}',i), other_names=str.format('{}Ama',i), skills=[NurseSkill, NursingOfficerSkill]))
contracts = []
skills = [NurseSkill, NursingOfficerSkill]
shift_types = ['morning', 'afternoon', 'night']
scheduling_period = N_DAYS
cover_request_matrix = []
day_request_matrix = []
shift_request_matrix = []
# create weighted shifts
shifts = []
for i in range(N_ALLOCATIONS):
is_morning_shift = i % 3 == 0
is_afternoon_shift = i % 3 == 1
is_night_shift = i % 3 == 2
is_weekend = i % 21 in [15,16,17,18,19,20]
shift = 'morning' if is_morning_shift else 'afternoon' if is_afternoon_shift else 'night'
nurses_required = 5 if is_morning_shift else 3 if is_afternoon_shift else 2
weight = 0
# different nurse requirements for weekend shifts
if is_weekend:
nurses_required = 3 if is_morning_shift else 2 if is_afternoon_shift else 1
# skills_required specify the minimum number required for the shift
# Aside that, all base nurses count toward the total staff requirement
skills_required = [
SkillRequired(NurseSkill, nurses_required, COST_NURSE_REQ)
]
if is_night_shift:
# require one qualified nursing officer on night shifts
skills_required.append(SkillRequired(NursingOfficerSkill, 1, COST_NURSING_OFFICER_REQ))
weight += NIGHT_SHIFT_WEIGHT
n_valid_nurses = count_skills(nurses, skills_required)
n_nurses = len(nurses)
# add weight to this new requirement
extra_weight = (n_nurses/n_valid_nurses) * SKILL_WEIGHT
weight += extra_weight
if is_weekend:
weight += WEEKEND_SHIFT_WEIGHT
# add more weight to shifts the later they occur
days_to_end_of_period = ceil((N_ALLOCATIONS - i) / N_SHIFTS)
weight += SHIFT_DATE_WEIGHT * days_to_end_of_period
multiplier = 1
shifts.append(Shift(
index=i,
shift_type=shift,
skills_required=skills_required,
n_nurses_required=nurses_required,
weight=weight,
evaluation_multiplier=multiplier
))
return Instance(nurses, shifts, contracts, skills,
shift_types, scheduling_period, cover_request_matrix,
day_request_matrix, shift_request_matrix)