【发布时间】:2015-01-29 00:27:18
【问题描述】:
我有以下问题:
一组 n 名玩家想要进行一组比赛。每场比赛有 m 参与者。我想找到一个最少比赛次数的时间表 每个玩家至少与其他玩家会面一次且最多 各种各样的对手。
经过一些研究,我发现“社交高尔夫球手问题”似乎是一个类似的问题,但我找不到可以适应的解决方案,也无法提出自己的解决方案。
【问题讨论】:
标签: algorithm combinatorics schedule
我有以下问题:
一组 n 名玩家想要进行一组比赛。每场比赛有 m 参与者。我想找到一个最少比赛次数的时间表 每个玩家至少与其他玩家会面一次且最多 各种各样的对手。
经过一些研究,我发现“社交高尔夫球手问题”似乎是一个类似的问题,但我找不到可以适应的解决方案,也无法提出自己的解决方案。
【问题讨论】:
标签: algorithm combinatorics schedule
伪代码(假设玩家内部有flag):
function taking array of players (x) and players per game (y) {
array of players in this game (z)
for each player (t) in x {
if z.length == y {break out of loop}
check the flag of each player in (t), if the flag is not set {
check if z.length is less than y {
set flag and add it to array z
}
}
}
if z.length is less than 2, change the players in z's flags back to false
return (if z.length == 3, return z, or else return false);
}
从玩家 A 开始; (假设玩家 A 到 F,每场 3 人)
通过从上到下,我们可以消除可能性。从每个人开始玩所有其他玩家(他们还没有玩过,例如,B 跳过 C,因为 B 在 ABC 中与 C 一起玩)(3 人一组)。我们可以编写一个函数来执行此操作(请参阅顶部的伪代码)
A B C (save this game to a list of games, or increment a counter or something)
A D E
A F -missing (returned false so we did not save this)
B D E
B F -missing
C D E
C F -missing
D E F
现在,如果只计算 3 人一组的话,几乎所有玩家都互相玩过。到目前为止,这是 5 场比赛。去掉我们已经统计过的游戏,导致
A F -missing
B F -missing
C F -missing
这里有什么共同点?他们都有F。这意味着F必须扮演这个列表中的每个人,所以我们需要做的就是把F放在前面。
我们现在可以做 F A B,然后 C F + 任何随机玩家。这是最少 7 场比赛。
基本上,您可以一遍又一遍地运行伪代码,直到它连续 2 次返回 false。当它连续 2 次返回 false 时,您知道所有标志都已设置。
【讨论】:
这可能不是一个完整的解决方案,但是...考虑一个带有n 节点的图。与m 玩家的比赛可以通过将m-1 边放置在每轮图表中来表示。每个玩家至少与其他玩家见面一次的要求意味着您将在几轮之后拥有complete graph。
对于第 1 轮(匹配),放置任意一组 m-1 边。对于下一轮,放置当前未连接两个节点的m-1 边。重复直到图表完成。
编辑: 需要将边连接起来以确保只有m 玩家与m-1 边匹配,这会使这变得更加困难。如果您将每一轮都放在完整图的步行中,那么问题就与找到完整图的最短步行相同。 This answer 可能与不同的问题相关,并建议Floyd-Warshall algorithm。
【讨论】: