Repository navigation
London | 26-Jul-SDC | Alex Jamshidi | Sprint 5 | Implement laptop allocation #685
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
c62be7b
9d05e3c
c385378
306f422
4c9c603
f67da51
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| .venv |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,29 @@ | ||
| # Laptop Allocation Program | ||
|
|
||
| ## About | ||
| A program that assigns laptops to people based on a list of operating system preferences, it includes a simulation that can be re-run to simulate different scenarios. | ||
|
|
||
| ## Specification | ||
| Create a program that alllocate laptops to people based on a list of preferred operating systems. Every person should be allocated exactly one laptop. | ||
|
|
||
| If we define "sadness" as the number of places down in someone's ranking the operating system the ended up with (i.e. if your preferences were [UBUNTU, ARCH, MACOS] and you were allocated a MACOS machine your sadness would be 2), we want to minimise the total sadness of all people. If we allocate someone a laptop with an operating system not in their preferred list, treat them as having a sadness of 100. | ||
|
|
||
| ## To run code | ||
| python3 -m venv .venv | ||
| . .venv/bin/activate | ||
| pip install -r requirements.txt | ||
| python3 simulate.py | ||
|
|
||
| ## About Allocation | ||
| Allocation of laptops works using the Hungarian algorithm. | ||
| This is achieved using the linear_sum_assignment function in scipy which acts on a cost matrix constructed from the possible combinations between each person and laptop. | ||
|
|
||
| ## About Simulation | ||
| To test the code for different scenarios, a simulation was created, which simulates: | ||
| - A random laptop to person ratio between 0.5 and 2 | ||
| - A random number of people between 10 and 100 | ||
| - Therefore a theoretical random number of laptops between 5 and 200 | ||
| - Random percentage chances a person will be created with 1, 2 or 3 preferred operating systems (randomly assigned) | ||
|
|
||
| When the simulation is run the statistics and output data are logged to a log.txt file and partially to the terminal. | ||
| An example of a simulation is shown in this repo in log.txt. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,53 @@ | ||
| # ----- Imports | ||
| from dataclasses import dataclass | ||
| from enum import Enum | ||
|
|
||
| from scipy.optimize import linear_sum_assignment | ||
|
|
||
|
|
||
| # ----- Classes | ||
| class OperatingSystem(Enum): | ||
| MACOS = "macOS" | ||
| ARCH = "Arch Linux" | ||
| UBUNTU = "Ubuntu" | ||
|
|
||
|
|
||
| @dataclass(frozen=True) | ||
| class Person: | ||
| name: str | ||
| age: int | ||
| # Sorted in order of preference, most preferred is first. | ||
| preferred_operating_systems: tuple[OperatingSystem, ...] | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is there a reason you use a tuple here? Is there an advantage of that over another type of structure? |
||
|
|
||
|
|
||
| @dataclass(frozen=True) | ||
| class Laptop: | ||
| id: int | ||
| manufacturer: str | ||
| model: str | ||
| screen_size_in_inches: float | ||
| operating_system: OperatingSystem | ||
|
|
||
|
|
||
| # ----- Functions | ||
| def allocate_laptops( | ||
| people: list[Person], laptops: list[Laptop] | ||
| ) -> dict[Person, Laptop]: | ||
| cost_matrix = [] | ||
| for person in people: | ||
| person_costs = [] | ||
| for laptop in laptops: | ||
| if laptop.operating_system in person.preferred_operating_systems: | ||
| sadness = person.preferred_operating_systems.index( | ||
| laptop.operating_system | ||
| ) | ||
| else: | ||
| sadness = 100 | ||
| person_costs.append(sadness) | ||
| cost_matrix.append(person_costs) | ||
|
|
||
| row_ind, col_ind = linear_sum_assignment(cost_matrix) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Using this algorithm is a good way of optimising laptop assignment. I have a couple of questions:
|
||
|
|
||
| return { | ||
| people[p_index]: laptops[l_index] for p_index, l_index in zip(row_ind, col_ind) | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,135 @@ | ||
| ------------------------------------------- | ||
| Simulation created at: 03-09-2026 04:29:49 | ||
| ------------------------------------------- | ||
| Laptop to person weighting = 0.84 | ||
| Number of People: 21 | ||
| Number of Laptops: 17 | ||
|
|
||
| Laptop surplus/deficit: -4 | ||
|
|
||
| Percentage chance of 1 preference: 48.75% | ||
| Percentage chance of 2 preference: 11.71% | ||
| Percentage chance of 3 preference: 39.55% | ||
|
|
||
| ===== List of Laptops ===== | ||
| ID: 1 | Manufacturer: Dell | Model: XPS | Screen size (inches): 15 | OS: Ubuntu | ||
| ID: 2 | Manufacturer: Dell | Model: XPS | Screen size (inches): 13 | OS: Arch Linux | ||
| ID: 3 | Manufacturer: Dell | Model: XPS | Screen size (inches): 16 | OS: Arch Linux | ||
| ID: 4 | Manufacturer: Dell | Model: XPS | Screen size (inches): 14 | OS: Ubuntu | ||
| ID: 5 | Manufacturer: Dell | Model: XPS | Screen size (inches): 13 | OS: Ubuntu | ||
| ID: 6 | Manufacturer: Dell | Model: XPS | Screen size (inches): 16 | OS: Arch Linux | ||
| ID: 7 | Manufacturer: Dell | Model: XPS | Screen size (inches): 17 | OS: Ubuntu | ||
| ID: 8 | Manufacturer: Apple | Model: macBook | Screen size (inches): 16 | OS: macOS | ||
| ID: 9 | Manufacturer: Dell | Model: XPS | Screen size (inches): 13 | OS: Ubuntu | ||
| ID: 10 | Manufacturer: Dell | Model: XPS | Screen size (inches): 13 | OS: Arch Linux | ||
| ID: 11 | Manufacturer: Apple | Model: macBook | Screen size (inches): 17 | OS: macOS | ||
| ID: 12 | Manufacturer: Dell | Model: XPS | Screen size (inches): 14 | OS: Ubuntu | ||
| ID: 13 | Manufacturer: Dell | Model: XPS | Screen size (inches): 15 | OS: Arch Linux | ||
| ID: 14 | Manufacturer: Dell | Model: XPS | Screen size (inches): 15 | OS: Ubuntu | ||
| ID: 15 | Manufacturer: Dell | Model: XPS | Screen size (inches): 17 | OS: Arch Linux | ||
| ID: 16 | Manufacturer: Apple | Model: macBook | Screen size (inches): 16 | OS: macOS | ||
| ID: 17 | Manufacturer: Dell | Model: XPS | Screen size (inches): 16 | OS: Ubuntu | ||
|
|
||
| ===== List of People ===== | ||
| Name: Person 1 | Age: 45 | Preferred OS: Ubuntu | ||
| Name: Person 2 | Age: 46 | Preferred OS: macOS, Arch Linux, Ubuntu | ||
| Name: Person 3 | Age: 56 | Preferred OS: Ubuntu | ||
| Name: Person 4 | Age: 85 | Preferred OS: Arch Linux, Ubuntu | ||
| Name: Person 5 | Age: 60 | Preferred OS: macOS, Ubuntu, Arch Linux | ||
| Name: Person 6 | Age: 89 | Preferred OS: Arch Linux, Ubuntu | ||
| Name: Person 7 | Age: 62 | Preferred OS: macOS | ||
| Name: Person 8 | Age: 21 | Preferred OS: macOS | ||
| Name: Person 9 | Age: 59 | Preferred OS: macOS | ||
| Name: Person 10 | Age: 46 | Preferred OS: macOS | ||
| Name: Person 11 | Age: 82 | Preferred OS: macOS | ||
| Name: Person 12 | Age: 33 | Preferred OS: Arch Linux, macOS, Ubuntu | ||
| Name: Person 13 | Age: 33 | Preferred OS: Arch Linux | ||
| Name: Person 14 | Age: 48 | Preferred OS: Ubuntu, Arch Linux, macOS | ||
| Name: Person 15 | Age: 67 | Preferred OS: Ubuntu, macOS, Arch Linux | ||
| Name: Person 16 | Age: 26 | Preferred OS: macOS, Arch Linux, Ubuntu | ||
| Name: Person 17 | Age: 66 | Preferred OS: macOS | ||
| Name: Person 18 | Age: 31 | Preferred OS: Ubuntu, macOS, Arch Linux | ||
| Name: Person 19 | Age: 42 | Preferred OS: Arch Linux, Ubuntu, macOS | ||
| Name: Person 20 | Age: 97 | Preferred OS: Arch Linux, Ubuntu, macOS | ||
| Name: Person 21 | Age: 79 | Preferred OS: Ubuntu | ||
|
|
||
| Laptop operating system options: | ||
| Arch Linux: 6 | ||
| Ubuntu: 8 | ||
| macOS: 3 | ||
|
|
||
| First choice of operating systems: | ||
| Arch Linux: 6 | ||
| Ubuntu: 6 | ||
| macOS: 9 | ||
|
|
||
| Second choice of operating systems: | ||
| Arch Linux: 3 | ||
| Ubuntu: 5 | ||
| macOS: 3 | ||
|
|
||
| Third choice of operating systems: | ||
| Arch Linux: 3 | ||
| Ubuntu: 3 | ||
| macOS: 3 | ||
|
|
||
| First choice OS given: 15 | ||
| Second choice OS given: 1 | ||
| Third choice OS given: 1 | ||
|
|
||
| >>>>> Total Sadness Score: 403 <<<<< | ||
|
|
||
| Note: Due to a deficit of 4 laptops, the minimum sadness score theoretically achievable could never be less than 400 | ||
|
|
||
| ===== Allocations ===== | ||
| Person 1 -- Preferred OS: Ubuntu | ||
| ----> Laptop ID: 1 -- OS: Ubuntu | ||
|
|
||
| Person 2 -- Preferred OS: macOS | Arch Linux | Ubuntu | ||
| ----> Laptop ID: 8 -- OS: macOS | ||
|
|
||
| Person 3 -- Preferred OS: Ubuntu | ||
| ----> Laptop ID: 4 -- OS: Ubuntu | ||
|
|
||
| Person 4 -- Preferred OS: Arch Linux | Ubuntu | ||
| ----> Laptop ID: 2 -- OS: Arch Linux | ||
|
|
||
| Person 5 -- Preferred OS: macOS | Ubuntu | Arch Linux | ||
| ----> Laptop ID: 14 -- OS: Ubuntu | ||
|
|
||
| Person 6 -- Preferred OS: Arch Linux | Ubuntu | ||
| ----> Laptop ID: 3 -- OS: Arch Linux | ||
|
|
||
| Person 7 -- Preferred OS: macOS | ||
| ----> Laptop ID: 11 -- OS: macOS | ||
|
|
||
| Person 8 -- Preferred OS: macOS | ||
| ----> Laptop ID: 16 -- OS: macOS | ||
|
|
||
| Person 12 -- Preferred OS: Arch Linux | macOS | Ubuntu | ||
| ----> Laptop ID: 6 -- OS: Arch Linux | ||
|
|
||
| Person 13 -- Preferred OS: Arch Linux | ||
| ----> Laptop ID: 10 -- OS: Arch Linux | ||
|
|
||
| Person 14 -- Preferred OS: Ubuntu | Arch Linux | macOS | ||
| ----> Laptop ID: 5 -- OS: Ubuntu | ||
|
|
||
| Person 15 -- Preferred OS: Ubuntu | macOS | Arch Linux | ||
| ----> Laptop ID: 7 -- OS: Ubuntu | ||
|
|
||
| Person 16 -- Preferred OS: macOS | Arch Linux | Ubuntu | ||
| ----> Laptop ID: 17 -- OS: Ubuntu | ||
|
|
||
| Person 18 -- Preferred OS: Ubuntu | macOS | Arch Linux | ||
| ----> Laptop ID: 9 -- OS: Ubuntu | ||
|
|
||
| Person 19 -- Preferred OS: Arch Linux | Ubuntu | macOS | ||
| ----> Laptop ID: 13 -- OS: Arch Linux | ||
|
|
||
| Person 20 -- Preferred OS: Arch Linux | Ubuntu | macOS | ||
| ----> Laptop ID: 15 -- OS: Arch Linux | ||
|
|
||
| Person 21 -- Preferred OS: Ubuntu | ||
| ----> Laptop ID: 12 -- OS: Ubuntu | ||
|
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| scipy>=1.13.1 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for writing this readme, it's always good to see programs documented well like this.