Skip to content

Commit 4cec581

Browse files
committed
initial algorithm
1 parent d36d75d commit 4cec581

1 file changed

Lines changed: 60 additions & 0 deletions

File tree

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
class GaleShapley:
2+
"""Implementation of the Gale-Shapley algorithem
3+
4+
takes it 2 preference list as a 2D array of ints. First one is the
5+
proposing side.
6+
"""
7+
8+
def find_matches(
9+
self,
10+
proposers_preferences: dict[int, list[int]],
11+
receivers_preferences: dict[int, list[int]],
12+
) -> dict[int, int]:
13+
"""
14+
>>> gs = GaleShapley()
15+
>>> gs.find_matches({1: [1, 2, 3], 2: [2, 1, 3], 3: [2, 3, 1]}, {1: [1, 2, 3], 2: [2, 1, 3], 3: [2, 3, 1]})
16+
{1: 1, 2: 2, 3: 3}
17+
>>> gs.find_matches({}, {})
18+
{}
19+
>>> gs.find_matches({1: [1,]}, {1: [1,]})
20+
{1: 1}
21+
"""
22+
23+
matches = {key: -1 for key in proposers_preferences.keys()}
24+
25+
# [NOTE] I would've used sets, but want replicability for easy debugging.
26+
free_proposers = list(proposers_preferences.keys())
27+
tested_matches = {key: 0 for key in proposers_preferences.keys()}
28+
29+
while free_proposers:
30+
proposer = free_proposers[0]
31+
32+
if tested_matches[proposer] == len(proposers_preferences[proposer]):
33+
free_proposers.remove(proposer)
34+
continue
35+
36+
receiver = proposers_preferences[proposer][tested_matches[proposer]]
37+
tested_matches[proposer] += 1
38+
39+
if receiver not in matches.values():
40+
matches[proposer] = receiver
41+
free_proposers.remove(proposer)
42+
continue
43+
cur_proposer = next(
44+
prop for prop, rec in matches.items() if rec == receiver
45+
)
46+
if receivers_preferences[receiver].index(proposer) < receivers_preferences[
47+
receiver
48+
].index(cur_proposer):
49+
matches[cur_proposer] = -1
50+
matches[proposer] = receiver
51+
free_proposers.remove(proposer)
52+
free_proposers.append(cur_proposer)
53+
54+
return matches
55+
56+
57+
if __name__ == "__main__":
58+
import doctest
59+
60+
doctest.testmod()

0 commit comments

Comments
 (0)