STL:在大量数据中进行分类和搜索

STL: sorting and searching in enormous data

本文关键字:分类 搜索 数据 STL      更新时间:2023-10-16

我有两组点(sourcetarget(。目的是为每个source点找到唯一1:1最近的邻居 target中的点。

我的尝试是按预期工作,但慢慢慢。我已经测试了几千分,但是在实际情况下,将是数百万。我不是 stl 的专家。有什么建议我如何优化它?

std::vector<UT_Vector3> targetPosVector;
for (auto i = 0; i < targetNumPoints; i++)
{
    auto pos = target->getPos3(i);
    targetPosVector.push_back(pos);
}
std::vector<int> uniqueNeighborVector;
for (auto ptoff = 0; ptoff < sourceNumPoints; ptoff++)
{
    std::vector<std::pair<int, fpreal>> nearpointVector; // neighbor vector in form of "(idx, dist)"
    auto pos = source->getPos3(ptoff);
    for (auto j = 0; j < targetNumPoints; j++)
    {
        fpreal dist = pos.distance(targetPosVector[j]);
        std::pair<int, fpreal> neighbor {j, dist};
        nearpointVector.push_back(neighbor);
    }
    std::sort(nearpointVector.begin(), nearpointVector.end(), [](const std::pair<int, fpreal> &left,
                                                                 const std::pair<int, fpreal> &right)
                                                                { return left.second < right.second; });
    std::vector<int> neighborVector;
    for (auto i : nearpointVector)
    {
        neighborVector.push_back(i.first);
    }
    // trying to imitate Python's next() function
    // uniqueNeighborList[]
    // uneighbor = next(i for i in neighborVector if i not in uniqueNeighborVector)
    // uniqueNeighborVector = set(uniqueNeighborList.append(uneighbor))
    for (auto i : neighborVector)
    {     
        if (std::find(uniqueNeighborVector.begin(), uniqueNeighborVector.end(), i) == uniqueNeighborVector.end())
        {
            int uneighbor = i; // later on binds to the geometry attribute
            uniqueNeighborVector.push_back(i);
            break;
        }
    }
}

其中

  • sourcetarget详细信息几何数据
  • distance是计算两个向量之间距离的函数
  • getPos3是获得3-float vector点位置的函数
  • fpreal aka 64-bit float
  • UT_Vector33-float vector
  • sourceNumPointstargetNumPointssourcetarget几何形状。

如评论中提到的,二次复杂性是在尝试以数百万点计算此点时的衰落。即使您优化了代码,如果方法不更改,则二次复杂性也将保持。

在我看来,这就像R3中的经典NN问题。一种众所周知的方法是使用k-d树,它们允许在O(n log n(构造时间和线性空间内使用O(log n(查询时间。可以通过各种库来寻求实现:nanoflann,kdtree(这些是从快速搜索中,我敢肯定也有包含k-d树的精心库。(

简短回顾:我将使用3-D树并将其构建在您的目标点集中。然后将每个源点(一一(拿到O(log n(时间的3-D树中的每个源点(| source | log | target |(和o(|(目标|(大小。

一个相关的问题。