我目前正在编写一个演示Gale-Shapley算法的程序。
Description of Gale-Shapley algorithm on wikipedia
我有两个列表作为输入。
preference_boys,这是男孩对女孩的偏爱,并且
preference_girls,这是女孩对男孩的偏爱。
在代码中,最先选择的是男孩,我已经成功地将每个男孩配对了
他是女孩的第一选择。
'''
preference_boys = [[2, 0, 1, 3], [1, 2, 3, 0], [0, 3, 1, 2], [2, 3, 0, 1]]
preference_girls = [[0, 2, 1, 3], [2, 3, 0, 1], [3, 1, 2, 0], [0, 3, 1, 2]]
'''
def couple_maker(preference_boys, preference_girls):
# stores the couples based on boys first choice of girls
temporary_couples = []
single_boys = []
for boy in range(len(preference_boys)):
single_boys.append(boy)
# single_boys = [0, 1, 2, 3]
while len(single_boys) > 0:
for single_boy in single_boys:
for girl in preference_boys[single_boy]:
temporary_couple = (single_boy, girl)
single_boys.remove(single_boy)
temporary_couples.append(temporary_couple)
break
return temporary_couples
>>> couple_maker(preference_boys, preference_girls)
[(0, 2), (2, 0), (1, 1), (3, 2)]
现在,我需要为另外两个条件解决两个夫妻共享一个女孩的情况。
从我当前的临时夫妇(0,2)和(3,2)夫妇的输出来看,同一个女孩。
我可以使用哪些方法来比较重叠的女孩(第二个元素
列表中的元组)并删除优先级低于女孩的男孩?
答案 0 :(得分:1)
一种方法是使用temporary_couples
之类的方法将defaultdict
“按女孩”分组(第一个索引):
from collections import defaultdict
temp_couples = [(0, 2), (2, 0), (1, 1), (3, 2)]
by_girl = defaultdict(list)
for (b,g) in temp_couples:
by_girl[g].append((b,g))
for (g,her_temp_couples) in by_girl.items():
if len(her_temp_couples) > 1:
print("Girl", g, "has conflicts:", her_temp_couples)
输出:
Girl 2 has conflicts: [(0, 2), (3, 2)]
然后,您可以继续使用引用的算法进行解析。
为清楚起见,在第一个循环中填充后,by_girl
如下所示:
{
0: [(2, 0)],
1: [(1, 1)]
2: [(0, 2), (3, 2)],
3: [] # Implicitly
}