制定一个时间表,让一群人在有限制的情况下相互交谈



问题陈述

我希望实现以下目标:(例如,可以用来为学生组织某种快速约会活动(

制定一个时间表,让人们一对一地交谈,并与团队中的每个成员交谈。但有限制。

  • 输入:人员列表。(例如30人(
  • 限制:有些人不应该互相交谈(例如,他们彼此认识(
  • 输出:配对列表(分为会话(只需一个解决方案即可,无需知道所有可能的结果

示例

例如。四人小组

  1. 约翰
  2. Steve
  3. Mark
  4. Melissa

限制:John-Mellisa->无

结果

会话一

  • 约翰-史蒂夫
  • 马克-梅丽莎

会话二

  • 约翰-马克
  • Steve-Melissa

会话三

  • Steve-Mark

John和Mellisa将不会加入第三阶段,因为这是限制。

问题

有没有一种方法可以使用Python甚至excel来解决这个问题?

我特别想找一些关于这个问题是如何命名的线索,因为我认为这是一些问题。我应该寻找一些解决方案吗?动态编程等?

这是一个相当幼稚的实现:

from itertools import combinations
from typing import Set, List, Generator

def generate_sessions(people: Set, excl: List[Set]) -> Generator[List[Set], None, None]:
# all the pairings you need are all possible pairings, except the exclusions
needed_pairings = [set(pair) for pair in combinations(people, 2)]
for pair in excl:
needed_pairings.remove(pair)
# while there pairing that haven't happened yet
while needed_pairings:
# each session starts empty
session = []
# keep track of all people still available for this session
available = set(people)
# create an iterator, so we can loop over the needed pairings
iter_needed_pairings = iter(needed_pairings)
# as long as there are more than 2 people still waiting and there's a pair left in the needed pairings
while (len(available) > 1) and (pair := next(iter_needed_pairings, False)):
# are both people in the pair in the group of available people?
if available.intersection(pair) == pair:
# then they can meet in this session
session.append(pair)
# and they're no longer available
available -= pair
# once we have a session, remove the pairs in it from the pairings still needed
for pair in session:
needed_pairings.remove(pair)
# yield the session
yield session

print(list(generate_sessions(people={'John', 'Steve', 'Mark', 'Melissa'}, excl=[{'John', 'Melissa'}])))

结果(由于集合的无序性,可能会有所不同(:

[[{'John', 'Mark'}, {'Melissa', 'Steve'}], [{'John', 'Steve'}, {'Melissa', 'Mark'}], [{'Mark', 'Steve'}]]

这会生成会话,直到每个人都见面为止。您可以从生成器中获取next(),直到您有足够的会话为止。这种方法唯一的缺点是,在有更多人开会的会议之前,可能会发现有几个人在等待的会议。您可以通过按长度对会话进行排序来解决这个问题,但这当然意味着生成所有会话。

编辑:我添加了打字信息,以明确预期的类型,但当然不需要这样。

你提供的信息非常慷慨,你有一组所有的学生,还有一组禁止配对的学生(因为你自己说过,这很容易解释,只要说这是一组相互认识的学生(。因此,我们可以迭代我们的学生列表,创建随机配对,只要它们不存在于我们的禁止集中,然后与它们一起扩展我们的禁止集,并在剩余的学生上递归,直到我们不能创建任何不存在于禁止集中的对(我们有配对,这样每个学生都见过所有学生(。

相关内容

  • 没有找到相关文章

最新更新