Skip to content

Commit cc37f86

Browse files
committed
Replace current laptop allocation with Hungarian algorithm
1 parent 7fc8382 commit cc37f86

File tree

1 file changed

+79
-26
lines changed

1 file changed

+79
-26
lines changed
Lines changed: 79 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
from dataclasses import dataclass
22
from enum import Enum
33
from typing import List, Dict
4-
from itertools import permutations
4+
5+
from scipy.optimize import linear_sum_assignment
6+
57

68

79
class OperatingSystem(Enum):
@@ -33,28 +35,79 @@ def sadness(person: Person, laptop: Laptop) ->int:
3335

3436

3537
def allocate_laptops(people: List[Person], laptops: List[Laptop]) -> Dict[Person, Laptop]:
36-
37-
best_scenario_assignment = None
38-
best_total_sadness = float("inf")
39-
40-
for scenario in permutations(laptops):
41-
total_sadness = 0
42-
43-
#find the sadness level for each scenario
44-
for person, laptop in zip(people, scenario):
45-
total_sadness += sadness(person, laptop)
46-
47-
#Implement early break if total is already worse than best
48-
if total_sadness >= best_total_sadness:
49-
break
50-
51-
# Check if this scenario is better
52-
if total_sadness < best_total_sadness:
53-
best_total_sadness = total_sadness
54-
best_scenario_assignment = scenario
55-
56-
57-
# Convert best_scenario_assignment into Dict[Person, Laptop]
58-
return {person: laptop for person, laptop in zip(people, best_scenario_assignment)}
59-
60-
38+
39+
if len(people) != len(laptops):
40+
raise ValueError("Number of individuals and laptops must be equal")
41+
42+
cost_matrix = [
43+
[sadness(person, laptop) for laptop in laptops]
44+
for person in people
45+
]
46+
47+
person_indices, laptop_indices = linear_sum_assignment(cost_matrix)
48+
49+
return {people[p_idx]: laptops[l_idx]
50+
for p_idx, l_idx in zip(person_indices, laptop_indices)
51+
52+
}
53+
54+
55+
56+
57+
58+
if __name__ == "__main__":
59+
people = [
60+
Person(
61+
name="Alice",
62+
age=30,
63+
preferred_operating_systems=[
64+
OperatingSystem.MACOS,
65+
OperatingSystem.UBUNTU,
66+
],
67+
),
68+
Person(
69+
name="Bob",
70+
age=25,
71+
preferred_operating_systems=[
72+
OperatingSystem.UBUNTU,
73+
OperatingSystem.MACOS,
74+
],
75+
),
76+
Person(
77+
name="Carol",
78+
age=28,
79+
preferred_operating_systems=[
80+
OperatingSystem.ARCH,
81+
OperatingSystem.MACOS,
82+
],
83+
),
84+
]
85+
86+
laptops = [
87+
Laptop(
88+
id=1,
89+
manufacturer="Apple",
90+
model="MacBook Air",
91+
screen_size_in_inches=13.3,
92+
operating_system=OperatingSystem.MACOS,
93+
),
94+
Laptop(
95+
id=2,
96+
manufacturer="Dell",
97+
model="XPS",
98+
screen_size_in_inches=13.0,
99+
operating_system=OperatingSystem.UBUNTU,
100+
),
101+
Laptop(
102+
id=3,
103+
manufacturer="Lenovo",
104+
model="ThinkPad",
105+
screen_size_in_inches=14.0,
106+
operating_system=OperatingSystem.ARCH,
107+
),
108+
]
109+
110+
allocation = allocate_laptops(people, laptops)
111+
112+
for person, laptop in allocation.items():
113+
print(f"{person.name}{laptop.model} ({laptop.operating_system.value})")

0 commit comments

Comments
 (0)