繁体   English   中英

查找列表中的所有对,条件为 Python

[英]Find all the pairs in a list with conditions Python

我有一个现实生活中的问题,我想使用 Python 来解决。 我有一个由 x=10 人组成的团队(包括我自己),在 n-1=9 周期间,我们希望每周安排一次 1 对 1 通话,这样每个人都可以接到每个人的电话,并且在此期间没有一对人交谈两次9 周。

这是我的解决方案,但它有缺陷,因为尽管每个人都与每个人交谈,但每个人每周都有两个电话,而我每周只需要 1 个电话。

知道我该如何解决这个问题吗?

#for shifting a list to the left with n positions
def rotate(l, n):
    return l[n:] + l[:n]

def generate_1on1_meetings(members):
    random.shuffle(members)
    n = len(members)
    for i in range(0, int(n / 2)):
        print("WEEK " + str(i + 1) + "\n")
        aux = rotate(members, i + 1)
        for j in range(0, n):
            print(members[j] + " - " + aux[j])
        print("\n")

编辑:所以为了让事情更清楚,应该有偶数(2k)人。 每周将有 k 次会议,每个人只出现在一次会议中,并且每周每个人都将参加一次会议。 召开所有会议需要 2k-1 周。

示例:让我们考虑 4 个团队成员的情况:[A, B, C, D]。 考虑到我的限制,一个解决方案是:

第1周:AB,CD

第 2 周:AC、BD

第 3 周:公元,公元前

所以每个人每周只有一次会议,他们每周只参加一次会议,4-1周过去后,每个人都和每个人开会

您可以使用循环(多边形)算法:

这是 Python 中的算法示例(适用于偶数和奇数的团队/人):

def roundRobin(T):
    P = T[1:]+len(T)%2*[None]
    for _ in range(len(T)-1):
        yield [g for g in zip(T[:1]+P[1:len(P)//2+1],P[:1]+P[::-1])]
        P.append(P.pop(0))

output:

# Even number of people (10)

for calls in roundRobin(["A","B","C","D","E","F","G","H","I","J"]):
    print(calls) 

[('A', 'B'), ('C', 'J'), ('D', 'I'), ('E', 'H'), ('F', 'G')]
[('A', 'C'), ('D', 'B'), ('E', 'J'), ('F', 'I'), ('G', 'H')]
[('A', 'D'), ('E', 'C'), ('F', 'B'), ('G', 'J'), ('H', 'I')]
[('A', 'E'), ('F', 'D'), ('G', 'C'), ('H', 'B'), ('I', 'J')]
[('A', 'F'), ('G', 'E'), ('H', 'D'), ('I', 'C'), ('J', 'B')]
[('A', 'G'), ('H', 'F'), ('I', 'E'), ('J', 'D'), ('B', 'C')]
[('A', 'H'), ('I', 'G'), ('J', 'F'), ('B', 'E'), ('C', 'D')]
[('A', 'I'), ('J', 'H'), ('B', 'G'), ('C', 'F'), ('D', 'E')]
[('A', 'J'), ('B', 'I'), ('C', 'H'), ('D', 'G'), ('E', 'F')]


# Odd number of people (7) 

for calls in roundRobin(["A","B","C","D","E","F","G"]):
    print(calls)

[('A', 'B'), ('C', None), ('D', 'G'), ('E', 'F')] # C sits out
[('A', 'C'), ('D', 'B'), ('E', None), ('F', 'G')] # E sits out
[('A', 'D'), ('E', 'C'), ('F', 'B'), ('G', None)] # G sits out
[('A', 'E'), ('F', 'D'), ('G', 'C'), (None, 'B')] # B sits out
[('A', 'F'), ('G', 'E'), (None, 'D'), ('B', 'C')] # D sits out
[('A', 'G'), (None, 'F'), ('B', 'E'), ('C', 'D')] # F sits out

让我们先安排对。 然后安排会议。

例子:

  1. 3 人团队有 3x2 = 6 对 (1:1)
  2. 要安排 6 次会议,每周一次会议,我们需要 6 周

使用itertools.combinations

import itertools

def arrange_pairs(members):
    # 1:1 combinations, return a list of tuples (1:1 pair)
    return list(itertools.combinations(members,2))  # combine pairs (r=2) of members


def schedule_meetings(pairs):
    # 1 meeting per week, return a list of meeting-descriptions as string
    scheduled = []
    cw = 1  # calendar week or just a counter
    for pair in pairs:
        scheduled.append(f"week {cw:2}: {pair}")
        cw = cw + 1
    return scheduled


members = [1,2,3]  # given 3 team-members, simplified as numerical ID
pairs = arrange_pairs(members)
meetings = schedule_meetings(pairs)
print(meetings)

印刷:

['week  1: (1, 2)', 'week  2: (1, 3)', 'week  3: (2, 3)']

另请参阅: 如何获取列表元素的所有可能组合?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM