瑞士锦标赛 - 配对算法

时间:2015-02-20 12:38:47

标签: python algorithm python-2.7 graph-algorithm

我正在研究Python的瑞士锦标赛系统,我正试图找出一种最佳的配对算法 我最大的问题是,我带来的每个算法都会在几个序列中产生错误,其中最后一对要拾取的对象已经相互发挥作用,判断配对无效。

我正在研究的瑞士系统很简单:即使是玩家,每个人都会在每一轮比赛中进行比赛,并且基于胜利的接近度来完成配对(因此强大的球员与强大的球员对抗,弱对弱者)。 没有再见,只有输赢(没有平局),对手不能互相比赛两次。

我目前使用的算法如下:

  1. 按排名顺序制作球员名单(最多获胜至最少获胜)
  2. 选择玩家,从获胜最多的玩家开始
  3. 将他与排名最靠近的球员相匹配。如果他们已经玩过,请将他与下一个匹配,直到找到匹配为止
  4. 将该对弹出列表并返回1
  5. 例如:
    2轮后的排名:

    1. P1: [P2 win, P3 win] 2 wins
    2. P5: [P6 win, P2 win] 2 wins
    3. P3: [P4 win, P1 lost] 1 win, 1 loss
    4. P4: [P6 win, P3 lost] 1 win, 1 loss
    5. P2: [P1 lost, P5 lost] 2 losses
    6. P6: [P5 lost, P4 lost] 2 losses
    

    第一个选择是P1,第一个匹配是P5。将(P1,P5)从列表中删除。

    1. P3: [P4 win, P1 lost] 1 win, 1 loss
    2. P4: [P6 win, P3 lost] 1 win, 1 loss
    3. P2: [P1 lost, P5 lost] 2 losses
    4. P6: [P5 lost, P4 lost] 2 losses
    

    首先选择P3,已经打过P4,所以比赛将是P2。将(P3,P2)从列表中取出。
    在这个序列中,我完成了一对相互对战,配对无效:

    1. P4: [P6 win, P3 lost] 1 win, 1 loss
    2. P6: [P5 lost, P4 lost] 2 losses
    

    问题:是否有任何算法可以保证最佳配对模块,同时确保我不会在两个玩家互相玩的时候“卡住”?

4 个答案:

答案 0 :(得分:3)

如果有一个强力算法,则可以保证找到最佳配对模块:

  1. 定义配对的惩罚函数(可能是配对玩家的胜利差异)
  2. 基于此,定义配对模块的惩罚函数(可能是模块中配对各自惩罚值的平方和)
  3. 枚举所有有效的模块(请注意,可能没有)
  4. 对于每个有效模块,根据(2。)
  5. 计算模块惩罚值
  6. 按此值排序并选择具有最小惩罚值的(一个)模块。 (最低可能由几个人共享。)
  7. 对于少数玩家来说,这甚至可能导致可行的运行时间。对于更大的数字,您需要查看优化和快捷方式。

答案 1 :(得分:2)

也许我可以帮助你。在国际象棋中,我们有不同的瑞士配对算法,但它们都使用强弱配对(可能会有惊喜)。

荷兰语(最常用)的基本原则是,一旦您分配了配对号码,就可以为每个得分括号应用算法。

算法大致如下:

在第一个得分范围内,选择(约)一半球员并将其放入一个小组,并将其他球员放在另一个小组中。如果玩家兼容,则将它们配对。如果它们不兼容,请尝试在第二个子组中交换玩家。如果没有配对兼容,则在子组之间交换玩家。如果支架中有一些奇数的玩家,那么其中一个将会向下浮动。

在下一个得分范围内: 如果有漂浮物,请先将它们配对。然后,使用残留组执行与之前相同的操作。

添加了更多规则以确保至少有一个配对可用。

例如:如果没有交易所能够进行足够好的配对,则回溯到前一个得分括号并打破配对以制作飞行物。

这是荷兰配对系统的一个非常粗略的解释,但这是我的问题。

答案 2 :(得分:1)

我遇到了同样的问题,并通过以下方式解决了这个问题。

  1. 我已将中间的排名分为两组
  2. 每组: 一个。在行和列中创建一个包含玩家的矩阵 湾为禁用对分配高成本(例如:10000)(例如:已经玩过,在奇数玩家的情况下为虚拟玩家) C。为所有其他对分配“性能”值,例如,基于收入和丢失的点数 d。找到所有可能的匹配,仅在矩阵的一半部分,因为它是一个镜像。总结此解决方案的“性能值” 即跳过成本> 10000 F。对解决方案列表进行排序,采用最低的总和条目

  3. 如果没有解决方案,那么重新做同样的算法而不分割玩家。

  4. 只有在控制匝数的情况下才会有最佳解决方案。例如,对于20名玩家,最佳轮数为5,更多可能是危险的(没有找到任何解决方案)。

    我已经用C ++实现了这个算法,并在现场测试了真正的锦标赛,它运行得很好。您可以在Tanca repository的Github上找到它,名为“Tournament.cpp”。

    我还在我的博客上写了一篇文章(用法语,抱歉)。

答案 3 :(得分:0)

我前段时间遇到了同样的问题,最后在python中使用最小权重最大匹配算法构建了一个解决方案。这里有一个很棒的图书馆! https://healthyalgorithms.com/2009/03/23/aco-in-python-minimum-weight-perfect-matchings-aka-matching-algorithms-and-reproductive-health-part-4/

我在博文中写下了我的思考过程,并确保链接到我在构建它时使用的资源。希望这有用:https://www.leaguevine.com/blog/18/swiss-tournament-scheduling-leaguevines-new-algorithm/