update for new run

This commit is contained in:
Ross
2023-01-16 16:28:57 +00:00
parent 7ef0c191d7
commit aaa10d5fb8
3 changed files with 56 additions and 31 deletions
+39 -17
View File
@@ -27,24 +27,24 @@ from rota.workers import (
suspend_on_finish = True suspend_on_finish = True
solve = True solve = True
time_to_run = 258500 time_to_run = 458500
#time_to_run = 2660000 #time_to_run = 2660000
#time_to_run = 458500 #time_to_run = 458500
# allow = 5000 # allow = 5000
ratio = 0.001 ratio = 0.05
#ratio = 0.9 #ratio = 0.9
start_date = datetime.date(2022, 9, 5) start_date = datetime.date(2023, 3, 6)
#start_date = start_date + datetime.timedelta(weeks=13) #start_date = start_date + datetime.timedelta(weeks=13)
# start_date = datetime.date(2022, 10, 10) # start_date = datetime.date(2022, 10, 10)
Rota = RotaBuilder(start_date, weeks_to_rota=26) Rota = RotaBuilder(start_date, weeks_to_rota=26, balance_offset_modifier=1)
Rota.constraint_options["balance_weekends"] = True Rota.constraint_options["balance_weekends"] = True
Rota.constraint_options["max_night_frequency"] = 3 Rota.constraint_options["max_night_frequency"] = 3 # 3
Rota.constraint_options["max_night_frequency_week_exclusions"] = [1,2,3,4,5,6] Rota.constraint_options["max_night_frequency_week_exclusions"] = []
Rota.constraint_options["max_weekend_frequency"] = 2 Rota.constraint_options["max_weekend_frequency"] = 2
Rota.constraint_options["hard_constrain_pair_separation"] = True Rota.constraint_options["hard_constrain_pair_separation"] = False
# Rota.constraint_options["avoid_st2_first_month"] = True # Rota.constraint_options["avoid_st2_first_month"] = True
Rota.add_shifts( Rota.add_shifts(
@@ -57,7 +57,7 @@ Rota.add_shifts(
constraint=[ constraint=[
{ {
"name": "max_shifts_per_week", "name": "max_shifts_per_week",
"options": 2, "options": 1,
} }
], ],
), ),
@@ -152,7 +152,7 @@ Rota.add_shifts(
bank_holidays_only=True, bank_holidays_only=True,
), ),
SingleShift( SingleShift(
sites=(sites), sites=sites,
name="night_weekday", name="night_weekday",
length=12.25, length=12.25,
days=days[:4], days=days[:4],
@@ -193,11 +193,11 @@ Rota.add_shifts(
), ),
) )
Rota.add_grade_constraint_by_week([2], [1, 2], ["night_weekday", "night_weekend"]) #Rota.add_grade_constraint_by_week([2], [1, 2], ["night_weekday", "night_weekend"])
load_leave = True load_leave = True
Rota.build_shifts() Rota.build_shifts()
Rota.add_grade_constraint_by_week([2], [1], Rota.get_shift_names()) #Rota.add_grade_constraint_by_week([2], [1], Rota.get_shift_names())
if load_leave: if load_leave:
import leave import leave
@@ -211,7 +211,12 @@ if load_leave:
w = workers[worker] w = workers[worker]
site = w["site"] site = w["site"]
grade = w["grade"] grade = w["grade"]
try:
fte = float(w["fte"]) * 100 fte = float(w["fte"]) * 100
except ValueError:
print(f"{worker} has invalid fte: {fte}")
raise ValueError
nwd = w["nwd"] nwd = w["nwd"]
end_date = w["end_date"] end_date = w["end_date"]
start_date = w["start_date"] start_date = w["start_date"]
@@ -244,7 +249,21 @@ if load_leave:
) )
# nwds = [i.strip()[:3].capitalize() for i in nwd.split("/")] if nwd else None # nwds = [i.strip()[:3].capitalize() for i in nwd.split("/")] if nwd else None
end_date = end_date if end_date else None end_date = end_date if end_date else None
oop = oop.split("-") if oop else None
if oop:
formatted_oops = []
for dates in oop.split(","):
s, e = dates.split("-")
formatted_oops.append(
{"start_date": datetime.datetime.strptime(s, "%d/%m/%y").date(), "end_date": datetime.datetime.strptime(e, "%d/%m/%y").date()}
)
oop = formatted_oops
else:
oop = []
print(f"{worker} OOP {oop}")
previous_shifts = {} previous_shifts = {}
# if twi: # if twi:
@@ -276,8 +295,7 @@ if load_leave:
work_requests = w["requests"] work_requests = w["requests"]
site_pref = w["site_pref"] site_pref = w["site_pref"]
Rota.add_worker( w = Worker(
Worker(
name=worker_name, name=worker_name,
site=site.lower(), site=site.lower(),
grade=int(grade[2]), grade=int(grade[2]),
@@ -286,7 +304,7 @@ if load_leave:
nwds=nwds, nwds=nwds,
start_date=start_date, start_date=start_date,
end_date=end_date, end_date=end_date,
opp=oop, oop=oop,
not_available_to_work=leave_requests, not_available_to_work=leave_requests,
work_requests=work_requests, work_requests=work_requests,
remote_site=site_pref, remote_site=site_pref,
@@ -295,12 +313,16 @@ if load_leave:
shift_balance_extra=w["shift_balance_extra"], shift_balance_extra=w["shift_balance_extra"],
bank_holiday_extra=w["bank_holiday_extra"], bank_holiday_extra=w["bank_holiday_extra"],
) )
)
print(w)
Rota.add_worker(w)
# Rota.build_workers() # Rota.build_workers()
# Rota.build_model() # Rota.build_model()
solver_options = {"ratio": ratio, "seconds": time_to_run, "threads": 11} solver_options = {"ratio": ratio, "seconds": time_to_run, "threads": 10}
start_time = time.time() start_time = time.time()
Rota.build_and_solve(solver_options) Rota.build_and_solve(solver_options)
+2 -2
View File
@@ -16,7 +16,7 @@ def load_leave(Rota):
workers = {} workers = {}
download = s.get("https://docs.google.com/spreadsheets/d/e/2PACX-1vS49eVS0f86wUJIhXMq7tMPZfAEJZatER09JLu0xnlTjDBkC-54DkAPT3I0JVXDQXNG6AIh_fVeIRS3/pub?gid=0&single=true&output=csv") download = s.get("https://docs.google.com/spreadsheets/d/e/2PACX-1vR18crGluN4wrL9n1sBdZ2u-JsvaLtQ6hr-R5CPUBOaKpL7_hBbhemyPSrFOhDuWxKlrjh-QUM0HrcD/pub?gid=0&single=true&output=csv")
decoded_content = download.content.decode('utf-8') decoded_content = download.content.decode('utf-8')
reader = csv.reader(decoded_content.splitlines(), delimiter=',') reader = csv.reader(decoded_content.splitlines(), delimiter=',')
@@ -100,7 +100,7 @@ def load_leave(Rota):
elif row_title == "Pair": elif row_title == "Pair":
if lower_item == "": if lower_item == "":
worker["pair"] = 0 worker["pair"] = None
else: else:
worker["pair"] = int(lower_item) worker["pair"] = int(lower_item)
+14 -11
View File
@@ -121,6 +121,7 @@ class Worker(BaseModel):
if self.name == "Steph bailey": if self.name == "Steph bailey":
print(self.start_date, self.end_date) print(self.start_date, self.end_date)
print(self.oop)
# if no start date default to the start of the rota # if no start date default to the start of the rota
if self.start_date is None: if self.start_date is None:
@@ -187,6 +188,7 @@ class Worker(BaseModel):
start_oop_date = Rota.start_date start_oop_date = Rota.start_date
oop_length = (end_oop_date - start_oop_date).days oop_length = (end_oop_date - start_oop_date).days
print(f"oop length {oop_length}")
days_to_work = days_to_work - oop_length days_to_work = days_to_work - oop_length
days_until_oop = (start_oop_date - Rota.start_date).days days_until_oop = (start_oop_date - Rota.start_date).days
@@ -280,18 +282,19 @@ class Worker(BaseModel):
) )
def __str__(self) -> str: def __str__(self) -> str:
return f"{self.name}, {self.site}, {self.oop}"
nwds = ( #nwds = (
", ".join([str(i) for i, start, end in self.non_working_day_list]) # ", ".join([str(i) for i, start, end in self.non_working_day_list])
if self.non_working_day_list is not None # if self.non_working_day_list is not None
else "" # else ""
) #)
return "{} {} [{}] REMOTE SITE:{}".format( #return "{} {} [{}] REMOTE SITE:{}".format(
self.name, # self.name,
(self.site, self.grade, self.fte_adj), # (self.site, self.grade, self.fte_adj),
nwds, # nwds,
self.remote_site, # self.remote_site,
) #)
def get_details(self) -> str: def get_details(self) -> str:
return "{} {} {}".format(self.id, self.site[0], self.grade) return "{} {} {}".format(self.id, self.site[0], self.grade)