最近邻区域可视化

时间:2012-02-15 06:32:03

标签: algorithm computational-geometry data-visualization kdtree space-partitioning

我正在编写一个使用k-d tree在二维空间中查找点的应用。在开发过程中,能够“看到”每个点周围的最近邻区域会很好。

在附图中,红点是k-d树中的点,每个点周围的蓝线限定了最近邻搜索将返回包含点的区域。

因此创建了图像:

for each point in the space:
  da = distance to nearest neighbor
  db = distance to second-nearest neighbor
  if absolute_value(da - db) < 4:
    draw blue pixel

该算法有两个问题:

  • (更重要)我的(相当快的Core i7)计算机速度很慢。
  • (不太重要)它很草率,你可以看到蓝线的宽度变化。

一组点的“可视化”是什么?

创建这样的可视化有哪些好的算法?

partitions

4 个答案:

答案 0 :(得分:7)

这称为 Voronoi Diagram ,并且有许多优秀的算法可以有效地生成它们。我最常听到的是 Fortune's algorithm ,它在时间O(n log n)内运行,但其他算法也存在此问题。

希望这有帮助!

答案 1 :(得分:4)

雅各

嘿,你找到了一种有趣的方法来生成这个Voronoi图,即使它不是那么有效。

首先不太重要的问题:你得到的不同厚度边界,那些蝴蝶形状,实际上是双曲线的两个分支之间的区域。正是由公式| da-db |给出的双曲线= 4.要获得粗线,您必须修改此标准并将其替换为距离两个最近邻居的平分线的距离,设A和B;使用矢量微积分,| PA.AB / || AB || - || AB || / 2 | &LT; 4。

更重要的问题:有两个众所周知的有效解决方案来构建一组点的Voronoi图:Fortune的扫描算法(如templatetypedef所述)和Preparata&amp; Shamos'Divide&amp;征服解决方案。对于N点,两者都以最佳时间O(N.Lg(N))运行,但实现起来并不容易。

这些算法将Voronoi图构建为一组线段和半线。检查http://en.wikipedia.org/wiki/Voronoi_diagram

本文“操纵一般细分的原语和Voronoi的计算”描述了两种算法,它们使用了一个有点高级的框架,关注所有实现细节;这篇文章很难,但算法是可以实现的。

您可能还会看一下“平面Voronoi图的直接迭代算法”,这是我从未尝试过的。

一种完全不同的方法是直接从给定点构建距离图,例如通过Dijkstra算法:从给定点开始,在每个点的给定距离内增长区域的边界,然后停止增长当两个边界相遇时。 [需要更多解释。]请参阅http://1.bp.blogspot.com/-O6rXggLa9fE/TnAwz4f9hXI/AAAAAAAAAPk/0vrqEKRPVIw/s1600/distmap-20-seed4-fin.jpg

另一个好的起点(用于有效计算距离图)可以是“用于计算线性时间距离变换的通用算法”。

答案 2 :(得分:2)

从个人经验来看:Fortune的算法很难实现。 Guibas和Stolfi提出的分而治之算法并不算太糟糕;它们提供了详细的伪代码,可以很容易地转换成过程式编程语言。如果您有几乎退化的输入并使用浮点,爆炸,但由于基元是二次的,如果您可以将坐标表示为32位整数,那么您可以使用64位来执行决定因素计算。

一旦你开始工作,你可以考虑用具有Theta(√n)最坏情况的kd-tree算法替换用于平面细分的算法。

答案 3 :(得分:1)

您可以在D3.js库找到一个很棒的实现:http://mbostock.github.com/d3/ex/voronoi.html