Need help creating league schedule based on matchup table

933 Views Asked by At

I have an table with a set of teams and how many games they need to play against each other team like the one below:

example matchup table

In this table, teams a, b, c, and d each play each other twice, and they play the other set of teams once each, for a total of ten games per team. I need to create a weekly matchup schedule (ex: week 1 - a vs b, c vs d, etc.) based on this table so that all games will be played in 10 weeks, with each team playing one of their matchups each week. Said another way, I need to know which team each team is playing each week for 10 weeks so that each team plays their 10 games. There is no home/away to consider.

EDIT: One additional note is that every team will play on the same day each week, so basically it's scheduling these games over 10 days with each team playing one game on each of the 10 days.

I'm having trouble figuring out a good way to do this so I'd be very grateful if anyone has any suggestions for algorithms/packages or can point me towards some resources (my language of preference is python).

Thanks in advance!

3

There are 3 best solutions below

0
On

You can do a first round-robin in the first 7 days, so that every team plays against every other team exactly once. Then in the last 3 days, do two separate round-robins, so that the teams in abcd play against each other once more, and the teams in efgh play against each other once more. More about round-robin tournaments:

# a table is a simple list of teams
def next_table(table):
  return [table[0]] + [table[-1]] + table[1:-1]
  # [0 1 2 3 4 5 6 7] -> [0 7 1 2 3 4 5 6]

# a pairing is a list of pairs of teams
def pairing_from_table(table):
  return list(zip(table[:len(table)//2], table[-1:len(table)//2-1:-1]))
  # [0 1 2 3 4 5 6 7] -> [(0,7), (1,6), (2,5), (3,4)]

# a team is an element of the table
def round_robin(table):
  pairing_list = []
  for day in range(len(table) - 1):
    pairing_list.append(pairing_from_table(table))
    table = next_table(table)
  return pairing_list

def get_programme():
  first7days = round_robin(list('abcdefgh'))
  last3days_abcd = round_robin(list('abcd'))
  last3days_efgh = round_robin(list('efgh'))
  return first7days + [a+e for a,e in zip(last3days_abcd, last3days_efgh)]

print(get_programme())
# [[('a', 'h'), ('b', 'g'), ('c', 'f'), ('d', 'e')],
#  [('a', 'g'), ('h', 'f'), ('b', 'e'), ('c', 'd')],
#  [('a', 'f'), ('g', 'e'), ('h', 'd'), ('b', 'c')],
#  [('a', 'e'), ('f', 'd'), ('g', 'c'), ('h', 'b')],
#  [('a', 'd'), ('e', 'c'), ('f', 'b'), ('g', 'h')],
#  [('a', 'c'), ('d', 'b'), ('e', 'h'), ('f', 'g')],
#  [('a', 'b'), ('c', 'h'), ('d', 'g'), ('e', 'f')],
#  [('a', 'd'), ('b', 'c'), ('e', 'h'), ('f', 'g')],
#  [('a', 'c'), ('d', 'b'), ('e', 'g'), ('h', 'f')],
#  [('a', 'b'), ('c', 'd'), ('e', 'f'), ('g', 'h')]]
1
On

a very simple way would be to generate combinations and then add doubles, something like this:

from itertools import combinations

teams = "abcdefgh"

possible_games = combinations(teams, 2)

doubles = {"a":("b", "c", "d"), "b":("c", "d"), "c":("d",), "e":("f", "g", "h"), "f":("g", "h"), "g":("h",)}
all_doubles = {(k, v) for k, values in doubles.iteritems() for v in values}
print all_doubles

games = list(possible_games)
games += [g for g in games if g in all_doubles]
print games, len(games)

This leaves the question about the actual scheduling open - you need to make sure (I believe) that for example team A does not play 7 days in a row and then idles for a week, but the above should be a good start I think.

1
On

To realize a round robin, create a first round with all games. Imagine all teams except the home team in the last game are connected like a chain. Rotate this chain clockwise (in total nr of teams minus 2 times) Like so

First round

Team 1 - Team 2
 |        |
Team 5 - Team 3
       \  |
Team 6 - Team 4

Second round

Team 5 - Team 1
  |       |
Team 4 - Team 2
       \   |
Team 6 - Team 3

etc. Works for all number of teams. In case of odd number of teams, just delete the last game of every round. It's up to you to write an algorithm. I did it long time before.