Skip to content

Commit 73d0d4a

Browse files
committed
Added description and changed code slightly
1 parent c1d850c commit 73d0d4a

File tree

1 file changed

+31
-17
lines changed

1 file changed

+31
-17
lines changed
Lines changed: 31 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,22 @@
1+
"""
2+
This example shows how one can optimize a model with categorical data by converting it into integers.
3+
4+
There are three employees (Alice, Bob, Charlie) and three shifts. Each shift is assigned an integer:
5+
6+
Morning - 0
7+
Afternoon - 1
8+
Night - 2
9+
10+
The employees have availabilities (e.g. Alice can only work in the Morning and Afternoon), and different
11+
salary demands. These constraints, and an additional one stipulating that every shift must be covered,
12+
allows us to model a MIP with the objective of minimizing the money spent on salary.
13+
"""
14+
115
from pyscipopt import Model
216

317
# Define categorical data
4-
shifts = {"Morning": 0, "Afternoon": 1, "Night": 2}
5-
employees = ["Alice", "Bob", "Charlie"]
6-
7-
# Employees have different salary demands
8-
cost = {
9-
"Alice": [2,4,1],
10-
"Bob": [3,2,7],
11-
"Charlie": [3,3,3]
12-
}
18+
shift_to_int = {"Morning": 0, "Afternoon": 1, "Night": 2}
19+
employees = ["Alice", "Bob", "Charlie"]
1320

1421
# Employee availability
1522
availability = {
@@ -19,9 +26,16 @@
1926
}
2027

2128
# Transform availability into integer values
22-
availability_int = {
23-
emp: [shifts[shift] for shift in available_shifts]
24-
for emp, available_shifts in availability.items()
29+
availability_int = {}
30+
for emp, available_shifts in availability.items():
31+
availability_int[emp] = [shift_to_int[shift] for shift in available_shifts]
32+
33+
34+
# Employees have different salary demands
35+
cost = {
36+
"Alice": [2,4,1],
37+
"Bob": [3,2,7],
38+
"Charlie": [3,3,3]
2539
}
2640

2741
# Create the model
@@ -30,22 +44,22 @@
3044
# x[e, s] = 1 if employee e is assigned to shift s
3145
x = {}
3246
for e in employees:
33-
for s in shifts.values():
47+
for s in shift_to_int.values():
3448
x[e, s] = model.addVar(vtype="B", name=f"x({e},{s})")
3549

3650
# Each shift must be assigned to exactly one employee
37-
for s in shifts.values():
51+
for s in shift_to_int.values():
3852
model.addCons(sum(x[e, s] for e in employees) == 1)
3953

4054
# Employees can only work shifts they are available for
4155
for e in employees:
42-
for s in shifts.values():
56+
for s in shift_to_int.values():
4357
if s not in availability_int[e]:
4458
model.addCons(x[e, s] == 0)
4559

4660
# Minimize shift assignment cost
4761
model.setObjective(
48-
sum(cost[e][s]*x[e, s] for e in employees for s in shifts.values()), "minimize"
62+
sum(cost[e][s]*x[e, s] for e in employees for s in shift_to_int.values()), "minimize"
4963
)
5064

5165
# Solve the problem
@@ -54,6 +68,6 @@
5468
# Display the results
5569
print("\nOptimal Shift Assignment:")
5670
for e in employees:
57-
for s, s_id in shifts.items():
71+
for s, s_id in shift_to_int.items():
5872
if model.getVal(x[e, s_id]) > 0.5:
5973
print("%s is assigned to %s" % (e, s))

0 commit comments

Comments
 (0)