python - 创建循环赛,替代解决方案?

标签 python sports-league-scheduling-problem

teams = ["Atletico","Barcelona","Real Madrid", "Sevilla", "Atletic Bilbao ", "Granada", "Mallorca","Valencia"]

我们有一组团队想要创建一个锦标赛名称。可以是任何锦标赛,任何数量的球队(不是奇数)。

我想创建一个循环赛,基本上,所有团队都与所有其他团队比赛。

我创建了一种解决方案:

weeks=[]
def schedule(teams):
    teams = list(teams)
    n = len(teams)
    for a in range(n - 1):
        b = zip(teams[:n // 2], reversed(teams[n // 2:]))
        weeks.append(list(b))
        teams.insert(1, teams.pop())
    print(weeks)
    return weeks

schedule(teams)

这个解决方案虽然不是最优的,因为我正在考虑周到的主场和客场状态。 1) 一组团队总是在家,另一组总是不在,并且 2) 不是随机的。

我想要一个解决方案,每周随机匹配这些对,但他们之前没有玩过。我如何才能继续跟踪已经安排了哪些比赛?

最佳答案

我只是想向您指出解决方案,但我厌倦了尝试在评论中解释,所以:

解决方法:

import random

teams = ["Atletico", "Barcelona", "Real Madrid", "Sevilla", "Atletic Bilbao ", "Granada", "Mallorca", "Valencia"]
pairs = [(i, j) for i in teams for j in teams if i != j]
random.shuffle(pairs)

numWeeks = len(teams) - 1
numPairs = len(teams)//2
matchUps = {}
for week in range(numWeeks):
    matchUps[f'Week {week}'] = []
    for _ in range(numPairs):
        for pair in pairs:
            if pair[0] not in [team for match in matchUps[f'Week {week}'] for team in match]:
                if pair[1] not in [team for match in matchUps[f'Week {week}'] for team in match]:
                    if pair not in [match for w in range(week) for match in matchUps[f'Week {w}']] and (pair[1], pair[0]) not in [match for w in range(week) for match in matchUps[f'Week {w}']]:
                        break
        matchUps[f'Week {week}'].append(pair)

print(matchUps)

输出:

{'Week 0': [('Granada', 'Sevilla'), 
            ('Mallorca', 'Barcelona'), 
            ('Real Madrid', 'Atletic Bilbao '), 
            ('Atletico', 'Valencia')], 
 'Week 1': [('Atletic Bilbao ', 'Sevilla'), 
            ('Granada', 'Atletico'), 
            ('Mallorca', 'Valencia'), 
            ('Real Madrid', 'Barcelona')], 
 'Week 2': [('Sevilla', 'Mallorca'), 
            ('Atletic Bilbao ', 'Barcelona'), 
            ('Valencia', 'Granada'), 
            ('Atletico', 'Real Madrid')], 
 'Week 3': [('Sevilla', 'Valencia'), 
            ('Atletico', 'Barcelona'), 
            ('Granada', 'Real Madrid'), 
            ('Mallorca', 'Atletic Bilbao ')], 
 'Week 4': [('Sevilla', 'Real Madrid'), 
            ('Atletico', 'Mallorca'), 
            ('Granada', 'Barcelona'), 
            ('Atletic Bilbao ', 'Valencia')], 
 'Week 5': [('Granada', 'Mallorca'), 
            ('Sevilla', 'Barcelona'), 
            ('Valencia', 'Real Madrid'), 
            ('Atletico', 'Atletic Bilbao ')], 
 'Week 6': [('Sevilla', 'Atletico'), 
            ('Barcelona', 'Valencia'), 
            ('Real Madrid', 'Mallorca'), 
            ('Atletic Bilbao ', 'Granada')]}

这会得到评论中显示的对:

teams = ["Atletico", "Barcelona", "Real Madrid", "Sevilla", "Atletic Bilbao ", "Granada", "Mallorca", "Valencia"]
pairs = [(i, j) for i in teams for j in teams if i != j]

然后它随机化:

random.shuffle(pairs)

然后得到需要的周数和每周需要的对数:

numWeeks = len(teams) - 1
numPairs = len(teams)//2

然后它在几周内循环(每次都创建一个新的一周):

for week in range(numWeeks):
    matchUps[f'Week {week}'] = []

然后它遍历每个需要的对:

for _ in range(numPairs):

对于每个对要求,它循环遍历无重复列表以找到未使用的对:

        for pair in pairs:
            if pair[0] not in [team for match in matchUps[f'Week {week}'] for team in match]:
                if pair[1] not in [team for match in matchUps[f'Week {week}'] for team in match]:
                    if pair not in [match for w in range(week) for match in matchUps[f'Week {w}']] and (pair[1], pair[0]) not in [match for w in range(week) for match in matchUps[f'Week {w}']]:
                        break

一旦找到可以使用的一对,它就会把它放在一周中:

matchUps[f'Week {week}'].append(pair)

注意:这会给出随机的主场/客场分配,但您可以更改:

numWeeks = len(teams) - 1

到:

numWeeks = (len(teams) - 1)*2

这将进行双循环赛,每支球队在主场一次,每支球队在客场一次。 (为此,您需要进行一些小的逻辑更改。)

关于python - 创建循环赛,替代解决方案?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71355474/

相关文章:

算法调度,多队循环赛/比赛

python - 生成所有唯一对排列

php - 循环调度器填写 "byes"

python - 如何正确地将 numpy 数组传递给 Cython 函数?

python - 如何使 declarative_base 派生类符合接口(interface)?

python - 正则表达式与我认为应该匹配的不匹配

Python Pandas 茎叶图

python - 创建一个从特定点倒数的新列

algorithm - 学生积木组合设计

algorithm - 安排 16 队 1v1 比赛,6 种不同的比赛类型