如果网格中有一组随机点,你如何检查有效它们都位于其他点的固定范围内。即:选择任意一个随机点,然后导航到网格中的任何其他点。
进一步澄清:如果你有一个1000 x 1000的网格并随机放置100个点,你怎么能证明任何一个点在一个邻居的100个单位内并且所有点都可以从一个点走到另一个点?
我一直在写一些代码,并提出了一个有趣的问题:非常偶尔(到目前为止只有一次)它会创建一个点数岛,超过其余点的最大范围。我需要解决这个问题,但蛮力似乎不是答案。
它是用Java编写的,但我对伪代码或C ++都很好。
答案 0 :(得分:2)
我喜欢@ joel.neely的construction approach但是如果你想确保更均匀的密度,这更有可能起作用(尽管它可能产生更多的集群而不是整体的均匀密度):
P_j
P_i
,P_i
)<的随机点P_j
100,重复以下步骤,直到在下面的子步骤4中选择有效的P_i
:
P_i
)=坐标(P_j
)+(dx,dy)。P_i
位于整个有效网格中,则该文件无效。答案 1 :(得分:1)
快速思考:如果将网格划分为50x50补丁,并且放置初始点,则还会记录它们属于哪个补丁。现在,当你想检查一个新点是否在其他点的100像素范围内时,你只需检查补丁加上它周围的8点,看看点数是否匹配。
,例如,你知道你有100个随机点,每个补丁包含它们包含的点数,你可以简单总结并查看它是否确实为100 - 这意味着所有点都可以到达。
我确信还有其他方法,很难。
编辑:50x50补丁的左上角到右下角的距离是sqrt(50 ^ 2 + 50 ^ 2)= 70分,所以你可能不得不选择较小的补丁大小。也许35或36会做(50 ^ 2 = sqrt(x ^ 2 + x ^ 2)=> x = 35.355 ......)。
答案 2 :(得分:1)
找到点集的convex hull,然后使用rotating calipers方法。凸壳上最远的两个点是该组中最远的两个点。由于所有其他点都包含在凸包中,因此保证它们比两个极值点更接近。
答案 3 :(得分:1)
就评估现有的点集而言,这看起来像是一种Euclidean minimum spanning tree问题。维基百科页面声明这是Delaunay triangulation的子图;所以我认为计算Delaunay三角剖分(参见prev。参考或谷歌“计算几何”)然后最小生成树并验证所有边的长度都小于100就足够了。
从阅读参考文献看来,这是O(N log N),也许有更快的方法,但这已足够。
更简单(但效率可能更低)的算法类似于以下内容:
j<0
或P[i].x - P[j].x > R
,停止失败。(存在间隙,并且半径为R的所有点都无法达到)(P[i].x-P[j].x)^2 + (P[i].y-P[j].y)^2 <
R ^ 2`,则点P [i]可以通过半径R内的先前点之一到达,并返回步骤4。编辑:这可以修改为应为O(N log N)的东西,但我不确定:
j<i
和P [i] .x-R与P [i] .x之间的x坐标都在集合YLIST中。答案 4 :(得分:1)
新增和改进; - )
感谢Guillaume和Jason S的评论让我思考了一下。这产生了第二项提案,其统计数据显示出了显着的改善。
Guillaume评论说,我发布的早期策略会失去统一的密度。当然,他是对的,因为它本质上是一个“酒鬼的行走”,往往围绕着原点。然而,点的均匀随机放置产生了很大的失败“路径”要求的可能性(所有点都可以通过没有大于100的步长的路径连接)。对这种情况的测试是昂贵的;产生纯粹随机的解决方案直到一次通过更是如此。
杰森S提供了一个变体,但是对大量模拟的统计测试使我得出结论,他的变异产生的模式与我的第一个提议中的模式一样(基于检查平均值和坐标的标准。)值)。下面修订的算法产生的点集的统计量与纯(均匀)随机放置的统计量非常相似,但是由构造保证以满足路径要求。不幸的是,可视化比口头解释更容易。实际上,它要求点在一个模糊的一致方向(NE,SE,SW,NW)中随机错开,只有在“从墙上反弹”时才会改变方向。
以下是高级概述:
随机选择一个初始点,将水平行程设置为RIGHT,将垂直行程设置为DOWN。
重复剩余的点数(例如原始规格中的99):
2.1。随机选择距离介于50和100之间的dx和dy。(我假设欧几里德距离 - 平方和的平方根 - 在我的试验实施中,但“出租车”距离 - 绝对值之和 - 会更容易代码。)
2.2。根据水平和垂直行程(向右/向下 - >添加,向左/向上 - >减去)将dx和dy应用于上一点。
2.3。如果任一坐标超出范围(小于0或至少1000),则反映违反边界的坐标,并以相反方向替换其行程。这意味着四种情况(2个坐标x 2个边界):
2.3.1. if x < 0, then x = -x and reverse LEFT/RIGHT horizontal travel.
2.3.2. if 1000 <= x, then x = 1999 - x and reverse LEFT/RIGHT horizontal travel.
2.3.3. if y < 0, then y = -y and reverse UP/DOWN vertical travel.
2.3.4. if 1000 <= y, then y = 1999 - y and reverse UP/DOWN vertical travel.
请注意,步骤2.3中的反射保证将新点保留在前一点的100个单位内,因此保留了路径要求。然而,水平和垂直行程约束迫使点的产生在整个空间中随机“扫描”,产生比原始纯粹的“酒鬼步行”算法更多的总色散。
答案 5 :(得分:1)
如果我正确理解您的问题,给定一组站点,您需要测试每个站点的最近邻居(对于L1距离,即网格距离)是否距离小于值K.
通过计算点集的Delaunay三角剖分,可以很容易地获得欧几里德距离:站点的最近邻居是Delaunay三角剖分中的邻居之一。有趣的是,L1距离大于欧几里德距离(在因子sqrt(2)内)。
以下是测试您的状况的方法如下:
可以通过多种方式改进此算法:
答案 6 :(得分:0)
通过施工强制所需的条件。不是仅通过绘制随机数来放置所有点,而是按如下方式约束坐标:
随机放置一个初始点。
重复剩余的点数(例如99):
2.1。随机选择前一点某个范围(例如90)内的x坐标。
2.2。计算y坐标的合法范围,使其在前一点的100个单位内。
2.3。随机选择该范围内的y坐标。
如果您想完全遮盖原点,请按坐标对对点进行排序。
这对于纯随机性不需要太多开销,但是将保证每个点在至少一个其他点的100个单位内(实际上,除了第一个和最后一个,每个点将在两个其他点。)
作为上述变体,在步骤2中,随机选择任何已生成的点并将其用作参考而不是前一点。