Optimization 寻找一个有效的结构来检查哪些圆包含一个点
我有一大组重叠的圆,每个圆在一个特定半径的随机位置Optimization 寻找一个有效的结构来检查哪些圆包含一个点,optimization,f#,computational-geometry,delaunay,Optimization,F#,Computational Geometry,Delaunay,我有一大组重叠的圆,每个圆在一个特定半径的随机位置 type Circle = struct val x: float val y: float val radius: float end 给定一个类型为的新点 type Point = struct val x: float val y: float end 我想知道我的集合中的哪些圆包含新的点。线性搜索很简单。我正在寻找一种结构,可以容纳圆,并返
type Circle =
struct
val x: float
val y: float
val radius: float
end
给定一个类型为的新点
type Point =
struct
val x: float
val y: float
end
我想知道我的集合中的哪些圆包含新的点。线性搜索很简单。我正在寻找一种结构,可以容纳圆,并返回比O(N)更好的圆
理想情况下,该结构应能快速插入新的圆,也能快速移除圆
我想在F#中实现这一点,但任何语言的想法都可以
为您提供信息,我希望实施
但是如果我用简单的方法扫描所有的圆来寻找每一个新的点,这将是一个O(N^2)。如果我们假设圆分布在一个面积
1
的矩形上,并且一个圆的平均面积是a
,那么一个m
级别的四叉树将留给你一个大小1/2^m
的区域。这只剩下
O(Na/2^m)
作为剩余区域中剩余的预期圆圈数
然而,我们已经做了O(log(m))
比较来达到这一点。这使得比较的总数为
O(log(m))+O(N/2^m)
如果log(m)
与N
成比例,则第二项为常数
这表明四叉树可以把事情简化为
O(logn)
四叉树是一种高效的平面搜索结构。可以使用它来保持平面的细分
例如,可以创建具有以下属性的四叉树:
1.四叉树的每个单元都包含圆的索引,并与之重叠。
2.每个单元格包含的圆不超过K个(例如10)//可能会断开
3.树的高度以M为界(通常为O(logn))
您可以通过迭代重叠的单元来构造四叉树,如果单元内的圆数超过K,则将该单元细分为四个(如果不超过最大高度)。对于圆内的单元,也应该考虑一些问题,因为它的细分是毫无意义的
当你们找到圆时,你们应该定位四叉树,然后在重叠的圆中迭代,找到那个些包含点的圆
在稀疏圆分布的情况下,搜索将非常有效
我有一篇学士学位论文,在这篇论文中,我采用了四叉树作为最近的线段位置,预期时间为O(logn),我认为类似的方法也可以在这里使用实际上,你可以搜索外接圆包含新点p的三角形。因此,您的Delaunay三角剖分已经是您所需要的数据结构:首先搜索三角形t,其中包括p(谷歌搜索“Delaunay walk”)。t的外接圆当然包括p。然后从t开始,增长外接圆包括p的三角形的(连通)面积 以一种快速可靠的方式实现它需要大量的工作。除非要创建新库,否则可能需要使用现有库。我的C++方法是FADE2D(1),但还有很多其他的方法,这取决于你的具体需求。p>
[1] 那就来点修改过的四叉树吧。然后你可能会做O(logn)是的,但四叉树是用于不重叠几何对象的点。我不知道如何继续。你至少可以把事情缩小到一个区域上重叠的圆的一些小子集。我在前一段时间致力于解决这个问题,结果证明,如果最大半径与坐标范围相比很小,你(或我)只能打败线性。你能断言关于范围的任何东西吗?我想我可能在寻找这个圆分布将是重叠的圆是delaunay三角剖分的外接圆。这有什么不同吗?@BradGonessurfing为什么不能在delaunay三角测量中定位?我认为在三角剖分中使用三角形,你可以在面的外接圆中找到包含外接圆的面,与你的三角形共享点。@BradGonessurfing我也认为你的情况对答案中的算法来说并不坏。最大细分将在阶数>K的三角剖分顶点处达到。但这没关系,在该顶点附近,除了迭代通过关联圆=)之外,您没有什么更好的方法