C++ 使用rtree(或任何其他算法)计算向量中组的频率

C++ 使用rtree(或任何其他算法)计算向量中组的频率,c++,frequency,boost-geometry,spatial-index,r-tree,C++,Frequency,Boost Geometry,Spatial Index,R Tree,给定向量中的以下点集 {(100150)、(101152)、(102151)、(105155)、(50,50)、(51,55)、(55,55)、(150250)、(190260)} 我需要识别相邻点及其计数。假设可接受的距离已设置为5。现在我需要以下输出: 5个单位内的点(100150)的频率为4。 点(50,50)在5个单位内的频率为3 5个单位内点(150250)的频率为1 点(190260)在5个单位内的频率为1 我尝试了一个RTree解决方案来解决这个问题,但无法确定排除所有相邻点作为候

给定向量中的以下点集 {(100150)、(101152)、(102151)、(105155)、(50,50)、(51,55)、(55,55)、(150250)、(190260)}

我需要识别相邻点及其计数。假设可接受的距离已设置为5。现在我需要以下输出: 5个单位内的点(100150)的频率为4。 点(50,50)在5个单位内的频率为3 5个单位内点(150250)的频率为1 点(190260)在5个单位内的频率为1

我尝试了一个RTree解决方案来解决这个问题,但无法确定排除所有相邻点作为候选点的逻辑。意味着一旦我确定了(100150)的四个邻居,我就不想确定这些邻居的邻居。我想转到下一个值。以下是假设: 1.效率是人们最关心的问题 2.向量未排序 3.向量可能包含数千个点。 我用C++来增强rTrE的实现。请指导我如何实现解决方案

下面是计算向量中唯一点的邻域数的代码。我需要指导,一旦确定某个点的邻居,就排除他们

       include set, iostream, boost/geometry.hpp,       boost/geometry/geometries/point.hpp, boost/geometry/index/rtree.hpp

      using namespace std;
      namespace bg = boost::geometry;
      namespace bgi = boost::geometry::index;

     typedef bg::model::point<int, 2, bg::cs::cartesian> point;
     typedef std::pair<point, unsigned> value;

    struct ltstr
    {
       bool operator()(const point &p1, const point &p2) const
    {
        return (p1.get < 0 >() < p2.get < 0 >() || p1.get < 1 >() < p2.get < 1 >());
}
   };


       void main()
      {
vector<point> candidatePoints{ point(457, 184), point(457, 184), point(457, 184), point(457, 184), point(457, 184),
    point(456, 184), point(456, 184), point(456, 184), point(456, 184), point(456, 184),
    point(456, 184), point(457, 184), point(457, 184), point(457, 184), point(458, 184), point(459, 185) };

bgi::rtree< value, bgi::quadratic<16> > rtree;

set<point, ltstr> uniqueCandidatePoints;

for (int i = 0; i < candidatePoints.size(); ++i)
{
    int x = candidatePoints[i].get < 0 >();
    int y = candidatePoints[i].get < 1 >();
    uniqueCandidatePoints.insert(point(x, y));
    rtree.insert(make_pair(candidatePoints[i], i));
}

for (auto it = uniqueCandidatePoints.begin(); it != uniqueCandidatePoints.end(); ++it)
{
    std::vector<value> returnedValues;
    point currentItem = *it;
    rtree.query(bgi::satisfies([&](value const& v) {return bg::distance(v.first, currentItem) < 5; }),
        std::back_inserter(returnedValues));

    cout << "Current Item: " << currentItem.get < 0 >() << "," << currentItem.get < 1 >() << "Count: " << returnedValues.size() << endl;
} 

getchar();
  }
包括set、iostream、boost/geometry.hpp、boost/geometry/geometry/point.hpp、boost/geometry/index/rtree.hpp
使用名称空间std;
名称空间bg=boost::geometry;
名称空间bgi=boost::geometry::index;
typedef bg::model::point;
typedef std::对值;
结构ltstr
{
布尔运算符()(常数点和p1、常数点和p2)常数
{
返回(p1.get<0>()()| | p1.get<1>()());
}
};
void main()
{
向量候选点{点(457184),点(457184),点(457184),点(457184),点(457184),点(457184),
点(456184),点(456184),点(456184),点(456184),点(456184),点(456184),
点(456184),点(457184),点(457184),点(457184),点(457184),点(458184),点(459185)};
bgi::rtreertree;
设置唯一的候选点数;
对于(int i=0;i();
int y=candidatePoints[i]。获取<1>();
唯一候选点。插入(点(x,y));
rtree.insert(配对(候选点[i],i));
}
for(自动it=uniqueCandidatePoints.begin();it!=uniqueCandidatePoints.end();+it)
{
std::向量返回值;
point currentItem=*它;
查询(bgi::满足([&](value const&v){return bg::distance(v.first,currentItem)<5;}),
std::back_插入器(返回值));

cout只是一个数据结构,而不是一个算法,对我来说,它看起来相当复杂。除非你真的需要处理mirco效率,否则我会使用简单的标准算法和点向量。这是我的第一个猜测。

R-树是最有用的空间索引数据结构之一,但对于或者特定的领域和问题。也就是说,这不是避免说教的理由(毕竟所问的可能是实际问题的简化)

如果你选择使用R-树,你就是在进行区域分解。就像空间填充曲线一样,你可以手头上有一个空间的顺序,但是节点元素保持空间附近(离根越远)

理想的解决方案是以一种形成
radius=5
区域的方式构建R-树,但这需要自定义数据结构和自定义STR或批量加载算法,并且类似于聚类算法

boost::index
可用的情况下,我将尝试详细介绍代码:

强制性包括 执行 对于每个点,我们查询距离最多为5的点

int main()
{
    std::vector<point> cloud {
        point(100, 150), point(101, 152), point(102, 151), 
        point(105, 155), point( 50,  50), point( 51,  55), 
        point( 55,  55), point(150, 250), point(190, 260) 
    }; 

    bgi::rtree<point, bgi::quadratic<16>> rtree(cloud.begin(), cloud.end());

    std::vector<point> hood;
    for (auto &&p : cloud)
    {
        hood.clear(); 
        std::cout << "neighborhood of point " << p << "\n-----------------\n\n";

        rtree.query(bgi::satisfies(distance_pred(p, 5)), std::back_inserter(hood)); 

        // Output the results -----------------------------------------
        if (!hood.empty())
        {
            for (auto &&pt : hood) std::cout << '\t' << pt << std::endl;
        }
        else
        {
            std::cout << "\t... is empty\n"; 
        }

        std::cout << std::endl; 
    }
}
intmain()
{
矢量云{
点(100150),点(101152),点(102151),
第(105,155)点,第(50,50)点,第(51,55)点,
点(55,55),点(150250),点(190260)
}; 
rtree-rtree(cloud.begin(),cloud.end());
病媒罩;
用于(自动和p:cloud)
{
引擎盖。清除();

std::一点也不宽泛,相反它非常具体。我已经准备好了答案,请重新打开以便我可以发布it@NikosAthanasiou--您对问题的编辑确实应该是一个注释。我已经回滚了编辑,但可以在注释中将OP链接到您的答案。@Michael0x2a我对问题的编辑应该是n答案和这个问题不应该被关闭。我过去一直在与这些主题斗争,并且能够理解它是多么令人沮丧。无论如何,这里是,祝你开心,如果主题重新打开,我将感谢通知(链接中的代码有很多要说的)@NikosAthanasiou感谢使用rtree编写的优雅代码。但它并不能完全满足我的要求。一旦确定了邻居,我想在下一步中排除它们。在点{100150}--------------------{101152}{102151}----------的代码邻域的输出中,现在我不想为其计算邻居{101,152}和{102,151}。我想继续检查{105,155}。请指导我如何做到这一点。@Nikosathanasi您的问题中包含了我的代码。我可以看出您的代码更加优雅。您能帮助我找到最终的解决方案吗?因为您是一开始就完全理解我需要的人。在使用count_if.can解决问题的漫长而令人沮丧的尝试之后,我决定使用R-tree。我可以吗我对解决方案做了更多的阐述?这根本不是解决方案。对于那些投票认为我的问题广泛而一般的老兵们,你们想让我把我写的代码贴出来吗
namespace bg  = boost::geometry;
namespace bgi = boost::geometry::index;   
using  point  = bg::model::point < float, 2, bg::cs::cartesian > ;
struct distance_pred
{
    point const& _base; 
    double       _threshold; 

    distance_pred(point const& base, double max_dist)
        : _base(base)
        , _threshold(max_dist)
    {
    }
    bool operator()(point const& p) const
    {
        auto d = boost::geometry::distance(_base, p); 
        return d && d < _threshold; 
    }
};

// just for output
std::ostream& operator<<(std::ostream &os, point const& p)
{
    os << "{ " << p.get<0>() << ", " << p.get<1>() << " }"; 
    return os; 
}
int main()
{
    std::vector<point> cloud {
        point(100, 150), point(101, 152), point(102, 151), 
        point(105, 155), point( 50,  50), point( 51,  55), 
        point( 55,  55), point(150, 250), point(190, 260) 
    }; 

    bgi::rtree<point, bgi::quadratic<16>> rtree(cloud.begin(), cloud.end());

    std::vector<point> hood;
    for (auto &&p : cloud)
    {
        hood.clear(); 
        std::cout << "neighborhood of point " << p << "\n-----------------\n\n";

        rtree.query(bgi::satisfies(distance_pred(p, 5)), std::back_inserter(hood)); 

        // Output the results -----------------------------------------
        if (!hood.empty())
        {
            for (auto &&pt : hood) std::cout << '\t' << pt << std::endl;
        }
        else
        {
            std::cout << "\t... is empty\n"; 
        }

        std::cout << std::endl; 
    }
}
using  pointI  = std::pair<point, std::size_t>; // remember : geometric info first
for (std::size_t i(0), i < cloud.size(); ++i)
{
    if (cloud.end() != std::find(rec.begin(), rec.end(), i))
    { // you'll only be building neighorhoods for points that are not touched
        // queries and recording performed on point2 types  
    }
}