Hay un sistema bastante sencillo utilizado en, por ejemplo, torneos de ajedrez llamados round-robin.
La idea es dividir a los jugadores en los dos lados de una mesa. Uno de los jugadores se designa como "hub" (por falta de una palabra mejor). El torneo comienza por tener jugadores enfrentados que juegan uno contra el otro. Después de la primera ronda, todos menos el cubo mueven una silla hacia adelante y se cambia el orden blanco/negro (inicio/fuera en deportes). La competencia completa de round-robin finaliza cuando los jugadores se sientan en sus lugares originales. Si quieres que todos jueguen a todos dos veces, haz lo mismo otra vez.
Wikipedia article con detalles de implementación.
En su caso especial trataría de hacer el round robin una vez, incluyendo todos los equipos. Luego, haga lo mismo para cada división una vez y para asegurarse de que los equipos dentro de las divisiones se jueguen entre sí una vez en casa y una vez fuera, verifique desde la primera ronda el rumbo que jugaron los equipos en esa ronda.
La desventaja de esto es, por supuesto, que jugarás todos los partidos entre divisiones mucho antes de que finalice el torneo (ya que las últimas n-1 son contra equipos intradivisión [n = número de equipos en división]). Si esto es un problema, simplemente podría cambiar las coincidencias un poco.
De hecho, escribí un script de Python simple que hace esto. No tomó muchas líneas de código y produjo muy buenos resultados. Esto creará un cronograma donde cada equipo jugará a cada equipo en su división dos veces y una vez contra equipos en otras divisiones. Sin embargo, no existe un control para asegurarse de que los equipos se reúnan dos veces de tal manera que el mismo equipo esté en casa. Pero este código debería dar una buena idea sobre cómo crear su propio código de programación.
#!/usr/bin/python
div1 = ["Lions", "Tigers", "Jaguars", "Cougars"]
div2 = ["Whales", "Sharks", "Piranhas", "Alligators"]
div3 = ["Cubs", "Kittens", "Puppies", "Calfs"]
def create_schedule(list):
""" Create a schedule for the teams in the list and return it"""
s = []
if len(list) % 2 == 1: list = list + ["BYE"]
for i in range(len(list)-1):
mid = int(len(list)/2)
l1 = list[:mid]
l2 = list[mid:]
l2.reverse()
# Switch sides after each round
if(i % 2 == 1):
s = s + [ zip(l1, l2) ]
else:
s = s + [ zip(l2, l1) ]
list.insert(1, list.pop())
return s
def main():
for round in create_schedule(div1):
for match in round:
print match[0] + " - " + match[1]
print
for round in create_schedule(div2):
for match in round:
print match[0] + " - " + match[1]
print
for round in create_schedule(div3):
for match in round:
print match[0] + " - " + match[1]
print
for round in create_schedule(div1+div2+div3):
for match in round:
print match[0] + " - " + match[1]
print
if __name__ == "__main__":
main()
Sí, esa es la intención del código anterior :) –
@Rune: En ese caso, +1 !!!! –