从首选项列表中找到可行的组合

时间:2018-06-30 12:20:37

标签: python python-3.x algorithm sorting permutation

我有一个看起来像这样的对象:

a - ['A', 'B', 'C']
b - ['A', 'B', 'C']
c - ['A', 'B', 'C', 'D']
d - ['A', 'B', 'C', 'D']

每个键之一都有许多可用选项,如列表所示(例如a可以在A, B, C之间进行选择,依此类推)。我想找到可以满足所有人的对的组合。可能是:

#   Chosen  Remaining          Available Options
------------------------------------------
a - B       - ['A', 'B', 'C'] - ['A', 'B', 'C']
b - A       - ['A', 'C']      - ['A', 'B', 'C']
c - D       - ['C', 'D']      - ['A', 'B', 'C', 'D']
d - C       - ['C']           - ['A', 'B', 'C', 'D']

因此,在以上示例中,a选择了项目B,从而减​​少了其余参与者的可用选项池。 b,然后选择项目A,依此类推。

我这样做的依据是,根据所有参与者的可用选择量来循环遍历所有参与者,其想法是,如果我有一个参与者只想要一个项目,那么别无选择,只能给他那个项目,从池中删除它。

import random

team_choices = {'a': ['A', 'B', 'C'],
                'b': ['A', 'B', 'C'],
                'c': ['A', 'B', 'C', 'D'],
                'd': ['A', 'B', 'C', 'D']}
teams_already_created = []
for team_b in sorted(team_choices, key=team_choices.__getitem__, reverse=False):
    available_opponents = [opponent for opponent in team_choices[team_b] if opponent not in teams_already_created]
    chosen_opponent = random.choice(available_opponents)
    teams_already_created.append(chosen_opponent)

尽管我无法做到这一点,但我无法保证它会在某个时候做出选择,而该选择会在以后阻塞其他玩家,从而使他没有其他选择。而且,如果chosen_opponent为空,则显然会失败。

是否有更好的方法可以每次都起作用?

1 个答案:

答案 0 :(得分:4)

这是找到maximum matching的问题。有多项式时间算法(例如Hopcroft–Karp)。