VB.NET英超风格足球联赛循环赛调度算法实现求助
VB.NET 20队主客场循环赛赛程生成方案
问题核心
你需要实现20支球队的双循环赛制:每队与其余19队各踢主客场1次,总计38轮赛事,每轮10场比赛,每队每轮仅参赛1场,且主客场次数严格各为19次。你的随机配对算法存在以下致命问题:
- 随机选队易导致某轮剩余球队无法找到未交手对手,出现赛程断层
- 未控制主客场次数平衡,可能出现某队主场/客场次数超标
- 循环逻辑冗余(定义的
totalRounds变量未实际使用),无法保证每轮凑齐10场比赛
正确实现思路
采用标准循环赛调度算法:先生成19轮单循环赛程,再将每一场的主客场翻转,生成另一组19轮赛程,合并后得到完整的38轮双循环赛程。该方法能严格保证每队的交手次数、主客场次数完全符合要求。
VB.NET 实现代码
Sub CreateFixtures() Dim teamCount As Integer = ClubList.Count If teamCount Mod 2 <> 0 Then Throw New ArgumentException("球队数量必须为偶数") End If Dim totalSingleRounds As Integer = teamCount - 1 ' 单循环轮次 Dim fixtures As New List(Of Match) ' 存储所有赛程信息 ' 步骤1:生成19轮单循环赛程 For round As Integer = 1 To totalSingleRounds Dim roundFixtures As New List(Of Match) For matchIndex As Integer = 0 To (teamCount \ 2) - 1 Dim homeTeam As ClubClass Dim awayTeam As ClubClass ' 固定首支球队,其余球队按轮转规则配对 If matchIndex = 0 Then homeTeam = ClubList(0) awayTeam = ClubList((round + matchIndex - 1) Mod (teamCount - 1) + 1) Else homeTeam = ClubList((round + matchIndex - 1) Mod (teamCount - 1) + 1) awayTeam = ClubList((round - matchIndex) Mod (teamCount - 1) + 1) End If ' 添加单循环主场比赛 roundFixtures.Add(New Match With { .MatchID = fixtures.Count, .HomeTeam = homeTeam, .AwayTeam = awayTeam, .Round = round }) fixtures.Add(roundFixtures.Last()) Next ' 输出单循环轮次信息 Debug.WriteLine($"轮次 {round}") For Each m In roundFixtures Debug.WriteLine($"{m.HomeTeam.name} vs {m.AwayTeam.name}") ' 标记两队已完成交手 m.HomeTeam.MarkAsPlayedAgainst(m.AwayTeam) m.AwayTeam.MarkAsPlayedAgainst(m.HomeTeam) Next Next ' 步骤2:生成主客场翻转的19轮赛程(轮次20-38) For originalRound As Integer = 1 To totalSingleRounds Dim newRound As Integer = totalSingleRounds + originalRound Dim originalRoundFixtures = fixtures.Where(Function(f) f.Round = originalRound).ToList() Dim reversedFixtures As New List(Of Match) For Each originalMatch In originalRoundFixtures ' 翻转主客场生成新比赛 reversedFixtures.Add(New Match With { .MatchID = fixtures.Count, .HomeTeam = originalMatch.AwayTeam, .AwayTeam = originalMatch.HomeTeam, .Round = newRound }) fixtures.Add(reversedFixtures.Last()) Next ' 输出翻转后轮次信息 Debug.WriteLine($"轮次 {newRound}") For Each m In reversedFixtures Debug.WriteLine($"{m.HomeTeam.name} vs {m.AwayTeam.name}") Next Next End Sub ' ClubClass补充交手状态标记方法 Partial Class ClubClass Private playedAgainst As New List(Of ClubClass) Public Function HasPlayedAgainst(team As ClubClass) As Boolean Return playedAgainst.Contains(team) End Function Public Sub MarkAsPlayedAgainst(team As ClubClass) If Not playedAgainst.Contains(team) Then playedAgainst.Add(team) End If End Sub End Class ' 赛程信息存储类 Class Match Public Property MatchID As Integer Public Property HomeTeam As ClubClass Public Property AwayTeam As ClubClass Public Property Round As Integer End Class
代码说明
- 单循环调度:固定首支球队,其余球队按轮转规则配对,确保每轮所有球队都有唯一对手,无重复交手
- 双循环生成:通过翻转单循环赛程的主客场,直接生成第20-38轮赛事,保证每队主客场次数各19次
- 状态管理:通过
MarkAsPlayedAgainst方法记录交手状态,避免重复配对 - 轮次控制:严格保证38轮赛事,每轮恰好10场比赛,完全符合赛事规则
内容的提问来源于stack exchange,提问作者ShakeyGames
相关产品推荐
相关产品推荐

