Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm 128人锦标赛中32名种子选手的分配算法_Algorithm_Tournament - Fatal编程技术网

Algorithm 128人锦标赛中32名种子选手的分配算法

Algorithm 128人锦标赛中32名种子选手的分配算法,algorithm,tournament,Algorithm,Tournament,我正在尝试创建一个网球比赛模拟器,其中的比赛结果是随机的(某种程度上)。大满贯赛有128名选手,其中32名是种子选手。目前我正试图把种子放在适当的位置。我根据正态分布(这将替代他们的排名)生成了球员的实力,并将其存储在升序排序数组中。我想最初只是将绘图表示为矢量绘图(128)。理想情况下,我会有一个算法,让每个球员在抽签时都处于适当的位置,但我还没有找到一个算法,所以我决定将位置输入一个数组,并根据比赛中有多少球员选择合适的数组 排名如下:0127,95,32,64,96,31,63,16112

我正在尝试创建一个网球比赛模拟器,其中的比赛结果是随机的(某种程度上)。大满贯赛有128名选手,其中32名是种子选手。目前我正试图把种子放在适当的位置。我根据正态分布(这将替代他们的排名)生成了球员的实力,并将其存储在升序排序数组中。我想最初只是将绘图表示为
矢量绘图(128)
。理想情况下,我会有一个算法,让每个球员在抽签时都处于适当的位置,但我还没有找到一个算法,所以我决定将位置输入一个数组,并根据比赛中有多少球员选择合适的数组

排名如下:0127,95,32,64,96,31,63,16112,79,48,15111,80,47,41,72,8119,23104,55,87,71,39,24,7,56,88103120

以32的倍数表示的前几项为:0*32,4*32-1,3*32-1,1*32,2*32,3*32,1*32-1,2*32-1,0.5*32,3.5*32-1,2.5*32-1,1.5*32,0.5*32-1,3.5*32,2.5*32


我还没有从中找出一个模式。有已知的算法吗?

基本算法说明

让我们假设你想在一个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);
}
导致该领域:

[1][5][3][7][2][6][4][8] Perfect! Like expected!
进一步通知


我不会为超过25%的球员播种种子,这样比赛会随着时间的推移而改变,每个不太好的球员都有机会与不同的球员比赛。

我可以想出两种方法:

  • 荒谬的头脑的答案,并增加了一点更多的信息
  • 我们不仅需要将前两名种子球员分开,避免他们在最后一轮比赛前在任何地方相遇,我们还必须确保前两名种子球员在第一轮比赛中扮演最后一名种子球员,第二名种子球员扮演最后一名种子球员,依此类推

    荒谬思维提出的算法实际上解决了这个问题。如果我必须改变什么,那只能是在最后一个函数中。或者我会简单地添加另一个步骤,从结果的任意一侧提取极值,将它们放置在另一个数组中,以获得问题中所问的数组位置

    For n=8, 
    [1][5][3][7][2][6][4][8] \\previous result
    
    \\extracting the extreme values on either side and placing them in another array:
    [1][8] [5][4] [3][6] [7][2]
    
    \\next round (assuming the higher seed wins):
    [1][4] [3][2]
    
    \\final round:
    [1][2]
    
    Hence, the order obtained initially is correct
    
  • 观察模式
  • 没有具体的公式来获得级数的第n项(至少我找不到)。但是有一个隐藏的模式可以利用。当您以这种特殊方式写入种子时,模式就会出现:

    (Arrowhead indicates the direction of the ascending order)
    For n=2,
    1 ---> 2
    
    For n=4,
    1 ---> 2
    4 <--- 3
    
    For n=8,
    1 ---> 2
    4 <--- 3
    5 ---> 6
    8 <--- 7
    
    In general,
    m ---> m+1
    ....
    ....
    n <--- n-1
    
    我们得到,

    A=[1][16] [4][13] [5][12] [8][9]
    
    Similarly for the other half,
    B=[2][15] [3][14] [6][11] [7][10] 
    
    继续从两个极端中抽取赢家,直到你从a盘和B盘中找到赢家,他们将在决赛中相互较量


    希望有帮助

    有一个按输出顺序选择玩家的公式

    基于0的玩家计数更容易计算,所以我将这样做,根据输出和输入的需要进行转换

    从位置0的玩家种子0开始

    PC = Player count (filled up with unseeded players then bye's to power of 2)
    slot[0] = seeded[0]
    for(n = 1; n < PC; n++) {
        seed = slot[n-(1<<ffs(n))]^(PC>>ffs(n))
        slot[n] = seeded[seed];
    }
    
    PC=Player count(填充了未种子选手,然后再见2次方)
    槽[0]=种子[0]
    对于(n=1;n

    ffs是find first set,也称为尾随0的计数。对于低位集,应返回0。
    在此处输入代码。

    您使用的是什么锦标赛系统?瑞士?KO?双淘汰?通常只有种子是固定的,其他所有种子都是随机放置的。抱歉,忽略了这一点。这是温布尔登、美国公开赛等比赛中使用的淘汰赛。是的我只想修复种子,然后随机放置其他种子。我想在管理种子后,我会处理随机放置,但如果可以同时处理,那就太好了。不确定你实际上在寻找什么。我知道一种递归方式来设置玩家。对于8个玩家,顺序将是1、5、3、7、2、6、4,8.k种子选手将占据前k名的位置。这符合你的需要吗?@NicoSchertler如果你看,你可以看到有128名选手,其中32名是种子选手,他们的位置是在比赛后期才会相遇。我想要一个算法来做到这一点。如果所有选手都是种子选手,那么你的递归算法就会起作用我想,但大多数球员都没有种子。
    1. Enter n (number of players, should be a power of 2)
    2. Arrays X[n/2], Y[n/2]
       Integer a=1
    3. for (i=1, i<=n/4, i++)
           {
           if(i=1){
             X[i]=a;
             Y[i]=a+1;}
           else if (i%2=0) {  \\if i is even
             X[i]=2i;
             Y[i]=X[i]-1;}
           else {
             X[i]=2i-1;
             Y[i]=X[i]+1; }
           a++;
           }
    
    Resulting arrays (for n=16):
    X=[1][4][5][8][9][12][13][16]
    Y=[2][3][6][7][10][11][14][15]
    
    X= *[1]* [4][5][8][9][12][13] *[16]*
    X= *[4]* [5][8][9][12] *[13]* 
    and so on...
    
    A=[1][16] [4][13] [5][12] [8][9]
    
    Similarly for the other half,
    B=[2][15] [3][14] [6][11] [7][10] 
    
    PC = Player count (filled up with unseeded players then bye's to power of 2)
    slot[0] = seeded[0]
    for(n = 1; n < PC; n++) {
        seed = slot[n-(1<<ffs(n))]^(PC>>ffs(n))
        slot[n] = seeded[seed];
    }