免责声明:以下代码中存在一些不良做法
您好,我刚才有一些关于如何正确格式化KD树K最近邻搜索的问题。这是我的功能的一个例子。
void nearest_neighbor(Node *T, int K) {
if (T == NULL) return;
nearest_neighbor(T->left, K);
//do stuff find dist etc
if(?)nearest_neighbor(T->right, K);
}
此代码令人困惑,所以我将尝试解释它。我的函数只取k值和节点T.我想要做的是找到当前节点和结构中每个其他值之间的距离。这些都工作,我遇到的问题是理解何时以及如何调用递归调用nearest_neighbor(T-> left / T-> right,K)我知道我打算修剪右边的调用但是我不知道该怎么做。顺便说一下,这是一个多维KD树。任何对更好的例子的指导都将非常感激。
答案 0 :(得分:0)
我建议您按照Wikipedia的说法执行,针对您的具体问题,请执行以下操作:
从根节点开始,算法向下移动树 递归地,以与搜索点相同的方式递归 被插入(即它是向左还是向右,取决于是否 point小于或大于拆分中的当前节点 尺寸)。
回答这个问题。当然,你可以记住这个形象:
如果您在示例中有更多两个维度,则只需在第一个维度中拆分,然后在第二个维度中拆分,然后在第三个维度中拆分,然后在第四个维度中拆分,依此类推,然后遵循循环策略,当你到达最终尺寸时,你会再次从第一个尺寸开始。
答案 1 :(得分:0)
一般的想法是保持一个最接近目标的全局点,用新发现的点进行更新,并且永远不会下降到一个n-gon中,该n-gon可能包含一个比已经找到的目标更近的点。我用C而不是C ++来表示它。您可以轻松地转换为面向对象的表单。
#define N_DIM <k for the k-D tree>
typedef float COORD;
typedef struct point_s {
COORD x[N_DIM];
} POINT;
typedef struct node_s {
struct node_s *lft, *rgt;
POINT p[1];
} NODE;
POINT target[1]; // target for nearest search
POINT nearest[1]; // nearest found so far
POINT b0[1], b1[1]; // search bounding box
bool prune_search() {
// Return true if no point in the bounding box [b0..b1] is closer
// to the target than than the current value of nearest.
}
void search(NODE *node, int dim);
void search_lft(NODE *node, int dim) {
if (!node->lft) return;
COORD save = b1->p->x[dim];
b1->p->x[dim] = node->p->x[dim];
if (!prune_search()) search(node->lft, (dim + 1) % N_DIM);
b1->p->x[dim] = save;
}
void search_rgt(NODE *node, int dim) {
if (!node->rgt) return;
COORD save = b0->p->x[dim];
b0->p->x[dim] = node->p->x[dim];
if (!prune_search()) search(node->rgt, (dim + 1) % N_DIM);
b0->p->x[dim] = save;
}
void search(NODE *node, int dim) {
if (dist(node->p, target) < dist(nearest, target)) *nearest = *node->p;
if (target->p->x[dim] < node->p->x[dim]) {
search_lft(node, dim);
search_rgt(node, dim);
} else {
search_rgt(node, dim);
search_lft(node, dim);
}
}
/** Set *nst to the point in the given kd-tree nearest to tgt. */
void get_nearest(POINT *nst, POINT *tgt, NODE *root) {
*b0 = POINT_AT_NEGATIVE_INFINITY;
*b1 = POINT_AT_POSITIVE_INFINITY;
*target = *tgt;
*nearest = *root->p;
search(root, 0);
*nst = *nearest;
}
请注意,这不是 最经济的实现。为简单起见,它进行了一些不必要的最近更新和修剪比较。但它的渐近性能与kd-tree NN的预期一致。在你使用它之后,你可以将它作为基础实现来挤出额外的比较。