【问题标题】:Find nearest edge in graph在图中找到最近的边
【发布时间】:2013-11-22 10:34:44
【问题描述】:

我想在图中找到最近的边。考虑以下示例:

图1: 黄色:顶点,黑色:边,蓝色:查询点

一般信息: 该图包含大约 1000 万个顶点和大约 1500 万条边。每个顶点都有坐标。边由两个相邻的顶点定义。

最简单的解决方案: 我可以简单地计算从查询点到图中所有其他边的距离,但这会非常慢。

想法和困难: 我的想法是使用一些空间索引来加速查询。我已经实现了一个 kd-tree 来找到最近的顶点。但如图 1 所示,入射到最近顶点的边不一定是离查询点最近的。我会得到边缘 3-4 而不是更近的边缘 7-8

问题: 有没有一种算法可以在图中找到最近的边?

【问题讨论】:

  • 我假设你所有的边都是直线?
  • 是的,他们是直的。
  • ... 顶点有坐标 ...,就像方形网格上的笛卡尔坐标纬度/经度?或其他一些特定领域的坐标系?极坐标?
  • 纬度/经度坐标。该图是一个国家规模的道路网络。边缘可能短于 1000 米。
  • 嘿,你知道如何解决这个问题吗?

标签: algorithm geometry computational-geometry graph-algorithm


【解决方案1】:

您可以计算 voronoi 图并在每个 voronoi 单元上运行查询。您可以细分 voronoi 图以获得更好的结果。可以结合metric和voronoi图:http://www.cc.gatech.edu/~phlosoft/voronoi/

【讨论】:

  • PSLG 段的 Voronoi 图是众所周知的难以计算的东西,会导致各种数值精度问题。它也不是一个适合高效点位置查询的结构,因此仍然需要额外的空间剔除结构。我同意这是“正确的解决方案”,但它不太可能是最实用的解决方案。
  • 组合...什么?该链接上有一些漂亮的图片,但我看不出它们的底层结构与 OP 的问题有什么真正的关系。他们使用基于 voronoi 的函数来为像素着色。它对于定位最近的边缘一点用处都没有。
  • @Sneftel:您可以使用分层集群,然后计算每个级别的 voronoi 图。它会给出一个voronoi-tree?
  • 如果黄色折线是静态的(或至少移动缓慢),那么这就是答案。如果每个点查询针对的是一组不同的折线,那么 voronoi gram 仅代表不必要的开销。
【解决方案2】:

有一些空间查询结构适用于点以外的其他类型的数据。最通用的是“R-tree”结构(及其许多变体),它允许您存储线段的边界矩形。然后,您可以从查询点向外搜索,检查边界矩形中的线段,并在最近的剩余矩形比目前遇到的最近线更远时停止。当有许多长线段重叠时,这可能会导致性能不佳,但对于您似乎在这里的 PSLG,这不应该发生。

另一种选择是使用段来定义 BSP 树,然后从您的点向外扫描以找到所有“可见”行。如果您的点可以看到很多边,这反过来又会有问题。

【讨论】:

  • R-Tree 真的是处理这类问题的有效方法吗?我认为由于它的通用方法,与专门用于直线的方法相比,性能会很差。
  • 如果不尝试就很难说。我的猜测是,考虑到您的用例中最小的重叠和短段,它会很好。在我研究更奇特的解决方案之前,这是我首先要尝试的。
  • 我认为四叉树仅用于点数据(如 kD 树)。但显然边缘确实有一个变体:en.wikipedia.org/wiki/Quadtree#Edge_quadtree。你是这个意思吗?
  • 所以想法是为四叉树中的每个单元格存储与单元格重叠的边缘?如果有两条重叠边,(最后一级)单元格将包含两条边?
  • 你能详细说明一下吗?我不明白这个问题。我读过这个问题:stackoverflow.com/questions/6042729/…,我很难理解。谢谢。
【解决方案3】:

没有证据:
您从constrained Delaunay Triangulation 开始,这是一个将现有边考虑在内的三角剖分。例如。 CGALTriangle 可以做到这一点。对于每个查询点,您确定它属于哪个三角形。然后,您只需要检查接触该三角形一角的边缘即可。
我认为这在大多数情况下应该有效,但肯定有一些极端情况会失败,例如当有很多没有任何边的顶点时,至少你必须删除那些空顶点。

【讨论】:

    【解决方案4】:

    一个非常简单的解决方案(但可能不是复杂度最低的解决方案)是根据边界框对所有边缘使用quad tree。然后,您只需提取最接近查询点的边集并遍历它们以找到最近的边。

    四叉树返回的提取边集应该比原来的 1500 万条边小很多,因此迭代成本要低得多。

    四叉树是比 R 树更简单的数据结构。它相当普遍,应该在许多环境中都可以使用。例如,在 Java 中,JTS Topology Suite 有一个结构 QuadTree,可以很容易地包装它来执行此任务。

    【讨论】:

    • 嘿,计划实现一个最近邻算法,使用四叉树找到最近的边。但是,我没有完全理解您的解决方案。 “根据边界框对所有边缘使用四叉树”我将所有节点都存储在四叉树中。您是否建议我将边缘存储在单独的四叉树中?谢谢!
    【解决方案5】:

    您可以在长边中插入额外的顶点以获得基于最近顶点的近似值..

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-09-16
      • 2020-12-28
      • 2021-07-20
      • 1970-01-01
      • 2013-01-05
      • 1970-01-01
      相关资源
      最近更新 更多