22from enum import Enum
33from typing import Dict , List
44import sys
5+ import numpy as np #to build and mnaiplate our sadness grid
6+ from scipy .optimize import linear_sum_assignment #to find optimal laptop allocaation to minimize sadness across all users
57
68class OperatingSystem (Enum ):
79 MACOS = "macOS"
@@ -37,13 +39,13 @@ class Laptop:
3739]
3840# Preset dataset of people
3941people = [
40- Person (name = "Sara" , age = 31 , preferred_operating_system = [OperatingSystem .ARCH ,OperatingSystem .UBUNTU ]),
41- Person (name = "Shabs" , age = 40 , preferred_operating_system = [OperatingSystem .ARCH ,OperatingSystem .MACOS ,OperatingSystem .UBUNTU ]),
42- Person (name = "Jawad" , age = 36 , preferred_operating_system = [OperatingSystem .MACOS ,OperatingSystem .UBUNTU ,OperatingSystem .ARCH ]),
43- Person (name = "Mike" , age = 35 , preferred_operating_system = [OperatingSystem .MACOS ,OperatingSystem .ARCH ]),
44- Person (name = "Mawra" , age = 28 , preferred_operating_system = [OperatingSystem .MACOS ]),
45- Person (name = "Fatma" , age = 22 , preferred_operating_system = [OperatingSystem .UBUNTU ,OperatingSystem .ARCH ]),
46- Person (name = "Muhib" , age = 19 , preferred_operating_system = [OperatingSystem .MACOS ,OperatingSystem .UBUNTU ]),
42+ Person (name = "Sara" , age = 31 , preferred_operating_systems = [OperatingSystem .ARCH ,OperatingSystem .UBUNTU ]),
43+ Person (name = "Shabs" , age = 40 , preferred_operating_systems = [OperatingSystem .ARCH ,OperatingSystem .MACOS ,OperatingSystem .UBUNTU ]),
44+ Person (name = "Jawad" , age = 36 , preferred_operating_systems = [OperatingSystem .MACOS ,OperatingSystem .UBUNTU ,OperatingSystem .ARCH ]),
45+ Person (name = "Mike" , age = 35 , preferred_operating_systems = [OperatingSystem .MACOS ,OperatingSystem .ARCH ]),
46+ Person (name = "Mawra" , age = 28 , preferred_operating_systems = [OperatingSystem .MACOS ]),
47+ Person (name = "Fatma" , age = 22 , preferred_operating_systems = [OperatingSystem .UBUNTU ,OperatingSystem .ARCH ]),
48+ Person (name = "Muhib" , age = 19 , preferred_operating_systems = [OperatingSystem .MACOS ,OperatingSystem .UBUNTU ]),
4749
4850]
4951
@@ -57,7 +59,29 @@ def sadness(person: Person, laptop: Laptop) -> int:
5759 else :
5860 return 100
5961
60- #There are two approaches to solve this
61- #Greedy approach or Hungarian Algorithm Approach
62+ #I have chose to use Hungarian Algorithm Approach to solve the problem.
6263
63- #def allocate_laptops(people: List[Person], laptops: List[Laptop]) -> Dict[Person, Laptop]:
64+ def allocate_laptops (people : List [Person ], laptops : List [Laptop ]) -> Dict [Person , Laptop ]:
65+ n_people = len (people ) #length of people []
66+ n_laptops = len (laptops ) #length of laptops []
67+ if n_laptops < n_people :
68+ raise ValueError ("Not enough laptops to allocate one to each person." )
69+ sadness_matrix = np .zeros ((n_people , n_laptops ), dtype = int ) #npzero mean each cell in 2d grid is a zero and dtype is datatype int so it int 0
70+ for i , person in enumerate (people ): #enumerate gives us both index position and the item itself from the list
71+ for j , laptop in enumerate (laptops ):
72+ sadness_matrix [i ,j ] = sadness (person , laptop ) #this matrix represents complete laptop allocation
73+ # Hungarian algorithm to run on our sadness matrix
74+ row_indices , col_indices = linear_sum_assignment (sadness_matrix ) #which person which laptop
75+ # Map people to laptops
76+ allocation = {}
77+ for i , j in zip (row_indices , col_indices ):#it pairs up results (person indices and laptop indices). The loop then uses those pairs to build the final allocation dictionary
78+ allocation [people [i ].name ] = laptops [j ]
79+ return allocation
80+
81+
82+ def print_allocation (allocation : Dict [Person , Laptop ]):
83+ for name , lap in allocation .items ():
84+ print (f"{ name } gets Laptop { lap .id } ({ lap .operating_system .value } )" )
85+
86+ allocation = allocate_laptops (people , laptop )
87+ print_allocation (allocation )
0 commit comments