我在一组中具有相当大的一组2D点(~20000),并且对于x-y平面中的每个点想要确定来自该组的哪一点最接近。 (实际上,这些点是不同类型的,我只想知道哪种类型最接近,而xy平面是位图,比如说640x480)。使用网格划分的2D中的最近邻居搜索
从this answer到问题“All k nearest neighbors in 2D, C++”我的想法是做一个网格。我创建了n * m个C++向量,并将这些点放入向量中,具体取决于它落入哪个bin。这个想法是,你只需要检查仓内点的距离,而不是所有的点。如果垃圾箱中没有点,则以螺旋方式继续相邻垃圾箱。
不幸的是,我只看过奥利查尔斯沃思的评论算账:
不只是相邻的,不幸的是(考虑到在细胞点的两个 向东可能比点更接近直接在单元格东北部,例如: ;这个问题在更高维度上变得更糟)。 另外,如果相邻单元碰巧有少于10个点的话呢?在实践中,你需要“螺旋形”。
幸运的是,我已经有不断上升的代码想通了(一个不错的C++ version here,并有在同一个问题的其他版本)。但我还是留下的问题:
如果我发现小区内的打击,有可能是在相邻的小区更近的命中(黄色是我的探头,红色的是错误的选择,绿色实际的最近点):
如果我发现相邻小区一击,有可能是在细胞内命中2步之遥,为奥利查尔斯沃思说:
但更糟糕的是,如果我在两步之外的单元格中发现命中,那么三步之外的命中仍然可能更接近命中!这意味着我不得不考虑所有的细胞与DX,DY = -3 ... 3,或49细胞!
现在,在实践中,这不会经常发生,因为我可以选择我的窗口尺寸使细胞充满足够。不过,我想得到一个正确的结果,而不是遍历所有点。
那么,我该如何找出何时停止“螺旋”或搜索?我听说有多个重叠网格的方法,但我不太明白。是否有可能挽救这种网格技术?
你的观点是静态的还是动态的?对一个点集执行多少个“最近查询”查询? – MBo 2013-04-05 03:06:50
是 - 有没有原因不使用现有的良好开发的库,如内部使用kd树的ANN?或者是 - 出于好奇? – WhitAngl 2013-04-05 23:26:37