我正在研究Python的瑞士锦标赛系统,我正试图找出一种最佳的配对算法 我最大的问题是,我带来的每个算法都会在几个序列中产生错误,其中最后一对要拾取的对象已经相互发挥作用,判断配对无效。
我正在研究的瑞士系统很简单:即使是玩家,每个人都会在每一轮比赛中进行比赛,并且基于胜利的接近度来完成配对(因此强大的球员与强大的球员对抗,弱对弱者)。 没有再见,只有输赢(没有平局),对手不能互相比赛两次。
我目前使用的算法如下:
例如:
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
问题:是否有任何算法可以保证最佳配对模块,同时确保我不会在两个玩家互相玩的时候“卡住”?
答案 0 :(得分:3)
如果有一个强力算法,则可以保证找到最佳配对模块:
对于少数玩家来说,这甚至可能导致可行的运行时间。对于更大的数字,您需要查看优化和快捷方式。
答案 1 :(得分:2)
也许我可以帮助你。在国际象棋中,我们有不同的瑞士配对算法,但它们都使用强弱配对(可能会有惊喜)。
荷兰语(最常用)的基本原则是,一旦您分配了配对号码,就可以为每个得分括号应用算法。
算法大致如下:
在第一个得分范围内,选择(约)一半球员并将其放入一个小组,并将其他球员放在另一个小组中。如果玩家兼容,则将它们配对。如果它们不兼容,请尝试在第二个子组中交换玩家。如果没有配对兼容,则在子组之间交换玩家。如果支架中有一些奇数的玩家,那么其中一个将会向下浮动。
在下一个得分范围内: 如果有漂浮物,请先将它们配对。然后,使用残留组执行与之前相同的操作。
添加了更多规则以确保至少有一个配对可用。
例如:如果没有交易所能够进行足够好的配对,则回溯到前一个得分括号并打破配对以制作飞行物。
这是荷兰配对系统的一个非常粗略的解释,但这是我的问题。
答案 2 :(得分:1)
我遇到了同样的问题,并通过以下方式解决了这个问题。
每组: 一个。在行和列中创建一个包含玩家的矩阵 湾为禁用对分配高成本(例如:10000)(例如:已经玩过,在奇数玩家的情况下为虚拟玩家) C。为所有其他对分配“性能”值,例如,基于收入和丢失的点数 d。找到所有可能的匹配,仅在矩阵的一半部分,因为它是一个镜像。总结此解决方案的“性能值” 即跳过成本> 10000 F。对解决方案列表进行排序,采用最低的总和条目
如果没有解决方案,那么重新做同样的算法而不分割玩家。
只有在控制匝数的情况下才会有最佳解决方案。例如,对于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/