Create a schedule where a group of people all talk to each other - with restrictions

青春壹個敷衍的年華 提交于 2021-01-29 15:31:22

问题


Problem statement

I would like to achieve the following: (could be used for example to organize some sort of a speeddating event for students)

Create a schedule so people talk to each other one-on-one and this to each member of the group. but with restrictions.

  • Input: list of people. (eg. 30 people)
  • Restrictions: some of the people should not talk to each other (eg. they know each other)
  • Output: List of pairs (separated into sessions) just one solution is ok, no need to know all of the possible outcomes

Example

eg. Group of 4 people

  1. John
  2. Steve
  3. Mark
  4. Melissa

Restrictions: John - Mellisa -> NO

Outcome

Session one

  • John - Steve
  • Mark - Melissa

Session two

  • John - Mark
  • Steve - Melissa

Session three

  • Steve - Mark

John and Mellisa will not join session three as it is restriction.

Question

Is there a way to approach this using Python or even excel?

I am especially looking for some pointers how this problem is called as I assume this is some Should I look towards some solver? Dynamic programming etc?


回答1:


This is a fairly naive implementation:

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'}])))

Result (can vary, due to unordered nature of sets):

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

This generates sessions until everyone has met. You could just get the next() from the generator until you have enough sessions. The only downside to this approach is that it may find a sessions where a few people are waiting before a session that has more people meeting. You could solve that by sorting the sessions by length, but of course that means generating all of them.

Edit: I added typing info, to make it clear what the expected types are, but of course it doesn't need that to work.




回答2:


Your given information is pretty generous, you have a set of all the students, and a set of no-go pairs (because you said it yourself, and it makes it easy to explain, just say this is a set of pairs of students who know each other). So we can iterate through our students list creating random pairings so long as they do not exist in our no-go set, then expand our no-go set with them, and recurse on the remaining students until we can not create any pairs that do not exist already in the no-go set (we have pairings so that every student has met all students).



来源:https://stackoverflow.com/questions/65163061/create-a-schedule-where-a-group-of-people-all-talk-to-each-other-with-restrict

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!