2

在 Switch Doubles Round Robin Tournament(即每轮更换搭档的地方)中,尝试平均分配对手的最佳方法是什么。

例如,在 8 人锦标赛中,您将进行 7 轮比赛,并与每位玩家进行 3 或 4 次比赛,并且与每位玩家进行一次比赛。当使用“右转”方法时,打法是正确的,但对手分布不均。

4

1 回答 1

1

几年前,一位朋友请我提供一个高尔夫锦标赛循环赛的解决方案。你的问题和那个类似。以下是我将如何解决问题:

  1. 列出一次两个玩家的组合。
  2. 为每一轮做一个组合列表和
    :从您的 round_combinations 中选择一对,并且:
    i。从您的播放器组合中删除组合
    ii. 从 round_combinations 中删除所有涉及您选择的玩家的组合。
    iii. 选择第二对并从玩家组合中删除该对并从回合组合列表中删除该对。
    湾。重复直到 round_combination 列表为空
  3. 对每一轮重复步骤 2 或直到 player_combinations 列表为空。

以下是用于实现此方法的代码:

# Given
players = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H']

from itertools import combinations
from copy import deepcopy

def filterByParties(ptys:list, pairs: list([tuple])) -> list([tuple]):
    # return pairs where neither player is in ptys list
    return [x for x in pairs if ptys.count(x[0]) == 0 and ptys.count(x[1]) == 0]
#  Alternative implementation without using list comprehension
#    rslt = []
#    ptr = 0
#    while ptr < len(pairs):
#        pr = pairs[ptr]
#        if ptys.count(pr[0]) == 0 and  ptys.count(pr[1]) == 0:
#            rslt.append(pr)
#        ptr += 1
#    return rslt

def dropPair(pr:list, pairings: list([tuple])) -> list([tuple]):
    # return list of parings minus pr
    return [x for x in pairings if  pr[0] != x[0] or pr[1] != x[1]]
#  Alternative implementation without using list comprehension
#    ptr = -1
#    for i, pair in enumerate(pairings):
#        if pr[0] == pair[0] and pr[1] == pair[1]:
#            ptr = i
#            break
#    if ptr >= 0:
#        pairings.pop(ptr)
#    return pairings         

def doublesTournament(players: list([str])):
    # Given list of players, produce a listing for a doubles tennis tournament
    # Where the tournament is split into rounds of play in which all players
    # play matches with the different participants
    tournament_pairings = list(combinations(players, 2))
    tournament_rounds = len(players) -1
    matches_per_round = len(players)//4
    tournament_schedule = []
    for rnd in range(tournament_rounds):
        rnd_play_list = []
        # Make true copy of parinings for assigning match play
        match_pairings = deepcopy(tournament_pairings)
        while match_pairings:
            team_one = match_pairings.pop()
            match_pairings = filterByParties(team_one, match_pairings)
            tournament_pairings = dropPair(team_one, tournament_pairings)
            team_two = match_pairings.pop()
            match_pairings = filterByParties(team_two, match_pairings)
            tournament_pairings = dropPair(team_two, tournament_pairings) 
            rnd_play_list.append((team_one, team_two))
        tournament_schedule.append(rnd_play_list)
    for r, round_play in enumerate(tournament_schedule):
        print(f'Round {r+1}')
        for m, match_play in enumerate(round_play):
            print(f'\tMatch {m+1}:  {match_play[0]} vs {match_play[1]}')  

doublesTournament(players) 

产量:

Round 1
    Match 1:  ('G', 'H') vs ('E', 'F')
    Match 2:  ('C', 'D') vs ('A', 'B')
Round 2
    Match 1:  ('F', 'H') vs ('E', 'G')
    Match 2:  ('B', 'D') vs ('A', 'C')
Round 3
    Match 1:  ('F', 'G') vs ('E', 'H')
    Match 2:  ('B', 'C') vs ('A', 'D')
Round 4
    Match 1:  ('D', 'H') vs ('C', 'G')
    Match 2:  ('B', 'F') vs ('A', 'E')
Round 5
    Match 1:  ('D', 'G') vs ('C', 'H')
    Match 2:  ('B', 'E') vs ('A', 'F')
Round 6
    Match 1:  ('D', 'F') vs ('C', 'E')
    Match 2:  ('B', 'H') vs ('A', 'G')
Round 7
    Match 1:  ('D', 'E') vs ('C', 'F')
    Match 2:  ('B', 'G') vs ('A', 'H')
于 2021-11-24T15:27:52.610 回答