python - 考虑到某些限制,随机化循环赛赛程

标签 python python-3.x algorithm random sports-league-scheduling-problem

我正在尝试编写一个脚本来随机化锦标赛的循环赛时间表。

约束条件是:

  • 8队
  • 两队交手两次,一次主场一次客场
  • 14 周,每周每队一场比赛

  • 我的代码在理论上运行良好,但是当它生成时,它有时会在某些周卡住,因为该周只剩下两支球队,而且两个可能的比赛都已经进行了。我使用一个 numpy 数组来检查已经进行了哪些比赛。

    目前我的代码如下所示:
    import random
    import numpy
    
    regular_season_games = 14
    regular_season_week = 0
    
    checker = numpy.full((8,8), 0)
    
    for x in range (0,8):
        checker[x][x] = 1
    
    teams_left = list(range(8))
    
    print ("Week " + str(regular_season_week+1))
    
    while (regular_season_week < regular_season_games):
    
        game_set = False
        get_away_team = False
    
        while get_away_team == False:
            Team_A = random.choice(teams_left)
            if 0 in checker[:,Team_A]:
                for x in range (0,8):
                    if checker[x][Team_A] == 0 and x in teams_left:
                        teams_left.remove(Team_A)
                        get_away_team = True
                        break
    
        while game_set == False:
            Team_B = random.choice(teams_left)
            if checker[Team_B][Team_A] == 0:
                teams_left.remove(Team_B)
                print(str(Team_A) + " vs " + str(Team_B))
                checker[Team_B][Team_A] = 1
                game_set = True
    
        if not teams_left:
            print ("Week " + str(regular_season_week+2))
            teams_left = list(range(8))
            regular_season_week = regular_season_week + 1
    

    最佳答案

    我使用了来自 here 的调度算法的改编版本。为达到这个。基本上,我们生成一个团队列表 - list(range(8)) - 并选择作为我们的初始匹配0 vs 4, 1 vs 5, 2 vs 6, 3 vs 7 .然后我们旋转列表,不包括第一个元素,并选择作为我们的下一个匹配 0 vs 3, 7 vs 4, 1 vs 5, 2 vs 6 .我们以以下方式继续,直到我们完成每一个配对。

    我为主客场比赛添加了一个处理程序 - 如果已经进行了配对,我们将进行相反的主客场配对。下面是代码,包括一个检查游戏列表是否有效的函数,以及一个示例输出。

    代码:

    import random
    
    # Generator function for list of matchups from a team_list
    def games_from_list(team_list):
        for i in range(4):
            yield team_list[i], team_list[i+4]
    
    # Function to apply rotation to list of teams as described in article
    def rotate_list(team_list):
        team_list = [team_list[4]] + team_list[0:3] + team_list[5:8] + [team_list[3]]
        team_list[0], team_list[1] = team_list[1], team_list[0]
        return team_list
    
    # Function to check if a list of games is valid
    def checkValid(game_list):
        if len(set(game_list)) != len(game_list):
            return False
        for week in range(14):
            teams = set()
            this_week_games = game_list[week*4:week*4 + 4]
            for game in this_week_games:
                teams.add(game[0])
                teams.add(game[1])
            if len(teams) < 8:
                return False
        else:
            return True
    
    
    # Generate list of teams & empty list of games played
    teams = list(range(8))
    games_played = []
    
    # Optionally shuffle teams before generating schedule
    random.shuffle(teams)
    
    # For each week -
    for week in range(14):
        print(f"Week {week + 1}")
    
        # Get all the pairs of games from the list of teams.
        for pair in games_from_list(teams):
            # If the matchup has already been played:
            if pair in games_played:
                # Play the opposite match
                pair = pair[::-1]
    
            # Print the matchup and append to list of games.
            print(f"{pair[0]} vs {pair[1]}")
            games_played.append(pair)
    
        # Rotate the list of teams
        teams = rotate_list(teams)
    
    # Checks that the list of games is valid 
    print(checkValid(games_played))
    

    示例输出:
    Week 1
    0 vs 7
    4 vs 3
    6 vs 1
    5 vs 2
    Week 2
    0 vs 3
    7 vs 1
    4 vs 2
    6 vs 5
    Week 3
    0 vs 1
    3 vs 2
    7 vs 5
    4 vs 6
    Week 4
    0 vs 2
    1 vs 5
    3 vs 6
    7 vs 4
    Week 5
    0 vs 5
    2 vs 6
    1 vs 4
    3 vs 7
    Week 6
    0 vs 6
    5 vs 4
    2 vs 7
    1 vs 3
    Week 7
    0 vs 4
    6 vs 7
    5 vs 3
    2 vs 1
    Week 8
    7 vs 0
    3 vs 4
    1 vs 6
    2 vs 5
    Week 9
    3 vs 0
    1 vs 7
    2 vs 4
    5 vs 6
    Week 10
    1 vs 0
    2 vs 3
    5 vs 7
    6 vs 4
    Week 11
    2 vs 0
    5 vs 1
    6 vs 3
    4 vs 7
    Week 12
    5 vs 0
    6 vs 2
    4 vs 1
    7 vs 3
    Week 13
    6 vs 0
    4 vs 5
    7 vs 2
    3 vs 1
    Week 14
    4 vs 0
    7 vs 6
    3 vs 5
    1 vs 2
    True
    

    关于python - 考虑到某些限制,随机化循环赛赛程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59355915/

    相关文章:

    python - 网络爬行期间的速度问题 (Python)

    python - Django模板更新后没有改变(可能是缓存)

    python - 如何将中点圆算法 "translate"导入matplotlib?

    python 基维 : hide virtual keyboard in Text Input Field

    Python:如何使从列表继承的类能够访问第一个元素?

    python - 我正在尝试检测按下的某个键(Python)

    python - OrderedDict 在 Python 3.7 中会变得多余吗?

    python - 运行 flake8 给出 - AttributeError : 'OptionManager' object has no attribute 'config_options'

    python - 以最小成本包围点的最小圆

    algorithm - PCG伪迷宫算法?