优化 - 将参与者远离彼此分配

时间:2018-04-26 05:43:37

标签: algorithm optimization match tournament

这是我的第一个问题。我试着找了2天的答案,但我找不到我要找的东西。

问题:如何最大限度地减少来自同一所学校的学生之间的匹配数量

我有一个非常实际的案例,我需要安排比赛(锦标赛支架) 但有些参与者可能来自同一所学校。 那些来自同一所学校的人应该尽可能地放在彼此身上

例如:{A A A B B C} => {A B},{A C},{A B}

如果一所学校的参与者超过一半,那么除了与来自同一所学校的两个人配对之外别无选择。

例如:{A A A A B C} => {A B},{A C},{A A}

我不希望得到代码,只是一些关键字或一些伪代码,你认为这将是一个很好的帮助!

我尝试深入研究约束解析算法和锦标赛括号算法,但他们不考虑尽量减少来自同一所学校的学生之间的匹配数量。

好的,非常感谢你!

3 个答案:

答案 0 :(得分:0)

一种简单的算法(编辑2)

从下面的评论中:你有一场淘汰赛。您必须在锦标赛支架中选择球员的位置。如果你看看你的支架,你会看到:玩家,还有成对的玩家(相互竞争1的玩家),成对的玩家对(第1对第2对的赢家),等等。

想法

  • 按学校排序学生,学生人数较少的学生排在学生较少的学校之前。例如A B B B B C C - > B B B B C C A。
  • 在战争卡片游戏中将学生分为A组和B组:A组第一名,B组第2名,A组第3名,B组第4名,......
  • 继续使用A组和B组。

你有一个递归:一个玩家在等级k-1(k = n-1到0)中的位置是((pos at level k) % 2) * 2^k + (pos at level k) // 2(每个偶数向左移动,每个奇数向右移动)< / p>

Python代码

按学校数量排序数组:

assert 2**math.log2(len(players)) == len(players) # n is the number of rounds
c = collections.Counter([p.school for p in players])
players_sorted_by_school_count = sorted(players, key=lambda p:-c[p.school])

找到每个球员的最终位置:

players_sorted_for_tournament = [-1] * 2**n
for j, player in enumerate(players_sorted_by_school_count):
    pos = 0
    for e in range(n-1,-1,-1):
        if j % 2 == 1:
            pos += 2**e # to the right
        j = j // 2
    players_sorted_for_tournament[pos] = player

这应该给出足够多样化的群体,但我不确定它是否是最佳的。等待评论。

第一版:如何与不同学校的学生进行配对

只需将同一所学校的学生放入一个堆栈。你拥有和学校一样多的筹码。现在,按学生数量对堆栈进行排序。在您的第一个示例{A A A B B C}中,您会得到:

A
A B
A B C

现在,从两个第一个堆栈中取出两个顶部元素。堆栈大小已更改:如果需要,请重新排序堆栈并继续。当你只有一个堆栈时,从这个堆栈中成对。

这个想法是保留尽可能多的学校 - 堆栈&#34;尽可能长时间:尽可能地让学生小堆,直到你别无选择,只能拿走它们。

第二个示例的步骤{A A A A B C}

A
A
A
A B C => output A, B

A
A
A C => output A, C

A
A => output A A

这是匹配问题(编辑1)

我详细说明了以下评论。你有一场淘汰赛。您必须在锦标赛支架中选择球员的位置。如果你看看你的支架,你会看到:玩家,还有成对的玩家(相互竞争1的玩家),成对的玩家对(第1对第2对的赢家),等等。

你的解决方案是从所有玩家的集合开始,并将其分成两组,尽可能多样化。 &#34;多元&#34;意思是:不同学校的最大数量。为此,请检查将该组拆分为两个等于大小的子集的所有可能元素组合。然后在这些集合上递归执行相同的操作,直到您到达玩家级别。

另一个想法是从玩家开始并尝试与其他学校的其他玩家进行配对。让我们定义一个距离:如果两个玩家在同一所学校,则为1;如果他们在不同的学校,则为0。您希望使用最小全局距离进行配对。

这个距离可以推广给玩家对:取普通学校的数量。即:A B A B - &gt; 2(A&amp; B),A B A C - &gt; 1(A),A B C D - &gt;你可以想象两组(球员,成对,成对,......)之间的距离:普通学校的数量。现在你可以看到这是一个图形,其顶点是集合(玩家,成对,成对,......),其边缘连接每对顶点,权重是上面定义的距离。您正在寻找具有最小权重的完美匹配(所有顶点都匹配)。

blossom algorithm或其某些变体似乎符合您的需求,但如果玩家数量有限,则可能过度杀伤。

答案 1 :(得分:0)

创建一个二维数组,其中第一个维度将用于每个学校,第二个维度将用于此起飞中的每个参与者。 加载它们,您将拥有线性所需的一切。 例如:

学校1 ------- Schol 2 --------学校3

A ------------ B ------------- C

A ------------ B ------------- C

A ------------ B ------------- C

A ------------ B

A ------------ B

A

A

在上面的例子中,我们将有3所学校(第一维),学校1有7名参与者(第二维),学校2有5名参与者,学校3有3名参与者。 您还可以创建包含结果组合的第二个数组,并且对于每个选定的对,从循环中的初始数组中删除该对,直到它完全为空并且结果数组完全填满。

答案 2 :(得分:0)

我认为this answer中的算法可以提供帮助。

基本上:按学校对学生进行分组,并使用Bresenham's Algorithm后面的错误跟踪理念尽可能地分散学校。然后从列表中拉出对。