连接点与网格

时间:2008-12-30 13:06:31

标签: algorithm geometry

如果网格中有一组随机点,你如何检查有效它们都位于其他点的固定范围内。即:选择任意一个随机点,然后导航到网格中的任何其他点。

进一步澄清:如果你有一个1000 x 1000的网格并随机放置100个点,你怎么能证明任何一个点在一个邻居的100个单位内并且所有点都可以从一个点走到另一个点?

我一直在写一些代码,并提出了一个有趣的问题:非常偶尔(到目前为止只有一次)它会创建一个点数岛,超过其余点的最大范围。我需要解决这个问题,但蛮力似乎不是答案。

它是用Java编写的,但我对伪代码或C ++都很好。

7 个答案:

答案 0 :(得分:2)

我喜欢@ joel.neely的construction approach但是如果你想确保更均匀的密度,这更有​​可能起作用(尽管它可能产生更多的集群而不是整体的均匀密度):

  1. 通过从有效网格内的均匀分布中选择x,y来随机放置初始点P_0
  2. 对于i = 1:N-1
    1. 选择随机j =从0到i-1均匀分布,识别先前放置的点P_j
    2. 选择距离(P_iP_i)<的随机点P_j 100,重复以下步骤,直到在下面的子步骤4中选择有效的P_i
      1. 选择(dx,dy)均匀分布在-100到+100
      2. 之间
      3. 如果dx ^ 2 + dy ^ 2> 100 ^ 2,距离太大(21.5%的时间失败),回到上一步。
      4. 计算候选坐标(P_i)=坐标(P_j)+(dx,dy)。
      5. 如果
      6. 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),也许有更快的方法,但这已足够。

更简单(但效率可能更低)的算法类似于以下内容:

  1. 给定:这些点位于从索引0到N-1的数组中。
  2. 按x坐标顺序对点进行排序,即O(N log N)以进行有效排序。
  3. 初始化i = 0。
  4. 增量i。如果i == N,停止成功。(所有点都可以从另一个半径为R的地方到达)
  5. 初始化j = i。
  6. 减少j。
  7. 如果j<0P[i].x - P[j].x > R停止失败。(存在间隙,并且半径为R的所有点都无法达到)
  8. 否则,如果P [i] .x和P [j] .x在彼此的R之内,我们就到达此处。检查点P [j]是否足够接近P [i]:如果(P[i].x-P[j].x)^2 + (P[i].y-P[j].y)^2 < R ^ 2`,则点P [i]可以通过半径R内的先前点之一到达,并返回步骤4。
  9. 继续尝试:回到第6步。
  10. 编辑:这可以修改为为O(N log N)的东西,但我不确定:

    1. 给定:这些点位于从索引0到N-1的数组中。
    2. 按x坐标顺序对点进行排序,即O(N log N)以进行有效排序。
    3. 以y坐标顺序维护点的有序集合YLIST,将YLIST初始化为集合{P [0]}。我们将从左到右扫描x坐标,逐点向YLIST添加点,并删除x坐标距离新添加点太远的点。
    4. 初始化i = 0,j = 0。
    5. 此时循环不变总是为真:所有点P [k]其中k <= i形成一个网络,在该网络中,它们可以通过半径R彼此到达.YLIST中的所有点都具有位于P之间的x坐标[i] .xR和P [i] .x
    6. 增量i。如果i == N,成功停止
    7. 如果P [i] .x-P [j] .x <= R,转到步骤10.(如果i == j,则自动为真)
    8. 点P [j]无法从半径为R的点P [i]到达。从YLIST中删除P [j](这是O(log N))。
    9. 增加j,转到第6步。
    10. 此时,所有点P [j] j<i和P [i] .x-R与P [i] .x之间的x坐标都在集合YLIST中。
    11. 将P [i]添加到YLIST(这是O(log N)),并记住YLIST中的索引k,其中YLIST [k] == P [i]。
    12. 点YLIST [k-1]和YLIST [k + 1](如果它们存在; P [i]可能是YLIST中唯一的元素,或者它可能处于极端)是YLIST到P的最近点[i]中。
    13. 如果点YLIST [k-1]存在并且在P [i]的半径R内,则P [i]可以从至少一个先前点到达半径R.转到第5步。
    14. 如果点YLIST [k + 1]存在并且在P [i]的半径R内,则P [i]可以从至少一个先前点到达半径为R.转到第5步。
    15. P [i]无法从之前的任何点到达。 停止失败。

答案 4 :(得分:1)

新增和改进; - )

感谢Guillaume和Jason S的评论让我思考了一下。这产生了第二项提案,其统计数据显示出了显着的改善。

Guillaume评论说,我发布的早期策略会失去统一的密度。当然,他是对的,因为它本质上是一个“酒鬼的行走”,往往围绕着原点。然而,点的均匀随机放置产生了很大的失败“路径”要求的可能性(所有点都可以通过没有大于100的步长的路径连接)。对这种情况的测试是昂贵的;产生纯粹随机的解决方案直到一次通过更是如此。

杰森S提供了一个变体,但是对大量模拟的统计测试使我得出结论,他的变异产生的模式与我的第一个提议中的模式一样(基于检查平均值和坐标的标准。)值)。

下面修订的算法产生的点集的统计量与纯(均匀)随机放置的统计量非常相似,但是由构造保证以满足路径要求。不幸的是,可视化比口头解释更容易。实际上,它要求点在一个模糊的一致方向(NE,SE,SW,NW)中随机错开,只有在“从墙上反弹”时才会改变方向。

以下是高级概述:

  1. 随机选择一个初始点,将水平行程设置为RIGHT,将垂直行程设置为DOWN。

  2. 重复剩余的点数(例如原始规格中的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.
    
  3. 请注意,步骤2.3中的反射保证将新点保留在前一点的100个单位内,因此保留了路径要求。然而,水平和垂直行程约束迫使点的产生在整个空间中随机“扫描”,产生比原始纯粹的“酒鬼步行”算法更多的总色散。

答案 5 :(得分:1)

如果我正确理解您的问题,给定一组站点,您需要测试每个站点的最近邻居(对于L1距离,即网格距离)是否距离小于值K.

通过计算点集的Delaunay三角剖分,可以很容易地获得欧几里德距离:站点的最近邻居是Delaunay三角剖分中的邻居之一。有趣的是,L1距离大于欧几里德距离(在因子sqrt(2)内)。

以下是测试您的状况的方法如下:

  1. 计算网站的Delaunay三角剖分
  2. 对于每个站点s,在三角测量中从s开始广度优先搜索,这样你就可以发现欧几里德距离小于K的所有顶点(Delaunay三角剖分具有距离较小的顶点集合的属性)在三角测量中连接来自给定站点的K)
  3. 对于每个站点s,在距离s小于K的这些顶点中,检查它们中的任何一个是否距离s小于K的L1距离。如果没有,该物业不满意。
  4. 可以通过多种方式改进此算法:

    1. 一旦找到L1距离小于K的站点,第2步的广度优先搜索当然应该停止。
    2. 在搜索s的有效邻居期间,如果发现站点s'与s的L1距离小于K,则无需为s'寻找有效的邻居:s显然是其中之一它们。
    3. 不需要完整的广度优先搜索:在访问s的所有三角形之后,如果三角测量中s的邻居都不是有效邻居(即L1距离小于K的站点),则表示为( v 1 ,...,v n )邻居。最多有四个边(v i ,v i + 1 ),它们与水平轴和垂直轴相交。只能通过这四个(或更少)边缘继续搜索。 [这来自L1球体的形状]

答案 6 :(得分:0)

通过施工强制所需的条件。不是仅通过绘制随机数来放置所有点,而是按如下方式约束坐标:

  1. 随机放置一个初始点。

  2. 重复剩余的点数(例如99):

    2.1。随机选择前一点某个范围(例如90)内的x坐标。

    2.2。计算y坐标的合法范围,使其在前一点的100个单位内。

    2.3。随机选择该范围内的y坐标。

  3. 如果您想完全遮盖原点,请按坐标对对点进行排序。

  4. 这对于纯随机性不需要太多开销,但是将保证每个点在至少一个其他点的100个单位内(实际上,除了第一个和最后一个,每个点将在两个其他点。)

    作为上述变体,在步骤2中,随机选择任何已生成的点并将其用作参考而不是前一点。