In [1]:
from matching.games import StableMarriage
import random
from copy import deepcopy
In [2]:
def search_dict_key(dict, value):
for key, val in dict.items():
if val == value:
return key
def check_unstable_pairs(groupA_preferences: dict, groupB_preferences: dict, current_matching: dict):
unstable_pairs = [] # format: [(a1, b1), (a2, b2), ...]
for groupA_test in groupA_preferences.keys():
for groupB_test in [val for val in groupB_preferences.keys() if val != current_matching[groupA_test]]:
if groupA_preferences[groupA_test].index(groupB_test) < groupA_preferences[groupA_test].index(current_matching[groupA_test]) and groupB_preferences[
groupB_test].index(groupA_test) < groupB_preferences[groupB_test].index(search_dict_key(current_matching, groupB_test)):
unstable_pairs.append((groupA_test, groupB_test))
return unstable_pairs
In [3]:
groupA_preferences = {
"M": ["A", "C", "T"],
"K": ["A", "T", "C"],
"J": ["T", "A", "C"],
}
groupB_preferences = {
"C": ["J", "M", "K"],
"T": ["M", "J", "K"],
"A": ["J", "M", "K"],
}
current_matching = {"M": "T", "K": "A", "J": "C"}
check_unstable_pairs(groupA_preferences, groupB_preferences, current_matching)
Out[3]:
[('M', 'A'), ('J', 'A')]
In [4]:
groupA_preferences = {
"B": ["M", "N", "S", "K"],
"H": ["K", "S", "M", "N"],
"C": ["K", "M", "N", "S"],
"E": ["S", "N", "M", "K"]
}
groupB_preferences = {
"M": ["B", "H", "C", "E"],
"K": ["H", "B", "C", "E"],
"N": ["H", "C", "B", "E"],
"S": ["C", "B", "H", "E"]
}
current_matching = {"B": "N", "H": "S", "C": "M", "E": "K"}
check_unstable_pairs(groupA_preferences, groupB_preferences, current_matching)
Out[4]:
[('B', 'M'), ('H', 'K'), ('C', 'K')]
In [5]:
import sys
sys.getrecursionlimit() # 100-100的gale-shapley大概需要1500的recursion limit
# 如果要尝试>100的gale-shapley就需要把recursion limit调大
# sys.setrecursionlimit(4500)
Out[5]:
3000
In [6]:
groupA_preferences = {}
groupB_preferences = {}
current_matching = {}
groupA_ids = [f"A_{idx}" for idx in range(0, 100)]
groupB_ids = [f"B_{idx}" for idx in range(0, 100)]
for id_A in groupA_ids:
groupA_preferences[id_A] = random.sample(groupB_ids, len(groupB_ids))
for id_B in groupB_ids:
groupB_preferences[id_B] = random.sample(groupA_ids, len(groupA_ids))
groupB_ids_copy = deepcopy(groupB_ids)
for id_A in groupA_ids:
random_B = random.choice(groupB_ids_copy)
current_matching[id_A] = random_B
groupB_ids_copy.remove(random_B)
print(f'Use random matching, there are {len(check_unstable_pairs(groupA_preferences, groupB_preferences, current_matching))} unstable matching pairs')
game = StableMarriage.create_from_dictionaries(
groupA_preferences, groupB_preferences
)
game_matching = dict(game.solve(optimal="suitor"))
stable_matching = {}
for key, val in game_matching.items():
stable_matching[str(key)] = str(val)
print(f'Use Gale-shapley algorithm, there are {len(check_unstable_pairs(groupA_preferences, groupB_preferences, stable_matching))} unstable matching pairs')
Use random matching, there are 2143 unstable matching pairs Use Gale-shapley algorithm, there are 0 unstable matching pairs
In [13]: