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 是否有一个有效的算法来生成平面上一般位置的随机点?_Algorithm_Random_Geometry_Computational Geometry - Fatal编程技术网

Algorithm 是否有一个有效的算法来生成平面上一般位置的随机点?

Algorithm 是否有一个有效的算法来生成平面上一般位置的随机点?,algorithm,random,geometry,computational-geometry,Algorithm,Random,Geometry,Computational Geometry,我需要在平面上的一般位置生成n个随机点,即没有三个点可以位于同一条线上。点的坐标应该是整数,并且位于固定的正方形m x m内。解决此类问题的最佳算法是什么 更新:正方形与轴对齐。嗯,您不需要指定哪个平面。。但只需生成3个随机数并分配给x、y和z 如果“平面”是任意的,那么每次都设置z=o或其他 检查x和y是否在m边界内 比较第三个x,y对,看看它是否与前两个在同一条线上。。。如果是,则重新生成随机值。在添加每个点时,无法找到任何方法来检查每个点,方法是(a)遍历它可能位于的所有可能的行,或者(b

我需要在平面上的一般位置生成n个随机点,即没有三个点可以位于同一条线上。点的坐标应该是整数,并且位于固定的正方形m x m内。解决此类问题的最佳算法是什么


更新:正方形与轴对齐。

嗯,您不需要指定哪个平面。。但只需生成3个随机数并分配给x、y和z

如果“平面”是任意的,那么每次都设置z=o或其他

检查x和y是否在m边界内


比较第三个x,y对,看看它是否与前两个在同一条线上。。。如果是,则重新生成随机值。

在添加每个点时,无法找到任何方法来检查每个点,方法是(a)遍历它可能位于的所有可能的行,或者(b)在添加过程中消除冲突点,以减少下一个点的可能位置。在这两者中,(b)似乎可以提供更好的性能。

由于它们是正方形中的整数,请将它们视为位图中的点。在第一个点之后添加点时,使用Bresenham算法在穿过新点和旧点的每条线上绘制所有像素。当你需要添加一个新的点,得到一个随机的位置,并检查它是否清晰;否则,请再试一次。由于每对像素都会产生一条新线,因此会排除多达m-2个其他像素,随着点数的增加,在找到一个好的像素之前,您将有多个随机选择被拒绝。我建议的方法的优点是,当你有一个好的选择时,你只需支付通过所有线路的费用,而拒绝一个坏的选择是一个非常快速的测试


(如果您想使用不同的直线定义,只需用适当的算法替换Bresenham的)

类似于@LaC的答案。如果内存不是问题,您可以这样做:

Add all points on the plane to a list (L).
Shuffle the list.
For each point (P) in the list,
   For each point (Q) previously picked,
     Remove every point from L which are linear to P-Q.
   Add P to the picked list.
你可以继续外循环,直到你有足够的点,或者用完它们。

这可能只是可行的(尽管可能有点随机限制)。在正方形内找到你能画的最大的圆(这似乎是可行的)。在圆上拾取任意n个点,三个点都不会共线:-)

在代码中,这应该是一个足够简单的任务。假设圆以原点为中心(这样的形式是x^2+y^2=r^2)。假设r是固定的,x是随机生成的,可以通过求解来找到y坐标。这将在圆上为每个x提供两个完全相反的点。希望这有帮助


编辑:哦,整数点,刚刚注意到。真遗憾。不过,我会继续使用这个解决方案,因为我喜欢这个想法,

无论是@LaC还是@MizardX的解决方案都非常有趣,但您可以将它们结合起来,得到更好的解决方案

@LaC解决方案的问题是,您会被拒绝随机选择。您已经生成的点数越多,生成新点数就越困难。如果只剩下一个可用位置,则随机选择该位置的几率很小(1/(n*m))

在@MizardX的解决方案中,您永远不会得到被拒绝的选择,但是,如果您直接实现“从L中删除与p-Q线性的每个点”步骤,您将得到更糟糕的复杂性(O(n^5))

相反,最好使用位图查找要从L中删除的点。位图将包含一个值,该值指示一个点是否可以自由使用以及它在L列表中的位置,或者一个值指示该点已被划掉。通过这种方式,可以得到最坏情况下的复杂度O(n^4),这可能是最优的

编辑:

我刚刚发现了这个问题:
它和这个非常相似。最好使用这个答案中的解决方案。稍微修改它以使用基数或桶排序,并将所有n^2个可能的点最初添加到P集并对其进行洗牌,还可以使用更简单的代码获得最坏情况下的复杂性O(n^4)。此外,如果空间是一个问题,@LaC的解决方案由于空间需求而不可行,那么该算法将无需修改即可适应,并提供相当的复杂性。

以下是一篇可能解决您的问题的论文:

点集在一般位置上具有许多 “模式的类似副本”


BERNARDO M.Abreego和SILVIA FERNANDEZ-MERCHANT所著

正方形是否与轴线对齐?如果是这样的话,我相信坐标实际上只是m²大小的网格上的点。是的,确实如此。复杂的是,三个点不应该位于同一条线上。我只是想指出,这是非常不随机的。你认为什么是一条线?由于您使用的是整数,实际碰撞的机会很少。@Danylo:“直线”仍然不明确:)您是指欧几里德线还是曼哈顿/出租车/L1线?这个答案中的每一行在某些小方面都是错误的。以随机数生成为例。。你不会生成任意的随机数,你会生成在范围内的随机数。你不会将第三个与前两个进行比较,而是将一个新元素与每一个可能的元素对进行比较。我同意你的选项(b),在约束编程社区中称之为正向检查,但问题是某些点对可能会比其他点消除更多的点,因此,这种生成和测试方法需要回溯或随机重新启动才能完成。您需要记住所有当前存在的行,例如,通过它们的系数。添加新点A后,您将遍历所有现有点,为每个点Bi构建ABi线,并检查(使用二进制搜索)它是否已经在您的线集中。如果是,则需要重新生成点A。对于n,它接近于n^2*log(n)