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
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.
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