Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Find all the pairs in a list with conditions Python

Tags:

python

I have a real life problem that I want to solve using Python. I have a team of x=10 people (myself included) and during n-1=9 weeks we want to schedule a 1-on-1 call each week such that everyone gets a call with everyone and no pair of people talk twice during the 9 weeks.

This is my solution but it is flawed because, although everyone speaks with everyone, each person has two calls per week and I want just 1 call per week.

Any idea of how could I solve this?

#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")

EDIT: So to make things more clear, there should be an even number (2k) of persons. In each week there will be k meetings, each person appearing just in one meeting, and in each week everyone will have participated in exactly one meeting. There need to be 2k-1 weeks to have all the meetings.

Example: so let's consider the case of 4 team members: [A, B, C, D]. A solution given my constraints would be:

Week 1:AB,CD

Week 2: AC, BD

Week 3: AD, BC

So each person had just one meeting per week, all of them appeared in just 1 meeting in each week and after the 4-1 weeks passed everyone had a meeting with everyone

like image 732
mihaicata1205 Avatar asked Nov 17 '25 13:11

mihaicata1205


1 Answers

You could use the round-robin (polygon) algorithm:

Here's an example of the algorithm in Python (works for even and odd number of teams/people):

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

output:

# Even number of people (10)

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

[('A', 'J'), ('B', 'I'), ('C', 'H'), ('D', 'G'), ('E', 'F')]
[('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')]


# Odd number of people (7) 

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

[('A', None), ('B', 'G'), ('C', 'F'), ('D', 'E')] no call for A
[('A', 'B'), ('C', None), ('D', 'G'), ('E', 'F')] no call for C
[('A', 'C'), ('D', 'B'), ('E', None), ('F', 'G')] no call for E
[('A', 'D'), ('E', 'C'), ('F', 'B'), ('G', None)] no call for G
[('A', 'E'), ('F', 'D'), ('G', 'C'), (None, 'B')] no call for B
[('A', 'F'), ('G', 'E'), (None, 'D'), ('B', 'C')] no call for D
like image 102
Alain T. Avatar answered Nov 20 '25 02:11

Alain T.