问题
我有一群人,我希望每个人与小组中的每个其他人进行1:1的会议。一个给定的人一次只能与另一个人见面,因此我想执行以下操作:
查找所有可能的配对组合
将配对成组进行“回合”会议,每个人只能参加一次回合,并且回合应包含尽可能多的对,以满足最少回合中所有可能的配对组合。
为了用所需的输入/输出来演示该问题,假设我有以下列表:
>>> people = ['Dave', 'Mary', 'Susan', 'John']
我想产生以下输出:
>>> for round in make_rounds(people):
>>> print(round)
[('Dave', 'Mary'), ('Susan', 'John')]
[('Dave', 'Susan'), ('Mary', 'John')]
[('Dave', 'John'), ('Mary', 'Susan')]
如果我的人数为奇数,那么我会期望得到以下结果:
>>> people = ['Dave', 'Mary', 'Susan']
>>> for round in make_rounds(people):
>>> print(round)
[('Dave', 'Mary')]
[('Dave', 'Susan')]
[('Mary', 'Susan')]
这个问题的关键是我需要我的解决方案表现出色(在合理范围内)。我编写的代码行得通,但是随着大小的people增长,它的速度将成指数增长。我对编写高性能算法的了解不足,无法知道我的代码是否效率低下,还是仅仅受问题参数的束缚?
我尝试过的
第1步很简单:我可以使用进行所有可能的配对itertools.combinations:
>>> from itertools import combinations
>>> people_pairs = set(combinations(people, 2))
>>> print(people_pairs)
{('Dave', 'Mary'), ('Dave', 'Susan'), ('Dave', 'John'), ('Mary', 'Susan'), ('Mary', 'John'), ('Susan', 'John')}
为了自己计算出回合,我正在构建一个回合,如下所示:
创建一个空round列表
迭代people_pairs使用上述combinations方法计算出的集合的副本
对于配对中的每个人,检查当前内容中round是否已有包含该个人的任何配对
如果已经有一对包含其中一个个体,请在本轮比赛中跳过该配对。如果不是,请将这对添加到该回合中,然后从people_pairs列表中删除该对。
一旦所有的人对都经过迭代,就将回合添加到主rounds列表中
重新开始,因为people_pairs现在只包含未进入第一轮的对
最终,这产生了预期的结果,并减少了我的员工对,直到没有人剩下,并计算了所有回合。我已经知道这需要大量的迭代,但是我不知道这样做的更好方法。
使用https://mycurvefit.com绘制100-300列表大小的方法的性能表明,计算1000人的列表轮数可能需要100分钟左右。有更有效的方法吗?
注意:实际上,我并不是要组织1000人的会议:)这只是一个简单的示例,代表了我要解决的匹配/组合问题。
噜噜哒
慕标5832272
慕田峪7331174
相关分类