From 9387156371c7f9bb01887032a968101e51a61acd Mon Sep 17 00:00:00 2001 From: Christophe Lecoutre Date: Sat, 16 Mar 2024 18:04:01 +0100 Subject: [PATCH] Minor Refactoring of a few models --- realistic/OncallRostering/OncallRostering.py | 10 ++++++++-- realistic/OpenShop/OpenShop.py | 4 ++-- realistic/OpenStacks/OpenStacks.py | 12 ++++++++++-- realistic/OpenStacks/OpenStacks_z.py | 10 ++++++---- .../PhysicianSchedule/PhysicianSchedule.py | 17 +++++++++-------- 5 files changed, 35 insertions(+), 18 deletions(-) diff --git a/realistic/OncallRostering/OncallRostering.py b/realistic/OncallRostering/OncallRostering.py index 5ffebca7..e1dbe50c 100644 --- a/realistic/OncallRostering/OncallRostering.py +++ b/realistic/OncallRostering/OncallRostering.py @@ -61,10 +61,16 @@ [x[i] != j for j in range(nWorkers) for i in unavailableDays[j]], # counting working (regular) days by each worker - Cardinality([x[i] for i in range(nDays) if i not in weekends], occurrences=do), + Cardinality( + [x[i] for i in range(nDays) if i not in weekends], + occurrences=do + ), # counting working weekends by each worker - Cardinality(x[weekends], occurrences=wo), + Cardinality( + x[weekends], + occurrences=wo + ), # computing the balance violation wrt working days [abs(workloads[j2] * do[j1] - workloads[j1] * do[j2]) <= 100 * db for j1, j2 in combinations(nWorkers, 2)], diff --git a/realistic/OpenShop/OpenShop.py b/realistic/OpenShop/OpenShop.py index cf49a9dd..c9cd2e44 100644 --- a/realistic/OpenShop/OpenShop.py +++ b/realistic/OpenShop/OpenShop.py @@ -64,14 +64,14 @@ # tasks on the same job cannot overlap [ Cumulative( - tasks=[(x[i][j], durations[i][j], 1) for j in range(nMachines)] + tasks=[Task(origin=x[i][j], length=durations[i][j], height=1) for j in range(nMachines)] ) <= 1 for i in range(nJobs) ], # tasks on the same machine cannot overlap [ Cumulative( - tasks=[(x[i][j], durations[i][j], 1) for i in range(nJobs)] + tasks=[Task(origin=x[i][j], length=durations[i][j], height=1) for i in range(nJobs)] ) <= 1 for j in range(nMachines) ], diff --git a/realistic/OpenStacks/OpenStacks.py b/realistic/OpenStacks/OpenStacks.py index bffd9cef..d6c6ed9c 100644 --- a/realistic/OpenStacks/OpenStacks.py +++ b/realistic/OpenStacks/OpenStacks.py @@ -80,10 +80,18 @@ def table2(t): AllDifferent(p), # computing starting times of stacks - [Minimum(p[j] for j in range(m) if orders[i][j]) == s[i] for i in range(n)], + [ + s[i] == Minimum( + p[j] for j in range(m) if orders[i][j] + ) for i in range(n) + ], # computing ending times of stacks - [Maximum(p[j] for j in range(m) if orders[i][j]) == e[i] for i in range(n)], + [ + e[i] == Maximum( + p[j] for j in range(m) if orders[i][j] + ) for i in range(n) + ], # inferring when stacks are open [(s[i], e[i], o[i][t]) in table2(t) for i in range(n) for t in range(m)], diff --git a/realistic/OpenStacks/OpenStacks_z.py b/realistic/OpenStacks/OpenStacks_z.py index ccb2d0a4..cea92946 100644 --- a/realistic/OpenStacks/OpenStacks_z.py +++ b/realistic/OpenStacks/OpenStacks_z.py @@ -46,9 +46,11 @@ minimize( Maximum( - Sum(both( - y[i][j - 1] < quantities[i], - y[i][j] > 0 - ) for i in range(nCustomers)) for j in range(1, nProducts + 1) + Sum( + both( + y[i][j - 1] < quantities[i], + y[i][j] > 0 + ) for i in range(nCustomers) + ) for j in range(1, nProducts + 1) ) ) diff --git a/realistic/PhysicianSchedule/PhysicianSchedule.py b/realistic/PhysicianSchedule/PhysicianSchedule.py index 6081ce17..5a7e044d 100644 --- a/realistic/PhysicianSchedule/PhysicianSchedule.py +++ b/realistic/PhysicianSchedule/PhysicianSchedule.py @@ -34,9 +34,10 @@ OFF = 0 sf = lambda t: sum(flatten(t)) # summing after flattening the argument array -sums0, sumsub = [nPersons - sf(demands[1:, 1:, d, 1:]) for d in range(nDays)], [sum(subDemand[:, d]) for d in range(nDays)] +sums0 = [nPersons - sf(demands[1:, 1:, d, 1:]) for d in range(nDays)] # below, expected number of occurrences -Osh = [[sums0[d]] + [sf(demands[1:, s, d, 1:]) + sumsub[d] * (-1 if s == 1 else 1 if s == 2 else 0) for s in range(1, nShifts)] for d in range(nDays)] +Osh = [[sums0[d]] + [sf(demands[1:, s, d, 1:]) + sum(subDemand[:, d]) * (-1 if s == 1 else 1 if s == 2 else 0) for s in range(1, nShifts)] for d in + range(nDays)] Ost = [[sums0[d]] + [sf(demands[s, 1:, d, 1:]) for s in range(1, nStations)] for d in range(nDays)] Osk = [[sums0[d]] + [sf(demands[1:, 1:, d, s]) for s in range(1, nSkills)] for d in range(nDays)] assert all(len(t) == nShifts for t in Osh) and all(len(t) == nStations for t in Ost) and all(len(t) == nSkills for t in Osk) @@ -96,35 +97,35 @@ # shifts 1 and 2: individual assignments on common stations [ - Sum( + demands[v1][v2][j][v3] == Sum( conjunction( st[i][j] == v1, sh[i][j] == v2, sk[i][j] == v3 ) for i in range(nPersons) - ) == demands[v1][v2][j][v3] for v1 in range(1, nStations) if commons[v1] == 1 for v2 in (1, 2) for j in range(nDays) for v3 in range(1, nSkills) + ) for v1 in range(1, nStations) if commons[v1] == 1 for v2 in (1, 2) for j in range(nDays) for v3 in range(1, nSkills) ], # shift 1 may be subsumed by shift 2 on non-common stations [ - Sum( + demands[v1][1][j][v3] == Sum( conjunction( st[i][j] == v1, sh[i][j] in {1, 2}, sk[i][j] == v3 ) for i in range(nPersons) - ) == demands[v1][1][j][v3] for v1 in range(1, nStations) if commons[v1] == 0 for j in range(nDays) for v3 in range(1, nSkills) + ) for v1 in range(1, nStations) if commons[v1] == 0 for j in range(nDays) for v3 in range(1, nSkills) ], # shifts 3+: regular assignments [ - Sum( + demands[v1][v2][j][v3] == Sum( conjunction( st[i][j] == v1, sh[i][j] == v2, sk[i][j] == v3 ) for i in range(nPersons) - ) == demands[v1][v2][j][v3] for v1 in range(1, nStations) for v2 in range(3, nShifts) for j in range(nDays) for v3 in range(1, nSkills) + ) for v1 in range(1, nStations) for v2 in range(3, nShifts) for j in range(nDays) for v3 in range(1, nSkills) ], # tag(redundant-constraints)