从N个玩家中生成每个可能的匹配,并创建N-1组,每组N/2个匹配



我正在尝试编写一个脚本,从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个顶点上制作一个完整的图,将除一个顶点外的所有顶点都放在正多边形上,其中一个顶点在中心。然后,我们做一个边着色。每个顶点与每个边颜色恰好入射一次。然后,这些颜色代表锦标赛的轮次,每个彩色边代表该轮次中的一对端点。

让我们把包括中心顶点的边称为"边";中心边缘";。我们通过以下方式形成着色:

  1. 首先对中心边缘使用所有颜色(圆形(
  2. 然后,将垂直于给定中心边的所有边着色为该中心边的颜色

例如,12个顶点标记为0-11,11个圆形标记为0-10,"颜色"。

  1. 将顶点11视为中心顶点
  2. 用颜色i给从11到i的边缘上色
  3. 对于{1,2,3,4,5}中的j,使用颜色i进行配对/颜色边缘(mod(i-j,11(,mod(i+j,11

圆形配对:

  1. (11,0(、(10,1(、
  2. (11,1(、(0,2(、(10,3(、(9,4(、(8,5(、(7,6(
  3. (11,2(、(1,3(、(0,4(、(10,5(、(9,6(、(8,7(
  4. (11,3(、(2,4(、(1,5(、(0,6(、(10,7(、(9,8(
  5. (11,4(、(3,5(、(2,6(、(1,7(、(0,8(、(10,9(
  6. (11,5(、(4,6(、(3,7(、(2,8(、(1,9(、(0,10(
  7. (11,6(、(5,7(、(4,8(、(3,9(、(2,10(、(1,0(
  8. (11,7(、(6,8(、(5,9(、(4,10(、(3,0(、(2,1(
  9. (11,8(、(7,9(、(6,10(、(5,0(、(4,1(、(3,2(
  10. (11,9(、(8,10(、(7,0(、(6,1(、(5,2(、(4,3(
  11. (11,10(、(9,0(、(8,1(、(7,2(、(6,3(、(5,4(

相关内容

最新更新