Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sports schedule: home/away alternation #65

Open
fredericgirod opened this issue Sep 21, 2018 · 2 comments
Open

Sports schedule: home/away alternation #65

fredericgirod opened this issue Sep 21, 2018 · 2 comments

Comments

@fredericgirod
Copy link

Hi again,
I've been spending my days trying to create a sports schedule with pyschedule, but I cannot implement a home/away alternation constraint. Each matches calendar should get the teams to alternate home and away matches in order not to play e.g. 5 times at home or away in a row.
I know a capacity constraint should do the job, but I don't see how.
Any thoughts about this ?
I would really appreciate any tips or advice.

@timnon
Copy link
Owner

timnon commented Sep 22, 2018

In the following script, we restrict each team to play in each stadium at most once every 3 rounds. Thats comes pretty close to what you want. Exactly matching your requirements is probably not possible at the moment.

import sys
sys.path.append('../src')
from pyschedule import Scenario, solvers, plotters, alt

n_teams = 8
n_stadiums = n_teams
n_slots = n_teams-1

S = Scenario('sports_scheduline',horizon=n_slots)
Stadiums = S.Resources('S',num=n_stadiums)
Teams = S.Resources('T',num=n_teams)

Games = list()
for T1 in Teams:
	count = 1
	for T2 in Teams:
		if str(T1) >= str(T2):
			continue
		Game = S.Task('%s%s'%(T1,T2),completion_time_cost=2**count)
		Game['team_%s'%str(T1)] = 1
		Game['team_%s'%str(T2)] = 1
		Games.append(Game)
		count += 1
		Game += T1, T2
		Game += alt(Stadiums)


for Stadium in Stadiums:
	for T in Teams:
		S += Stadium['team_%s'%T][0:n_slots:3] <= 1

print(S)

#print(S)
solvers.mip.solve(S,time_limit=600,msg=1)
plotters.matplotlib.plot(S,show_task_labels=True,img_filename='tmp.png')

tmp

@timnon
Copy link
Owner

timnon commented Sep 23, 2018

Here might be a better solution for 10 teams:

  • each team plays at least 4 times at home (in the Stadium with the same number)
  • in at most 3 consecutive rounds it doesnt play at home (this includes not playing at all, which is not exactly your requirement, but its pretty close). This is the minimum such that still a solution exists. I also allow a game only happening in one of the two stadiums of the participating teams. This makes finding a solution much easier and is probably also a requirement.
from pyschedule import Scenario, solvers, plotters, alt

n_teams = 10
n_stadiums = n_teams
n_slots = n_teams-1

n_plays_at_home = 4
max_n_not_at_home_periods = 3

S = Scenario('sports_scheduline',horizon=n_slots)
Stadiums = S.Resources('Stadium',num=n_stadiums)
Teams = S.Resources('T',num=n_teams)
Team2Stadium = dict(zip(Teams,Stadiums))

Games = list()
for Team0 in Teams:
	count = 1
	for Team1 in Teams:
		if Team0.name >= Team1.name:
			continue
		Game = S.Task('%s%s'%(Team0,Team1),completion_time_cost=2**count)
		Game[Team0.name] = 1
		Game[Team1.name] = 1
		Games.append(Game)
		Game += Team0, Team1
		Game += Team2Stadium[Team0] | Team2Stadium[Team1]
		count += 1

for Team in Team2Stadium:
	Stadium = Team2Stadium[Team]
	S += Stadium[Team.name] >= n_plays_at_home
	S += Stadium[Team.name][0:n_slots:max_n_not_at_home_periods] >= 1

print(S)
solvers.mip.solve(S,time_limit=600,msg=1)
plotters.matplotlib.plot(S,show_task_labels=True,hide_resources=Teams)

Note that i am hiding the Team resources in the following plot, the Stadiums are the interesting ones:

tmp

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants