我正在尝试编写一个脚本,从N
玩家生成每一个可能的1v1比赛,然后创建N/2
玩家的N-1
组(天(,这样每天每个人都会比赛,到所有N-1
天结束时,每个玩家都会与所有其他玩家比赛。
就我而言:
N
=12名玩家N-1
=11天N/2
=每天6场比赛Number of matches
=公式
我写了下面的脚本,但效果不太好。我使用player_combinations()
生成每个可能的匹配。然后,我迭代N-1
次以创建N-1
组(天(。我确保每天只包括一个给定的玩家一次,在进入第二天之前,我从combinations
中减去day
并清除day
,这样我就不会使用同一场比赛两次。
问题是,在运行脚本后,并不是每个组都有相同数量的参与者,而且匹配的总数加起来也不正确(更低(。
我该怎么办?有没有一种简单的方法(也许是分区、排列等(可以解决我没有看到的这个问题?
脚本:
from itertools import combinations
def player_combinations(players):
return [' - '.join(i) for i in combinations(players, 2)]
p = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L']
combinations = player_combinations(p)
day = []
for i in range(len(p)-1):
for pair in combinations:
if not any(pair.split(' - ')[0] in participants for participants in day) and not any(pair.split(' - ')[1] in participants for participants in day):
day.append(pair)
for participants in day:
print(participants)
print()
for participants in day:
if participants in combinations:
combinations.remove(participants)
day.clear()
我使用下面的参考为您的示例制作了一个循环类型的脚本。这将以一种特殊的方式将每个玩家配对,以确保每轮中所有或几乎所有(在奇数玩家的情况下(玩家的回合数最少
此处引用:https://nrich.maths.org/1443
import math
def shuffle(players): # rotate the values in players so the last player is first and everyone else is shifted one down
shuffled = list(players[-1])
shuffled.extend(players[:-1])
return shuffled
def pair_up_players(players, shuffled_players): # pair up the values in players, round robin style
pairs = []
idx_left_side_players = range(math.floor(len(shuffled_players)/2))
for idx in idx_left_side_players:
p1 = shuffled_players[idx]
p2 = shuffled_players[-idx-1-len(shuffled_players)%2]
pairs.append((p1, p2))
# if even number of players, pair up the last shuffled player with the last player in players
if len(players) % 2 == 0:
p1 = shuffled_players[-1]
p2 = players[-1]
pairs.append((p1, p2))
return pairs
players = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L']
num_players = len(players)
rounds_to_play = num_players - 1 + num_players%2
result = []
# we shuffle all or all but the last player depending if num_players is even or odd
if num_players % 2 == 0: # even, shuffle all players except for the last one, which is static
shuffled_players = players[:-1]
else:
shuffled_players = players # shuffle all players around
# loop the rounds
for round in range(rounds_to_play):
print(shuffled_players)
result.append(pair_up_players(players, shuffled_players))
shuffled_players = shuffle(shuffled_players)
print(result)
答案如下:https://math.stackexchange.com/questions/1477767/efficiently-partition-a-set-into-all-possible-unique-pair-combinations
这个想法是在N个顶点上制作一个完整的图,将除一个顶点外的所有顶点都放在正多边形上,其中一个顶点在中心。然后,我们做一个边着色。每个顶点与每个边颜色恰好入射一次。然后,这些颜色代表锦标赛的轮次,每个彩色边代表该轮次中的一对端点。
让我们把包括中心顶点的边称为"边";中心边缘";。我们通过以下方式形成着色:
- 首先对中心边缘使用所有颜色(圆形(
- 然后,将垂直于给定中心边的所有边着色为该中心边的颜色
例如,12个顶点标记为0-11,11个圆形标记为0-10,"颜色"。
- 将顶点11视为中心顶点
- 用颜色i给从11到i的边缘上色
- 对于{1,2,3,4,5}中的j,使用颜色i进行配对/颜色边缘(mod(i-j,11(,mod(i+j,11
圆形配对:
- (11,0(、(10,1(、
- (11,1(、(0,2(、(10,3(、(9,4(、(8,5(、(7,6(
- (11,2(、(1,3(、(0,4(、(10,5(、(9,6(、(8,7(
- (11,3(、(2,4(、(1,5(、(0,6(、(10,7(、(9,8(
- (11,4(、(3,5(、(2,6(、(1,7(、(0,8(、(10,9(
- (11,5(、(4,6(、(3,7(、(2,8(、(1,9(、(0,10(
- (11,6(、(5,7(、(4,8(、(3,9(、(2,10(、(1,0(
- (11,7(、(6,8(、(5,9(、(4,10(、(3,0(、(2,1(
- (11,8(、(7,9(、(6,10(、(5,0(、(4,1(、(3,2(
- (11,9(、(8,10(、(7,0(、(6,1(、(5,2(、(4,3(
- (11,10(、(9,0(、(8,1(、(7,2(、(6,3(、(5,4(