Estoy buscando un algoritmo para generar un cronograma para un conjunto de equipos . Por ejemplo, imagine una temporada deportiva en la que cada equipo juegue entre sí, una vez como equipo de casa y la otra como un equipo visitante en campo de otro equipo.Generando un cronograma natural para una liga deportiva
Para generar un conjunto de todos los partidos en la temporada es fácil, si los equipos es una lista de los equipos de la siguiente haría:
set((x, y) for x in teams for y in teams if x != y)
Pero también quiero pedir los juegos en orden cronológico en tales una forma que cumple la restricción de un horario de juego válido y también parece "naturalmente aleatorio".
La restricción es que la lista de juegos debe ser agrupables en una serie de rondas en las cada ronda consta de n/2 juegos (donde N es el número de equipos ) en el que cada equipo está emparejado con otro.
Para hacer que el horario parezca más natural, dos equipos no deben enfrentar cada otro dos veces en rondas consecutivas. Es decir, si (a, b) se juega en una ronda , el juego (b, a) no debe jugarse en el campo ext.
Además, tanto como sea posible, todos los equipos deben jugar cada dos asaltos como el equipo visitante y las otras rondas como el equipo local. No creo que es posible cumplir siempre esta restricción, por lo que es más agradable tener . Por ejemplo, un equipo no debería jugar 8 partidos en casa y , luego 8 juegos fuera.
A continuación se muestra lo que obtuve ahora. El principal problema con el algoritmo es que se queda atascado en el while-loop con bastante frecuencia. Especialmente cuando el número de equipos es 16 o más. También es muy ineficiente porque se basa en el uso de la función muestra aleatoria y con la esperanza de hacerlo bien:
from random import sample
def season_schedule_order(teams, pairs):
n_games_per_round = len(teams) // 2
last_pairs = set()
while pairs:
r_pairs = set(sample(pairs, n_games_per_round))
# Check that each team is present once in the round.
r_teams = set(x for (x, y) in r_pairs) | set(y for (x, y) in r_pairs)
if r_teams != teams:
continue
# Check that two teams doesn't face each other again.
rev_pairs = set((y, x) for (x, y) in r_pairs)
if rev_pairs & last_pairs:
continue
pairs -= r_pairs
for p in r_pairs:
yield p
last_pairs = r_pairs
teams = set(['aik', 'djurgarden', 'elfsborg', 'gais',
'gefle', 'hacken', 'halmstad', 'helsingborg'])
pairs = set((x, y) for x in teams for y in teams if x != y)
for (ht, at) in season_schedule_order(teams, pairs):
print '%-20s %-20s' % (ht, at)
Produce [[('1', '5 '), (' 2 ',' 4 ')], [(' 4 ',' 1 '), (' 3 ',' 5 ')], [(' 1 ',' 3 '), (' 4 ',' 2 ')], [(' 2 ',' 1 '), (' 5 ',' 3 ')]] por ejemplo 5 equipos con sets = Ninguno. Que NO es correcto El equipo '2' juega contra '4' dos veces y no contra '3', '5'. Esta NO es la respuesta correcta. – Scrontch