单轮Round-Robin循环赛赛程随机生成算法实现问题求助
单轮循环赛对阵生成问题修复方案
现有代码问题梳理
你的实现存在3个核心逻辑漏洞:
- 无失败重置机制:遇到球队找不到可配对对手时仅执行
continue跳过,不会清空已生成的无效配对,直接标记赛程有效,最终输出的赛程必然缺漏、不符合规则 - 未维护已占用球队池:没有排除本轮已经参赛(不管作为主场还是客场)的球队,会出现多支球队选同一个主场、同一支球队一轮参赛多次的冲突
- 无合法性校验:没有校验最终生成的赛程是否满足所有球队仅参赛一次、历史未交战的规则
调整后实现逻辑
每次配对尝试前清空所有临时状态,只要任意一支球队配对失败立刻终止本轮尝试、重新开始,直到生成完全符合规则的赛程,代码如下:
import random # 全局球队列表,12支球队示例,可根据实际场景修改 teams = list(range(1, 13)) def findAvailableOpps(away_team, playedMatchups, used_teams): """ 过滤可用主场球队: 1. 不能是客场球队自身 2. 历史上没有和当前客场球队对阵过 3. 本轮还没有作为主/客场参赛 """ available = [ home_team for home_team in teams if home_team != away_team and (away_team, home_team) not in playedMatchups and home_team not in used_teams ] return available if available else False def chooseOpponent(availableOpps): """从可用主场列表随机选一个""" return random.choice(availableOpps) if availableOpps else False def findNextMatchups(playedMatchups): scheduleGood = False final_schedule = [] while not scheduleGood: # 每轮尝试前重置所有临时变量,避免上轮失败残留数据干扰 tentativeSchedule = [] used_teams = set() match_success = True # 随机打乱客场球队遍历顺序,大幅降低配对失败概率 shuffled_away_teams = random.sample(teams, len(teams)) for away_team in shuffled_away_teams: # 已经作为主场参赛过的球队跳过 if away_team in used_teams: continue available_home = findAvailableOpps(away_team, playedMatchups, used_teams) home_team = chooseOpponent(available_home) if not home_team: # 配对失败,标记本轮无效直接跳出重试 match_success = False break tentativeSchedule.append((away_team, home_team)) # 把主客场球队都加入已使用集合,避免本轮重复参赛 used_teams.add(away_team) used_teams.add(home_team) # 校验本轮配对是否完整合法:所有球队都成功配对 if match_success and len(used_teams) == len(teams): scheduleGood = True final_schedule = tentativeSchedule return final_schedule
调用示例
# 历史对阵数据示例,存所有已完成的(客场,主场)元组 played = [(1,3), (2,1), (3,4), (4,2)] next_round = findNextMatchups(played) # 输出格式为 客场 @ 主场 for away, home in next_round: print(f"{away} @ {home}")
内容的提问来源于stack exchange,提问作者ryan
相关产品推荐
相关产品推荐

