我在平面上散布的非空 Set 点,它们由坐标给出。 问题是快速回复此类查询:
从你的集合中给出我最接近点A(x,y)
的点
我当前的解决方案伪代码
query( given_point )
{
nearest_point = any point from Set
for each point in Set
if dist(point, query_point) < dist(nearest_point, given_point)
nearest_point = point
return nearest_point
}
但是这个算法很慢,复杂度为O(N)
。
问题是,是否存在任何数据结构或具有预先计算的棘手算法,这将大大降低时间复杂度?我至少需要O(log N)
更新
距离我的意思是欧几里德距离
答案 0 :(得分:4)
您可以使用kd-tree获取 O(日志N)时间。这就像二元搜索树,除了它首先在x维度上分割点,然后是y维度,然后再分割x维度,依此类推。
如果你的点是均匀分布的,你可以通过将点分成均匀大小的方框然后搜索查询点落在其中的方框来实现 O(1)查找邻近的盒子。
很难从Voronoi图中获得有效的解决方案,因为这需要您解决查询查询点落入哪个Voronoi单元的问题。大多数情况下,这涉及构建R * -tree来查询Voronoi单元格的边界框(在 O(log N)时间内),然后执行多边形点检查( O(p)中的点数多边形的周长。
答案 1 :(得分:1)
您可以在子章节中划分网格:
根据点数和网格大小,您可以选择有用的分区。让我们假设一个1000x1000像素的屏幕,填充随机点,均匀分布在表面上。
您可以将屏幕划分为10x10个部分并制作地图(roughX,roughY) - &gt;(列表((x,y),...)。对于某个点,您可以查找相同的所有点细胞和 - 由于该点可能更接近相邻细胞的点而不是相同细胞中的极点,周围的细胞甚至可能距离2个细胞。这会将搜索范围缩小到16个细胞。
如果在同一单元格/图层中找不到某个点,请将搜索范围扩展到下一层。
如果碰巧在下一个图层中找到下一个邻居,则必须将搜索范围扩展到每个图层的附加图层。如果点数太多,请选择更精细的网格。如果点数很少,请选择更大的网格。请注意,连接到红线的两个绿色圆圈与红色圆圈的距离相同,但一个在第0层(相同的单元格),而另一个在第2层(下一个单元格的下一个)。
答案 2 :(得分:0)
如果没有预处理,你肯定需要花费O(N),因为你必须在返回最接近之前查看每个点。
您可以在此Nearest neighbor search查看如何解决此问题。