C++ 在笛卡尔二维空间中的每个象限中查找最近的点

C++ 在笛卡尔二维空间中的每个象限中查找最近的点,c++,boost,r-tree,C++,Boost,R Tree,我在二维笛卡尔空间中有N个点,加载在boost:rtree中。 给定一个不在树中的随机点P(x,y),我需要找到一种有效的方法,为以P为中心并平行于主csy的局部csy生成的四个象限中的每一个找到最近的点 如图所示(上面链接),给定红色点,我需要找到四个紫色点 我尝试过这种天真的方法: 名称空间bg=boost::geometry; typedef bg::model::box; 向量结果; 向量结果p; int xres=10/*这是一个与积分分布松散相关的固定数量*/ int yres=

我在二维笛卡尔空间中有N个点,加载在boost:rtree中。 给定一个不在树中的随机点P(x,y),我需要找到一种有效的方法,为以P为中心并平行于主csy的局部csy生成的四个象限中的每一个找到最近的点

如图所示(上面链接),给定红色点,我需要找到四个紫色点

我尝试过这种天真的方法:


名称空间bg=boost::geometry;
typedef bg::model::box;
向量结果;
向量结果p;
int xres=10/*这是一个与积分分布松散相关的固定数量*/
int yres=10/*至于xres*/
int范围=10;
int maxp=30;
/*
* .. 填满树
*/
框查询_box2(点(纬度,经度),点(纬度范围*yres,经度+范围*xres));
rtree.query(bgi::intersects(query_box2)和&bgi::nearest(p,maxp),std::back_inserter(result_p));
如果(result_p.size()>0)result_.s.推回(result_p[0]);
结果p.clear();
框查询_box1(点(纬度,经度),点(纬度+范围*yres,经度+范围*xres));
rtree.query(bgi::intersects(query_box1)和&bgi::nearest(p,maxp),std::back_inserter(result_p));
如果(result_p.size()>0)result_.s.推回(result_p[0]);
结果p.clear();
框查询_box3(点(纬度,经度),点(纬度+经度*yres,经度范围*xres));
rtree.query(bgi::intersects(query_box3)和&bgi::nearest(p,maxp),std::back_inserter(result_p));
如果(result_p.size()>0)result_.s.推回(result_p[0]);
结果p.clear();
方框查询_方框4(点(纬度,经度),点(纬度范围*yres,经度范围*xres));
rtree.query(bgi::intersects(query_box4)和&bgi::nearest(p,maxp),std::back_inserter(result_p));
如果(result_p.size()>0)result_.s.推回(result_p[0]);
结果p.clear();
如果(结果大小()>3)

cout我会做一个迭代的
最近的
查询

它将生成按距离升序排列的最近点

在所有象限中获得至少1分后,您将继续学习

原则上,这种方法的时间复杂度要低得多,因为它只涉及一个查询

最坏情况下的行为将迭代树中的所有点,例如

  • 如果一个象限不包含任何点,或
  • 当一个象限中的所有点实际上比另一个象限中最近的点更接近时
似乎前者在您的模型(?)中可能不可能,而后者在正态分布下统计上不可能。您必须检查您的域的期望点分布


或者,这总是适用的:测量和比较有效性能

我会做一个迭代的
最近的
查询

它将生成按距离升序排列的最近点

在所有象限中获得至少1分后,您将继续学习

原则上,这种方法的时间复杂度要低得多,因为它只涉及一个查询

最坏情况下的行为将迭代树中的所有点,例如

  • 如果一个象限不包含任何点,或
  • 当一个象限中的所有点实际上比另一个象限中最近的点更接近时
似乎前者在您的模型(?)中可能不可能,而后者在正态分布下统计上不可能。您必须检查您的域的期望点分布


或者,这始终适用:测量和比较有效性能

使用修改后的距离函数。更准确地说,使用四个

其主要思想是使用距离,以便

d(v1,v2) = infinity if v2.x < v1.x
d(v1,v2) = infinity if v2.y < v1.y
d(v1,v2) = (v1.x-v2.x)²+(v1.y-v2.y)² otherwise
d(v1,v2)=如果v2.x
如果搜索具有此距离的最近点,则该点必须位于右上象限

在搜索树时,您需要将此逻辑扩展到minDist


这样做的好处是,当找到一个点时,它可以停止搜索象限。与“轴”重叠的页面可以展开两次。

使用修改后的距离函数。更准确地说,使用四个

其主要思想是使用距离,以便

d(v1,v2) = infinity if v2.x < v1.x
d(v1,v2) = infinity if v2.y < v1.y
d(v1,v2) = (v1.x-v2.x)²+(v1.y-v2.y)² otherwise
d(v1,v2)=如果v2.x
如果搜索具有此距离的最近点,则该点必须位于右上象限

在搜索树时,您需要将此逻辑扩展到minDist


这样做的好处是,当找到一个点时,它可以停止搜索象限。与“轴”重叠的页面可以展开两次。

box::min_corner
的x值和y值不应该小于box::max_corner的值吗?这一点很好。我去查一下。谢谢。@Albjenow很管用,tnx很管用。希望找到一种比我的“幼稚”代码更有效的方法。
box::min\u corner
的x和y值不应该比
box::max\u corner
的x和y值小吗?很好。我去查一下。谢谢。@Albjenow很管用,tnx很管用。希望找到一个比我的“天真”代码更有效的方法。谢谢@sehe。我最终得到了你建议的解决方案。在表演上没有大的差别。促使我做出这一选择的唯一原因是,这些点的分布很奇怪,而且这个解决方案对非均匀分布的容忍度很高。仍然在寻找更强壮的东西。谢谢@sehe。我最终得到了你建议的解决方案。在表演上没有大的差别。促使我做出这一选择的唯一原因是,这些点的分布很奇怪,而且这个解决方案对非均匀分布的容忍度很高。仍然期待着更强大的东西。