c++ - 使用nanoflann的缠结行为

标签 c++ kdtree flann

使用nanoflann -library基于KDTree进行k最近邻搜索时,我遇到了一个非常奇怪的行为。我的代码是一组简单的查询:

#include <vector>
#include <iostream>
#include <nanoflann.hpp>
#include <eigen3/Eigen/Dense>

using Eigen::MatrixX3d;
using Eigen::Vector3d;

using nanoflann::KNNResultSet;
using nanoflann::SearchParams;
using kdt = nanoflann::KDTreeEigenMatrixAdaptor<MatrixX3d, 3, nanoflann::metric_L2>;

int main()
{
    // Create simple matrix
    MatrixX3d matrix(10, 3);
    for(unsigned int i = 0; i < 10; i++)
    {
        double f_i = static_cast<double>(i);
        matrix.row(i) = Vector3d(f_i, 0, 0);
    }

    // Create test points
    std::vector<Vector3d> test_vecs;
    for(unsigned int i = 0; i < 10; i++)
    {
        double f_i = static_cast<double>(i);
        test_vecs.push_back(Vector3d(f_i, f_i, f_i));
    }
    
    // Result buffer
    double distance;
    size_t index;
    KNNResultSet<double> result_set(1);
    result_set.init(&index, &distance);
    SearchParams sp;
    // KDTree
    kdt matrix_index(3, std::ref(matrix), 10);
    matrix_index.index->buildIndex();

    //Query points backwards
    for(int i = 9; i >= 0; i--)
    {
        Vector3d curr_vec = test_vecs.at(i);
        matrix_index.index->findNeighbors(result_set, &curr_vec[0], sp);
        std::cout << i << std::endl;
        std::cout << index << " " << distance << std::endl << std::endl;
    }

    // Query points forwards
    for(unsigned int i = 0; i < 10; i++)
    {
        Vector3d curr_vec = test_vecs.at(i);
        matrix_index.index->findNeighbors(result_set, &curr_vec[0], sp);
        std::cout << i << std::endl;
        std::cout << index << " " << distance << std::endl << std::endl;
    }
}
向后查询(BQ)返回预期结果。但是,前向查询(FQ)仅产生零(索引和距离)。 FQ似乎也完全破坏了KDTree。如果更改两个查询的顺序(最后两个for循环),则在FQ之前执行BQ,两者现在都只会产生零。
为什么会发生这种行为,以及如何规避它?

最佳答案

结果集似乎是有状态的-它始终向您显示所有点中最近的总体邻居。例如,如果您从5循环到10,则每次迭代都会获得5 50每次迭代重新初始化结果集,您将获得所需的行为:

result_set.init(&index, &distance);
matrix_index.index->findNeighbors(result_set, &curr_vec[0], sp);
演示:https://godbolt.org/z/s5f1jq

关于c++ - 使用nanoflann的缠结行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65099735/

相关文章:

c++ - 从终端编译框架(cppunit、boost、++)以使用 Xcode 4.6

c# - 四叉树和Kd树

python - OpenCV 中的 Flann KNN Matcher 只返回一个点而不是一对

visual-studio-2012 - 在 vs2012 中构建 pcl 时 C++ CMake FLANN 失败

c++ - PCL 1.8.0 项目的链接器错误

c++ - 另一个 C++ 临时生命周期困惑

c++ - C++ (GCC) 中的四倍精度

c++ - 在 C++ 中返回指向具有普通函数和 void 函数的动态分配数组的指针

c++ - 从二维平衡 KD 树中删除元素

python - 满足条件的最近 k 个邻居(python)