基本算法说明:
假设您想在 8 人锦标赛中播种 4 名玩家。
[ ][ ][ ][ ][ ][ ][ ][ ] 8 empty positions
播种第一个球员很容易,我们把他放在哪里并不重要。我们把他放在开头,这样算法就更容易了。
[1][ ][ ][ ][ ][ ][ ][ ]
如果我们想播种第二名玩家,我们需要将整个场地分成两部分。位于左侧的玩家只会在决赛中遇到右侧的玩家。因此,必须将第二名球员放在正确的位置,这样两个最好的球员就不会在决赛前相遇。我们再次将玩家置于其部分的开头。
[1][ ][ ][ ] [2][ ][ ][ ]
现在我们再次拆分这两个部分,并将第三个和第四个玩家放入新的空白部分。现在第三名球员将在半决赛中遇到第一名球员。
[1][ ] [3][ ] [2][ ] [4][ ]
请注意,该算法将奇数放在左侧,将偶数放在右侧。现在可以用随机玩家填充空单元格。该算法与@Nico Schertler 建议的基本相同。
编程:
我的想法是定义一个函数,该函数获取玩家的位置(例如 1、2、3、4 等)和空闲位置的数量(在您的示例中为 128)并返回您应该放置该玩家的位置。我用 Java 编写了这个函数,但它应该很容易适应它。
/**
* @param rank
* rank of the player, best player == 1, second best player == 2
* @param partSize
* number of total free positions. Has to be a power of 2 (e.g.
* 2,4,8,16,32)
* @return returns the start position of the player, zero based
*/
public static int seedPlayer(int rank, int partSize) {
// base case, if rank == 1, return position 0
if (rank <= 1) {
return 0;
}
// if our rank is even we need to put the player into the right part
// so we add half the part size to his position
// and make a recursive call with half the rank and half the part size
if (rank % 2 == 0) {
return partSize / 2 + seedPlayer(rank / 2, partSize / 2);
}
// if the rank is uneven, we put the player in the left part
// since rank is uneven we need to add + 1 so that it stays uneven
return seedPlayer(rank / 2 + 1, partSize / 2);
}
示例:
让我们播种我们的第一场比赛(8 名种子选手,总共 8 名选手)
for (int i = 1; i <= 8; i++) {
System.out.printf("seeded player %d in position %d%n", i, seedPlayer(i, 8) + 1);
}
这打印:
seeded player 1 in position 1
seeded player 2 in position 5
seeded player 3 in position 3
seeded player 4 in position 7
seeded player 5 in position 2
seeded player 6 in position 6
seeded player 7 in position 4
seeded player 8 in position 8
导致该字段:
[1][5][3][7][2][6][4][8] Perfect! Like expected!
进一步通知:
我不会播种超过 25% 的球员,所以比赛会随着时间的推移而改变,每个不那么优秀的球员都有机会与不同的球员比赛。