我想用随机放置的点填充一个平面,检查它们中的任何一个是否重叠(如果有的话,将其中一个移动到空位),然后计算它们之间的平均距离。后来我计划将它扩展到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 */
下一阶段是找到重叠点:
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]);
现在,当我确定哪些点重叠时,我必须移动其中一个点,但是当我这样做时,新位置的点可能会与之前的点重叠。有没有可以解决这个问题的方法?一种方法是无限的(真)循环与破坏条件,但这似乎非常低效,特别是当系统变得密集。 谢谢!
答案 0 :(得分:0)
以下是我认为可行的解决方案草图:
您的点生成算法很好,可以保留原样。
生成点时,检查重叠的时间正确。我们只是生成新的点,直到我们生成一个与之前的任何点都不重叠的点。
要快速查找重叠,请使用哈希表,例如&#39;&#39; glib&#39;&#39;&#39;。密钥可以是两个int32_t打包成int64_t联合:
typedef union _Point {
struct {
int32_t x;
int32_t y;
};
int64_t hashkey;
} Point;
使用&#34;迭代所有键&#34;哈希表的功能,用于构建输出数组。
我还没有能够测试这个,但它应该可行。这假设平面相对于点的数量较大,因此重叠的可能性较小。如果相反,则可以反转逻辑:从完整平面开始并随机添加孔。
该算法的平均复杂度为O(n)。
答案 1 :(得分:0)
当你暗示它也应该适用于高密度时,最好的做法是创建一个布尔二维数组(如果你想节省空间,则为位向量),其中所有元素最初都设置为false。然后循环NUMBER次,生成随机坐标,并检查数组中的值是否为真。如果为true,则生成另一个随机坐标。如果为false,则将坐标添加到列表中,并将数组中的相应元素设置为true。
以上假设您希望完全 NUMBER个点,并且完全均匀地放置它们。如果不需要这些约束中的任何一个,那么可能存在使用更少内存的其他算法。
答案 2 :(得分:0)
一种解决方案是随机放置点,看它们是否重叠,然后重新尝试重叠。为避免测试每个点,您需要按空间设置索引 - 如果您有一个100 * 100的平面和3-4的截止,您可以使用10 * 10网格方格。然后你必须搜索四个网格方块来检查你没有受到打击。
但还有其他方法可以做到这一点。将点均匀地放置在网格上将创建泊松分布。因此,对于每个点,您可以使用泊松分布创建随机数。当你得到2个或更多时会发生什么?此方法强制您回答该问题。也许你人为地夹在一个,也许你进入相邻的插槽。这种方法不会产生确切的N点,所以如果你必须有N,你可以加入一个软糖(随机添加/删除最后几个点)。