PHP实现Round-Robin算法:主客场分配问题求助
搞定Round-Robin算法的主客场分配问题
嘿,看起来你在实现双循环Round-Robin赛程时,主客场分配这块卡壳了,我来帮你梳理问题并给出可行的解决方案!
首先看了你的代码片段,发现几个核心问题:当前只处理了单循环的部分轮次,主客场切换逻辑太简单,没法保证每个球队和对手都能各打一次主场、一次客场。咱们一步步来修正:
核心需求明确
对于4支球队的双循环Round-Robin赛程,每两队之间需要进行主客场两场比赛,总共有 4×3=12 场比赛,分成6轮(每轮2场比赛)。
修正后的完整代码
$allTeam = [3, 10, 8, 7]; $leng = sizeof($allTeam); $totalRounds = 2 * ($leng - 1); // 双循环总轮次:单循环是leng-1轮,双循环乘2 $teamList = $allTeam; // 复制球队数组用于轮转操作 for ($t = 0; $t < $totalRounds; $t++) { $currentSingleRound = $t % ($leng - 1); // 对应单循环中的第几轮 $isReverseRound = $t >= ($leng - 1); // 是否是双循环的后半段(主客场反转) $lastHalf = $leng - 1; \Log::info("=== 第 " . ($t + 1) . " 轮 ==="); for ($i = 0; $i < $leng / 2; $i++) { $homeIdx = $i; $awayIdx = $lastHalf - $i; // 两种情况交换主客场:1. 后半段轮次;2. 单循环内的奇数轮 if ($isReverseRound || ($currentSingleRound % 2 !== 0)) { list($homeIdx, $awayIdx) = [$awayIdx, $homeIdx]; } $homeTeam = $teamList[$homeIdx]; $awayTeam = $teamList[$awayIdx]; \Log::info("Home Team => {$homeTeam} vs {$awayTeam} <= Away Team"); } // 经典Round-Robin轮转逻辑:固定第一个球队,其余球队轮转(避免重复对阵) if ($currentSingleRound < ($leng - 2)) { $lastTeam = array_pop($teamList); array_splice($teamList, 1, 0, $lastTeam); } }
关键逻辑解释
- 双循环轮次设置:
$totalRounds = 2 * ($leng - 1)确保每个球队和其他对手都能打主客场两场。 - 球队轮转:每轮固定第一个球队,把最后一个球队移到第二个位置,这样每轮的对阵组合都不会重复,这是Round-Robin算法的核心。
- 主客场切换:结合两个条件切换主客场:
- 后半段轮次(双循环的第二轮循环):所有对阵的主客场直接反转。
- 单循环内的奇数轮:每间隔一轮交换一次主客场,保证单循环内的对阵也有主客交替。
验证效果
运行这段代码后,你会看到每支球队:
- 和另外3支球队各交手2次
- 每支对手都有一次在主场、一次在客场的对阵
这样就完全满足双循环Round-Robin的主客场分配需求啦!
内容的提问来源于stack exchange,提问作者Hkm Sadek
相关产品推荐
相关产品推荐

