我不确定如何说出这个问题...任何建议或编辑都将不胜感激!
我正试图获得联赛赛程的所有可能性。我 8支球队在 12周中相互比赛。每周有四个时段,其中一对队伍将参加比赛。
How to split a list into pairs in all possible ways为我提供了一个解决方案:
Ex:
(0, 1) is the same as (1, 0)
but
[(0, 1), (2, 3), (4, 5), (6, 7)]
is not the same as
[(2, 3), (0, 1), (4, 5), (6, 7)]
等等。似乎有105 = 15 * 7这样的对。
然而,这些并非所有对。由于我有四个小组可以玩的时间段,列表中这些对的顺序可以改变。
schedules = list(itertools.combinations(<all_possible_4-pair_matchups>, 12))
我想最终拥有所有可能的12对4对比赛,其中没有球队将比其他球队多出2次。
如果我要通过以下方式创建所有可能的时间表:
# Author: Abraham Glasser, abrahamglasser@gmail.com
#
# This program determines if there's a schedule where
# each team will play at a specific hour exactly 3 times
#
# 12 weeks
# 8 teams
# 4 hours per week
from pandas import *
teams = [i for i in range(8)]
twelve_weeks = [[[-1 for i in range(2)] for j in range(4)] for k in range(12)]
# table to count how many times a team
# has played at a specific time slot
hour_count = [[0 for i in range(4)] for j in range(8)]
# table to count how many times two teams have played each other
game_count = [[0 for i in range(8)] for j in range(8)]
for i in range(8):
# a team cannot play against itself
game_count[i][i] = "X"
# function to update game count
def update_game_count():
for week in twelve_weeks:
for hour in week:
if hour[0] == -1:
pass
else:
game_count[hour[0]][hour[1]] += 1
game_count[hour[1]][hour[0]] += 1
# function to update hour count
def update_hour_count():
for week in twelve_weeks:
for hour in range(4):
pair = week[hour]
for team in teams:
if team in pair:
hour_count[team][hour] += 1
# solution from
# https://stackoverflow.com/questions/5360220/how-to-split-a-list-into-pairs-in-all-possible-ways
def all_pairs(lst):
if len(lst) < 2:
yield lst
return
a = lst[0]
for i in range(1,len(lst)):
pair = (a,lst[i])
for rest in all_pairs(lst[1:i]+lst[i+1:]):
yield [pair] + rest
x = list(all_pairs([0, 1, 2, 3, 4, 5, 6, 7]))
# TAKES TOO LONG AND DOES NOT ACCOUNT
# FOR TEAMS PLAYING MORE THAN TWICE
#
# schedules = list(itertools.combinations(x, 12))
# pretty printing
print("\nThe twelve weeks:")
print(DataFrame(twelve_weeks))
print("\n The hour counts:")
print(DataFrame(hour_count))
print("\n The game counts:")
print(DataFrame(game_count))
效率非常低,需要很长时间才能运行。这种方法没有考虑到一支球队是否已经打了另外两支球队。
到目前为止我有这个代码:
<button class="navbar-toggler navbar-ligh" ... \>
答案 0 :(得分:0)
您对解决方案的数量有所估计吗? 如果这个数字太大,那么就没有办法列出所有这些配对。
我做了一种递归方法,以某种树状方式列出所有可能性。
这是:
import itertools
import numpy as np
n = 6
weeks = 8
def all_pairs(lst):
if len(lst) < 2:
yield lst
return
a = lst[0]
for i in range(1,len(lst)):
pair = (a,lst[i])
for rest in all_pairs(lst[1:i]+lst[i+1:]):
yield [pair] + rest
def recurse(so_far, rem_list, count):
if len(so_far) == weeks: return [so_far]
res = []
for current in range(len(rem_list)):
match = rem_list[current]
new_count = count.copy()
for pair in match:
new_count[pair[0],pair[1]] += 1
new_count[pair[1],pair[0]] += 1
#set of pairs, whcih are not allowed any more
forbidden = {(i,j) for i in range(n) for j in range(n) if new_count[i,j] == 2}
#append current match, remove all now forbidden combinations
res += recurse(so_far + [match], [entry for entry in rem_list[(current+1):] if set(entry) & forbidden == set([])], new_count)
return res
l = list(all_pairs(list(range(n))))
foo = recurse([], l, np.zeros((n,n)))