C 用随机点填充平面

C 用随机点填充平面,c,random,C,Random,我想用随机放置的点填充平面,检查它们是否重叠(如果重叠,将其中一个移动到空白处),然后计算它们之间的平均距离。后来我计划将其扩展到3D,这样它就有点像盒子里的粒子。 我知道一定有更好的方法,但我想到的是。用于在平面中放置随机点: int pos[NUMBER][2]; /* Creates an array of NUMBER amount of points with x and y coordinate */ int a, b; srand( time(NULL) ); for(a=0

我想用随机放置的点填充平面,检查它们是否重叠(如果重叠,将其中一个移动到空白处),然后计算它们之间的平均距离。后来我计划将其扩展到3D,这样它就有点像盒子里的粒子。 我知道一定有更好的方法,但我想到的是。用于在平面中放置随机点:

int pos[NUMBER][2];    /* Creates an array of NUMBER amount of points with x and y coordinate */
int a, b;
srand( time(NULL) );
for(a=0;a<NUMBER;a++)
      for(b=0;b<2;b++)
         pos[a][b]=rand()%11; /* Using modulus is random enough for now */
int pos[NUMBER][2];/*创建具有x和y坐标的点数数组*/
INTA,b;
srand(时间(空));

对于(a=0;a这里是一个我认为可行的解决方案的草图:

  • 您的点生成算法很好,可以保持原样

  • 检查重叠的正确时间是在生成点时。我们只需生成新点,直到生成一个不与任何先前点重叠的点

  • 要快速查找重叠,请使用哈希表,如“glib”中的哈希表。该键可以是两个int32\t并打包成一个int64\t并集:

    typedef联合点{
    结构{
    int32_t x;
    int32_t y;
    };
    int64_t hashkey;
    }点;

  • 使用哈希表的“迭代所有键”功能构建输出数组

  • 我还无法测试这一点,但它应该可以工作。这假设平面相对于点的数量而言较大,因此重叠的可能性较小。如果相反,则可以反转逻辑:从完整平面开始,随机添加孔


    此算法的平均复杂度为O(n)。

    正如您所暗示的,它也适用于高密度,最好的做法是创建一个布尔(或位向量)的2D数组,如果您想节省空间的话,其中所有元素最初都设置为false。然后循环次数,生成一个随机坐标,并检查数组中的值是否为true。如果为true,则生成另一个随机坐标。如果为false,则将坐标添加到列表中,并将数组中的对应元素设置为true


    以上假设您需要精确的点数,并且放置点数的机会完全一致。如果不需要这些约束中的任何一个,则可能会有其他算法使用更少的内存。

    一种解决方案是随机放置点数,查看它们是否重叠,然后重新尝试重叠。为了避免测试每个点,您需要按空间设置索引-如果你有一个100*100的平面和一个3-4的截止线,你可以使用10*10的方格。然后你必须搜索四个方格来检查你没有命中


    但还有其他方法。在网格上均匀放置点将创建泊松分布。因此,对于每个点,您可以使用泊松分布创建一个随机数。当您得到2个或更多时会发生什么情况?此方法迫使您回答该问题。可能您人为地钳制到一个点,可能您移动到相邻点这个方法不会创建精确的N个点,所以如果你必须有N个点,你可以加入一个软糖(随机添加/删除最后的几个点)。

    我不知道“接受”的方法,但我想我可以提供一个O(
    NUMER*log(网格大小)
    )时间,其中
    GRID\u SIZE
    是可能位置的总数。对于小参数可能较慢,但对于大参数可能较快。为什么不在放置点时检查重叠?您需要某种数据结构使其合理有效。a)因为我们知道网格上的点数和位置,所以检查完整性是很简单的。在任何情况下,救助都是愚蠢的。b)即使是超过一半的董事会也不应该出现。此时,选择不包含点的位置会更快。(其工作原理完全相同。)c)由于第二个点重复放置在第一个点上而导致的救援应该受到反对,因此您的算法不能保证终止。(无可否认,这不太可能)让最坏的情况变得更糟。不过,平均值看起来不错。@Hermann,你是对的,我已经相应地编辑了我的答案。把你的(b)带入解决方案,不终止应该是不太可能的。对于一个合适的随机函数选择,它应该最终生成所有可能的输出。这假设坐标的最大大小有一个相当低的界限,并且不适用于真实坐标(这不是问题中的要求,而是问题的合理扩展)。其想法是将其扩展到真实坐标,是的。无论如何,这对我来说太复杂了,不过我很感激所有的答案。
        for(a=0;a<NUMBER-1;a++)
          for(b=a+1;b<NUMBER;b++)
            if( pos[a][0] == pos[b][0] && pos[a][1] == pos[b][1])
               printf("These points overlap:\t", pos[a][0], pos[a][1]);