You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#单循环赛(Round-robin)生成器问题:配对数量不足

单循环赛(Round-robin)配对生成器问题排查与修复(C#)

你的C#单循环赛生成器存在配对不完整的问题:12位选手应生成66组唯一配对(11轮,每轮6组),但当前代码仅生成50组,且前3轮后每轮只能生成4组配对。

问题根源

当前代码采用嵌套循环暴力遍历选手配对的方式,逻辑上存在核心缺陷:

  • 固定的遍历顺序会导致后续轮次中部分选手的可用配对被提前耗尽,无法凑齐每轮所需的全部配对
  • 未遵循单循环赛的标准轮转规则,暴力匹配容易出现「配对断层」,无法覆盖所有可能的选手组合

修复方案:使用标准单循环赛轮转算法

单循环赛有成熟的轮转生成规则,能保证每轮所有选手都参与配对(奇数时加入轮空选手0),且所有选手仅交手一次。以下是修改后的完整代码:

修改后的Button点击事件代码

private void button_G_Click(object sender, EventArgs e)
{
    int originalPlayerCount = (int)numericUpDown1.Value;
    bool hasBye = originalPlayerCount % 2 != 0;
    int playerCount = hasBye ? originalPlayerCount + 1 : originalPlayerCount;
    int totalRounds = playerCount - 1;
    int pairsPerRound = playerCount / 2;

    List<Pair> allPairs = new List<Pair>();
    List<int> players = Enumerable.Range(hasBye ? 0 : 1, playerCount).ToList();

    for (int round = 0; round < totalRounds; round++)
    {
        List<Pair> roundPairs = new List<Pair>();
        // 生成当前轮的配对
        for (int i = 0; i < pairsPerRound; i++)
        {
            int p1 = players[i];
            int p2 = players[playerCount - 1 - i];
            // 跳过轮空选手自己配对的情况(仅奇数人数时出现)
            if (p1 != p2)
            {
                roundPairs.Add(new Pair(p1, p2));
            }
        }

        // 记录本轮配对并添加到列表控件
        int gameNum = 0;
        foreach (var pair in roundPairs)
        {
            gameNum++;
            allPairs.Add(pair);
            listBox1.Items.Add($"{allPairs.Count}. Round {round + 1}, game {gameNum}: [player {pair.Player1}] vs [player {pair.Player2}]");
        }

        listBox2.Items.Add($"Round {round + 1}: {roundPairs.Count} pairs");

        // 执行轮转操作:固定第一个选手,其余选手顺时针轮转
        if (playerCount > 2)
        {
            int lastPlayer = players[playerCount - 1];
            players.RemoveAt(playerCount - 1);
            players.Insert(1, lastPlayer);
        }
    }

    // 输出每位选手的对手列表
    Console.WriteLine("Show each player matchup");
    int startPlayer = hasBye ? 0 : 1;
    foreach (var player in Enumerable.Range(startPlayer, originalPlayerCount))
    {
        var opponents = allPairs
            .Where(x => x.Player1 == player || x.Player2 == player)
            .Select(x => x.Player1 == player ? x.Player2 : x.Player1)
            .OrderBy(x => x);
        Console.WriteLine($"Player: {player.ToString().PadLeft(2)}:  {string.Join(", ", opponents.Select(x => x.ToString().PadLeft(2)))}");
    }
}

Pair类保持不变

public class Pair
{
    public int Player1 { get; set; } = -1;
    public int Player2 { get; set; } = -1;

    public Pair(int p1, int p2)
    {
        Player1 = p1;
        Player2 = p2;
    }
}

代码说明

  1. 轮转规则:固定第一个选手,其余选手每轮顺时针移动一个位置,确保所有选手能遍历到其他所有对手
  2. 轮空处理:当选手数为奇数时,自动添加选手0作为轮空选手,该选手在每轮中与一位真实选手配对(代表该真实选手轮空获胜)
  3. 配对完整性:12位选手会生成11轮,每轮6组配对,总计66组唯一配对,完全符合单循环赛要求

验证结果

运行修改后的代码,12位选手的输出会显示每位选手都与其他11位选手各交手一次,总配对数为66,每轮都能生成完整的6组配对。

内容的提问来源于stack exchange,提问作者Stanislav Vladev

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 11:18:12