Python Balanced sports schedule generation

Go To StackoverFlow.com

0

I have the following code sample

import itertools
import random
set_size = 2
schedule = set()
teams = range(10)
for comb in itertools.product(teams, repeat=set_size):
    comb = sorted(list(comb))
    if len(set(comb)) == set_size:
        schedule.add(tuple(comb))

schedule = list(schedule)
random.shuffle(schedule)

home = {}
for game in schedule:
    if home.has_key(game[0]):
        home[game[0]] += 1
    else:
        home[game[0]] = 1


print home

It generates a valid schedule but the issue is some of the teams are very lopsided for home games.

For example a print out of home is

{0: 5, 1: 3, 2: 5, 3: 5, 4: 5, 5: 5, 6: 5, 7: 5, 8: 4, 9: 3}

The key is the team and the value is the number of home games. If I have 10 teams in a league I expect some teams to get 5 home and others to get only 4 but some get 5 while others are getting only 3

2012-04-05 21:28
by Mike


1

This is a start:

from itertools import combinations

def balance(teams):
  home_count = dict.fromkeys(teams,0)
  max_homes = len(teams)//2
  matches = []
  for a,b in combinations(teams,2):
    if home_count[a] >= max_homes:
      matches.append((b,a))
      home_count[b] += 1
    else:
      matches.append((a,b))
      home_count[a] += 1
  return matches

def home_games(matches):
  counts = {}
  for (a,b) in matches:
    counts[a] = counts.get(a,0) + 1
  return counts

Then

>>> matches = balance(range(10))
>>> home_games(matches)
{0: 5, 1: 5, 2: 5, 3: 5, 4: 5, 5: 4, 6: 4, 7: 4, 8: 4, 9: 4}

You should shuffle the team order passed to balance as the last few teams will always have fewer home matches.

You may also need to distribute the matches so that any one team doesn't play too soon after it's last match, but that will depend on how many games are held concurrently. And is worthy of another SO question.

2012-04-05 22:21
by MattH


1

Another example:

import random

data = range(10)
home_games = len(data)/2
home = {}
schedule = []
for d in data:
    home[d] = 0

random.shuffle(data)

for i in range(len(data)):
    for j in range(1,len(data)-i):
        if j < home_games:
            schedule.append((data[i], data[j+i]))
            home[data[i]]+=1
        else:
            schedule.append((data[i+j], data[i]))
            home[data[j+i]]+=1

print home

And the output:

{0: 5, 1: 5, 2: 4, 3: 4, 4: 4, 5: 5, 6: 5, 7: 5, 8: 4, 9: 4}

You can use random.shuffle on the schedule to change the pair order

2012-04-06 05:12
by Krzysztof Rosiński
Ads