0
$\begingroup$

I'm trying to separate people from a pool into several smaller groups. The group-size should always remain the same. People can be part of several groups - but no two people can be part of more than one group.

members = [A,B,C,D,E]

group1 = [A,B,C]
group2 = [A,D,E]

There aren't anymore valid groups possible. A can't be part of any more groups. B can't be in a group with C anymore (because they're already members of group1. B can be in a group with D, however E cannot be part of that group, because it can't be in a group with E - since they're both already in group2.

So my question is, is there an algorithm where I can figure out all the possible team combinations for every members-size and group-size?

$\endgroup$
6
  • $\begingroup$ How about: group1 = [A,B,C], group2 = [B,D,E]? You need all varations or just 1 random one that fits requirements? $\endgroup$
    – ulou
    Commented May 20, 2021 at 13:49
  • $\begingroup$ @RazorHail, when you said There aren't anymore valid groups possible you meant that there cannot be a group3 provided that sizeof(group)=3, right? because ulou is right that there are many other variations that meet your constrains with sizeof(group)=3 $\endgroup$
    – Amo Robb
    Commented May 20, 2021 at 14:33
  • $\begingroup$ @ulou Just a random one. This obviously is very easy to do with group-size 3 and a total of 5 members. But what if there were 9 members, etc. $\endgroup$
    – RazorHail
    Commented May 20, 2021 at 15:02
  • $\begingroup$ Progamming language? Or are you looking for pseudo code e.g. in JS? $\endgroup$
    – ulou
    Commented May 20, 2021 at 15:03
  • $\begingroup$ @AmoRobb yes, correct. If the group-size is 3 and there are 5 total members. There are only 2 possible teams at the same time $\endgroup$
    – RazorHail
    Commented May 20, 2021 at 15:03

1 Answer 1

0
$\begingroup$

I've solved my own problem and wanted to share it with everybody

First, I need this helper-function that checks if any of the members of a current team have already been part of a previous team before:

def part_of_prev_teams(current_team):
    for member_i in range(0, len(current_team)):
        for member_j in range(member_i, len(current_team)):
            for team in teams:
                if member_i != member_j:
                    if current_team[member_i] in team and current_team[member_j] in team:
                        return True

The actual function looks like this:

pool = ["A", "B", "C", "D", "E", "F", "G", "H", "I"]
team_size = 3
teams = []

for member_i in range(0, len(pool)-1):              # iterate every member
    current_team = [pool[member_i]]                 # add the current member to current team
    for member_j in range(member_i, len(pool)):
        if len(current_team) >= team_size:          # team full
            break
        if pool[member_j] in current_team:          # member_i == member_j
            pass
        else:
            current_team.append(pool[member_j])     # add current member into the current_team
            if len(current_team) > 1:               # team has at least 2 members
                if part_of_prev_teams(current_team):# check for conflicts
                    current_team.pop()              # member was incorrectly added. remove it again
    if len(current_team) == team_size:              # team size has been reached. Finalize result
        print(current_team)
        teams.append(current_team)

For 9 members and a team-size of 3, this is what the result looks like:

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

Additionally, I've written this print-function to count the membership count of every member:

def print_memberships(teams):
    for member in pool:
        member_count = 0
        for team in teams:
            member_count += team.count(member)
        print(member + ": " + str(member_count))

Which prints the following result:

memberships:

A: 1
B: 2
C: 2
D: 3
E: 2
F: 3
G: 2
H: 2
I: 1

So, these are very "unfair" results. I was expecting every member to be part of an equal amount of teams, which isn't the case.

So then I went back to the pool-array and added another A/I (because it was in the least number of teams) and got much better results:

pool = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "A"]  # 2x "A" in list

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

memberships:
A: 2
B: 2
C: 2
D: 3
E: 2
F: 3
G: 3
H: 2
I: 2
A: 2
I: 2
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.