使用KDtree的最近邻居

时间:2016-12-29 05:22:37

标签: java data-structures

我知道如何构建一个kd树。但我面临的问题是如何使用KD Tree找到最近邻居。我在google上搜索但是找不到找到最近邻居的代码,尽管给出了algos。但由于语言的原因,我很难将该算法转换为代码。

您能否在java中为我提供可理解的NNSearch代码?

2 个答案:

答案 0 :(得分:1)

这是伪代码,假设目标点未存储在树中。 (如果是,只需添加逻辑来忽略它):

nearest_point = NULL
nearest_distance = INFINITE;
target_point = <set to the target point>

void nn_search(KD_NODE node) {
  FLOAT d = node->point.distance_to(target_point);
  if (d < nearest_distance) {
    nearest_distance = d;
    nearest_point = node->point;
  }
  BOX left_bb = node->left.bounding_box();
  BOX right_bb = node->right.bounding_box();
  if (left_bb.contains(target)) {
    search_children(node->left, node->right, right_bb);
  else { // right_bb must contain target
    search_children(node->right, node->left, left_bb);
  }
}

void search_children(KD_NODE a, KD_NODE b, BOX b_bb) {
  nn_search(a);
  // This condition makes the search expected O(log n) time rather than O(n).
  // Skip searching the other child unless it might improve the answer.
  if (b_bb.contains_point_closer_than(target, nearest_distance)) {
    nn_search(b);
  }
}

运行完毕后,nearest_point包含距离目标最近的点。请注意,将边界框计算为nn_search的参数很简单,而不是将它们存储在节点中,而这些代码似乎也是如此。在生产代码中,您需要这样做以节省每个节点4个浮点数的空间。为简单起见,我省略了参数。

如果在边界框中存在任何点,谓词contains_point_closer_than返回true,该点比给定距离更接近目标。令人高兴的是,只考虑方框中的一点就足够了。例如,如果当前节点将搜索空间分成X左右两半​​,那么您只需要考虑点(X, Y_target)及其到目标的距离。那距离只是abs(X - X_target)!我会让你在没有进一步讨论的情况下说服自己

答案 1 :(得分:0)

我知道两个支持kNN搜索的Java kd-tree实现,herehere。他们的表现似乎大致相当。