C# 分发匹配项';锦标赛友谊赛';

C# 分发匹配项';锦标赛友谊赛';,c#,distribution,evenly,matchmaking,C#,Distribution,Evenly,Matchmaking,假设我有四支球队,ABCD,我想创造比赛,以便各球队都能平等地进行比赛: 不需要 A对B A对C A对D B对C B对D C对D 所需的 A对B C对D B对C A对D A对C B对D 另一种说法是:我希望球队尽可能少地连续比赛。 目标语言是C#,但我很容易翻译 编辑:快速侧注,可以超过4个团队 我认为你可以通过以下方式实现你需要做的事情。如果有n个团队,那么团队之间所有可能的比赛都可以用一个表示 我会想出你想要的排序方法,就是从图中提取(删除)边,一次一条,总是试图找到一条与之前不匹配

假设我有四支球队,ABCD,我想创造比赛,以便各球队都能平等地进行比赛:

不需要

  • A对B
  • A对C
  • A对D
  • B对C
  • B对D
  • C对D
所需的

  • A对B
  • C对D
  • B对C
  • A对D
  • A对C
  • B对D
另一种说法是:我希望球队尽可能少地连续比赛。
目标语言是C#,但我很容易翻译


编辑:快速侧注,可以超过4个团队

我认为你可以通过以下方式实现你需要做的事情。如果有n个团队,那么团队之间所有可能的比赛都可以用一个表示

我会想出你想要的排序方法,就是从图中提取(删除)边,一次一条,总是试图找到一条与之前不匹配的团队匹配的边。此外,我认为这种方法(有一点变化)可以用来生成最大化并发比赛的最佳方法,如果每次你取得优势时,你都选择与大多数时间没有比赛的球队进行竞争

为了简单起见,我们假设团队是介于0到n-1之间的整数。该图可以简单地用布尔矩阵表示。要选择与大多数时间未参加比赛的球队的比赛,您可以记录每支球队上次比赛的时间。对于
n
团队,您将拥有总共
n*(n-1)/2
个匹配数

IEnumerable<Tuple<int,int>> GenerateMatches(int n) {
    bool[,] pendingMatches = new bool[n,n];
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < i; j++)
            pendingMatches[i,j] = true;
    }

    int[] lastPlayed = new int[n];
    int totalMatches = n*(n-1)/2;
    for (int m = 1; m <= totalMatches; m++) {
        Tuple<int, int> t = null;
        int longestPlayed = -1;
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < i; j++) {
                if (pendingMatches[i,j]) {
                    int moreRecentlyPlayed = Math.Max(lastPlayed[i], lastPlayed[j]);
                    int timeSinceLastPlay = m - moreRecentlyPlayed;
                    if (timeSinceLastPlay > longestPlayed) {
                        longestPlayed = timeSinceLastPlay;
                        t = Tuple.Create(i,j);
                    }
                }
            }
        }
        lastPlayed[t.Item1] = lastPlayed[t.Item2] = m;
        pendingMatches[t.Item1, t.Item2] = false;
        yield return t;
    }
}
IEnumerable生成匹配(int n){
bool[,]pendingMatches=新bool[n,n];
对于(int i=0;i
选择下一个匹配项的零件是两个嵌套最多的FOR。如果在更新lastPlayed数组后使用某种优先级队列来调整涉及最后拾取的边的团队的边的优先级,则可以提高该部分的复杂性


希望有帮助。

解决此问题的一种方法是通过以下步骤:

  • 创建包含匹配组合总数的集合
  • 创建与步骤1中的集合长度相同的新集合
  • 检查步骤1中的项目,在步骤2中添加相同的项目,条件是要添加的下一个项目与上次添加的项目之间应具有最大差异
  • 一些示例代码:

    // Just a container to conveniently hold a match between two teams
    public class Match
    {
        public Match(string teamOne, string teamTwo)
        {
            TeamOne = teamOne;
            TeamTwo = teamTwo;
        }
    
        public string TeamOne { get; private set; }
    
        public string TeamTwo { get; private set; }
    
        public override string ToString()
        {
            return String.Format("{0} vs {1}", TeamOne, TeamTwo);
        }
    }
    
    public class MatchMaking
    {
        public MatchMaking()
        {
            Teams = new List<string> { "A", "B", "C", "D", "E" };
        }
    
        public IList<string> Teams { get; private set; }
    
        public IList<Match> GetMatches()
        {
            var unorderedMatches = GetUnorderedMatches();
    
            // The list that we will eventually return
            var orderedMatches = new List<Match>();
    
            // Track the most recently added match
            Match lastAdded = null;
    
            // Loop through the unordered matches
            // Add items to the ordered matches
            // Add the one that is most different from the last added match
            for (var i = 0; i < unorderedMatches.Count; i++)
            {
                if (lastAdded == null)
                {
                    lastAdded = unorderedMatches[i];
                    orderedMatches.Add(unorderedMatches[i]);
                    unorderedMatches[i] = null;
                    continue;
                }
    
                var remainingMatches = unorderedMatches.Where(m => m != null);
    
                // Get the match which is the most different from the last added match
                // We do this by examining all of the unadded matches and getting the maximum difference
                Match mostDifferentFromLastAdded = null;
                int greatestDifference = 0;
                foreach (var match in remainingMatches)
                {
                    var difference = GetDifference(lastAdded, match);
                    if (difference > greatestDifference)
                    {
                        greatestDifference = difference;
                        mostDifferentFromLastAdded = match;
                    }
    
                    if (difference == 2)
                    {
                        break;
                    }
                }
    
                // Add the most different match
                var index = unorderedMatches.ToList().IndexOf(mostDifferentFromLastAdded);
                lastAdded = unorderedMatches[index];
                orderedMatches.Add(unorderedMatches[index]);
                unorderedMatches[index] = null;
            }
    
            return orderedMatches;
        }
    
        // Create a list containing the total match combinations with an arbitrary order
        private List<Match> GetUnorderedMatches()
        {
            var totalNumberOfCombinations = AdditionFactorial(Teams.Count - 1);
    
            var unorderedMatches = new List<Match>(totalNumberOfCombinations);
            for (int i = 0; i < Teams.Count; i++)
            {
                for (int j = 0; j < Teams.Count; j++)
                {
                    if (j <= i) continue;
    
                    unorderedMatches.Add(new Match(Teams[i], Teams[j]));
                }
            }
            return unorderedMatches;
        }
    
        // Get the difference between two matches
        // 0 - no difference, 1 - only one team different, 2 - both teams different
        private int GetDifference(Match matchOne, Match matchTwo)
        {
            var matchOneTeams = new HashSet<string> { matchOne.TeamOne, matchOne.TeamTwo };
            var matchTwoTeams = new HashSet<string> { matchTwo.TeamOne, matchTwo.TeamTwo };
            var intersection = matchOneTeams.Intersect(matchTwoTeams);
    
            return (intersection.Count() - 2) * -1;
        }
    
        // Just a helper to get the total number of match combinations
        private int AdditionFactorial(int seed)
        {
            int result = 0;
    
            for (int i = seed; i > 0; i--)
            {
                result += i;
            }
    
            return result;
        }
    }
    
    public class Program
    {
        private static void Main(string[] args)
        {
            var matchMaking = new MatchMaking();
    
            foreach (var match in matchMaking.GetMatches())
            {
                Console.WriteLine(match);
            }
        }
    }
    
    //只是一个容器,可以方便地存放两队之间的比赛
    公开课比赛
    {
    公开比赛(一队、二队)
    {
    TeamOne=TeamOne;
    TeamTwo=TeamTwo;
    }
    公共字符串TeamOne{get;private set;}
    公共字符串TeamTwo{get;private set;}
    公共重写字符串ToString()
    {
    返回String.Format(“{0}vs{1}”,TeamOne,TeamTwo);
    }
    }
    公课相亲
    {
    公开相亲
    {
    小组=新名单{“A”、“B”、“C”、“D”、“E”};
    }
    公共IList团队{get;private set;}
    公共IList GetMatches()
    {
    var unorderedMatches=GetUnorderedMatches();
    //我们最终将返回的列表
    var orderedMatches=新列表();
    //跟踪最近添加的匹配项
    Match lastpadded=null;
    //循环遍历无序的匹配项
    //将项目添加到已排序的匹配项中
    //添加与上次添加的匹配项最不相同的匹配项
    for(var i=0;im!=null);
    //获取与上次添加的匹配最不相同的匹配
    //我们通过检查所有未添加的匹配并获得最大差异来实现这一点
    Match mostDifferentFromLastAdded=null;
    int greatestDifference=0;
    foreach(剩余匹配中的var匹配)
    {
    var差异=GetDifference(最后添加,匹配);
    如果(差异>最大差异)
    {
    最大差异=差异;
    mostDifferentFromLastAdded=匹配;
    }
    如果(差=2)
    {
    打破
    }
    }
    //添加最不同的匹配项
    var index=unorderedmatchs.ToList().IndexOf(mostdifferencefromstadded);
    lastAdded=无序匹配[索引];
    Add(无序匹配[index]);
    无序匹配[索引]=空;
    }
    退货订单匹配;
    }
    //创建包含任意顺序的总匹配组合的列表
    私有列表GetUnorderedMatches()
    {
    var TotalNumberOfCombines=加法因子(Teams.Count-1);
    var unorderedMatches=新列表(totalNumberOfCombinations);
    for(int i=0;i