我知道如何构建一个kd树。但我面临的问题是如何使用KD Tree找到最近邻居。我在google上搜索但是找不到找到最近邻居的代码,尽管给出了algos。但由于语言的原因,我很难将该算法转换为代码。
您能否在java中为我提供可理解的NNSearch代码?
答案 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)