python - 比赛问题
问题描述
我们有一个小任务来创建 n 支球队的锦标赛,每支球队必须在 o 场上按照 3 条规则进行 m 场比赛:
- 一场比赛不得超过一次
- 一支球队不能与自己对抗
- 在锦标赛的任何给定时间,一支球队参加比赛的次数之差不能大于一。
下面的代码解决了这个问题,但显然非常非常慢。我知道有一个解决方案快一百万倍(并且也在 C++ 中,但我不相信这会产生超过一千倍的差异),但不知道该代码。
有没有人有关于使下面的代码更快的建议。应该进行回溯以寻找答案(允许的比赛)。Evaluate 查看锦标赛是否仍然允许,如果锦标赛仍然有效,extend 会继续(递归地)从 all_possible_games 堆栈中添加游戏。E 指定一个空字段,仅在最后一轮中允许。对于不同领域的 2-30 个团队等,该程序运行良好。但是 50 个球场上的 100 支球队,每支球队 10 场比赛应该可以在 0.001 秒内解决。这个程序需要几个小时...
import math
def printtournament(tournament):
for gameround in grouped(tournament, fields):
for game in sorted(gameround, key=lambda x: x[0] if isinstance(x[0], int) else 0):
if game[0] != 'E':
print(game, end='')
print()
print()
def grouped(iterable, n):
return zip(*[iter(iterable)]*n)
def allgames(teamcount):
games = []
for t in range(teamcount):
for u in range(teamcount):
if u is not t:
game = (u, t)
game = sorted(game, reverse=False)
if game not in games:
games.append(game)
return games
def evaluate(tournament, fieldcount, gamesperteam, teamcount):
current_games_per_team = {}
for i in range(teamcount):
current_games_per_team[i] = 0
current_games_per_team['E'] = 0
gamehasbeenplayed = []
current_games_per_team_round = {}
for i in range(teamcount):
current_games_per_team_round[i] = 0
current_games_per_team_round['E'] = 0
for gameround in grouped(tournament, fieldcount):
teamhasplayed = []
for game in (gameround):
for t in game:
if t in teamhasplayed and t is not 'E':
return False
else:
teamhasplayed.append(t)
if game in gamehasbeenplayed and game[0] is not 'E' and game[1] is not 'E':
return False
else:
gamehasbeenplayed.append(game)
current_games_per_team[int(game[0]) if isinstance(game[0], int) else 'E'] += 1
current_games_per_team[int(game[1]) if isinstance(game[0], int) else 'E'] += 1
current_games_per_team_round[int(game[0]) if isinstance(game[0], int) else 'E'] += 1
current_games_per_team_round[int(game[1]) if isinstance(game[0], int) else 'E'] += 1
for k, c in current_games_per_team.items():
if c > gamesperteam and k is not 'E':
return False
for k1, c in current_games_per_team_round.items():
for k2, d in current_games_per_team_round.items():
if abs(c - d) > 1 and k1 is not 'E' and k2 is not 'E':
return False
return True
def extend(gamecount, games, teams, fields, gamesperteam):
if gamecount < games:
for game in all_possible_games:
tournament[gamecount] = game
for i in range(fieldrounds):
if i > gamecount:
tournament[i] = ['E', 'E']
if evaluate(tournament, fields, gamesperteam, teams):
extend(gamecount+1, games, teams, fields, gamesperteam)
else:
printtournament(tournament)
teams = 30
fields = 4
gamesperteam = 2
games = int(teams/2*gamesperteam)
fieldrounds = int(math.ceil(games/fields)*fields)
all_possible_games = allgames(teams)
tournament = []
for i in range(fieldrounds):
tournament.append(['E', 'E'])
if __name__ == '__main__':
extend(0, games, teams, fields, gamesperteam)
解决方案
推荐阅读
- javascript - JS - IntersectionObserver - 参数 1 未实现接口元素
- excel-formula - 使用 TEXTJOIN 在之间添加“和”
- javascript - 将侦听器绑定到动态创建的元素
- mongodb - 使用 node/express 从 MongoDB 获取数据
- python - Jupyter Notebook:找不到与 python 3 匹配的内核
- javascript - 在用户选择至少一个复选框之前,如何设置下一个按钮不可用?
- vba - 允许在 MS Access 表单的文本框中添加数据但不允许删除数据
- android - Android TV:如何添加密码操作
- javascript - 无法读取 null 的属性“getSheetId”;不知道为什么会这样
- asp.net - 如何使用 axios 将文件上传 POST 到 ASP.NET 控制器?