Kd-Tree有缺陷的K最近邻居

时间:2016-11-17 02:46:43

标签: c++ algorithm data-structures nearest-neighbor kdtree

免责声明:以下代码中存在一些不良做法

您好,我刚才有一些关于如何正确格式化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树。任何对更好的例子的指导都将非常感激。

2 个答案:

答案 0 :(得分:0)

我建议您按照Wikipedia的说法执行,针对您的具体问题,请执行以下操作:

  

从根节点开始,算法向下移动树   递归地,以与搜索点相同的方式递归   被插入(即它是向左还是向右,取决于是否   point小于或大于拆分中的当前节点   尺寸)。

回答这个问题。当然,你可以记住这个形象:

enter image description here

如果您在示例中有更多两个维度,则只需在第一个维度中拆分,然后在第二个维度中拆分,然后在第三个维度中拆分,然后在第四个维度中拆分,依此类推,然后遵循循环策略,当你到达最终尺寸时,你会再次从第一个尺寸开始。

答案 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的预期一致。在你使用它之后,你可以将它作为基础实现来挤出额外的比较。

相关问题