我的 KD-Tree 出了啥问题? (K=2)

Posted

技术标签:

【中文标题】我的 KD-Tree 出了啥问题? (K=2)【英文标题】:What's wrong with my KD-Tree? (K=2)我的 KD-Tree 出了什么问题? (K=2) 【发布时间】:2009-04-25 20:19:16 【问题描述】:

更具体地说,我的最近邻搜索有问题。我已确认树已正确构建,并且所有辅助函数都按预期工作。

请注意,这与标准 KD 树略有不同,因为我正在寻找最接近的 3 个点。

struct Node

unsigned int axis;
Point* obj;

struct Node* left;
struct Node* right;
;


void _findClosest(struct Node* current, Point* to, Point** first, Point** second, Point** third, unsigned int depth)

if(current == NULL) return;

if(current->left == NULL && current->right == NULL)

            //_setOrder updates first, second, and third so that they point to
            //objects that are closest to "to", given an object and the current
            //current first, second, and third.
    _setOrder(to, current->obj, first, second, third);
    return;


unsigned int axis = depth % 2;
struct Node* other = NULL;

if(to->getValue(axis) < current->obj->getValue(axis))

    other = current->right;
    _findClosest(current->left, to, first, second, third, depth+1);

else

    other = current->left;
    _findClosest(current->right, to, first, second, third, depth+1);


_setOrder(to, current->obj, first, second, third);

if(other == NULL) return;

double searchToBest = _largestDistance(to, *first, *second, *third);
double searchToSplit = _distance(to, current->obj, current->axis);

    //This branch is ALWAYS taken, so this devolves into an O(n) search
if(searchToBest >= searchToSplit)

    _findClosest(other, to, first, second, third, depth+1);


我想我只是在某种程度上误解了数据结构/算法。

小细节: - 如果对 NULL 对象调用距离函数,它们返回 std::numberic_limits::max() - 这在 KD 树的根上调用,深度为 0,*first = *second = *third = NULL -axis = 0对应X,axis = 1对应Y

问题是每个节点都被访问了,而不是看到利用树属性的预期减少。无论缺陷是什么,它都会使这成为一个 O(n) 搜索。

【问题讨论】:

你能举个例子说明它做错了什么吗? 现在在问题中澄清:基本上它可以工作,但它一直访问每个节点。 【参考方案1】:

这一行是错误的:

double searchToSplit = _distance(to, current->obj, current->axis);

你想要轴,而不是当前轴->轴。

【讨论】:

以上是关于我的 KD-Tree 出了啥问题? (K=2)的主要内容,如果未能解决你的问题,请参考以下文章

Kd-tree算法原理

BZOJ-4520K远点对 KD-Tree + 堆

bzoj4520[Cqoi2016]K远点对 KD-tree+堆

BZOJ2989数列 kd-tree

bzoj2989数列 KD-tree

如何使用 Scipy 的 Kd-tree 函数来加速 K-Nearest Neighbors (KNN) [关闭]