我正在研究Planar Point位置,现在正在考虑使用The Slabs方法。
我读了几篇文章:
我理解持久平衡二叉搜索树背后的概念,但是我们在这个问题中省略它们,我并不真正关心额外的存储空间开销。文章的内容是他们正在讨论如何提高速度,但不解释基本的东西。例如:
如果我错了,请你纠正我:
我们在所有十字路口画一条线。
现在,我们有不同角度的分段分割。
任何与任何线条的交点都被视为顶点。
在二元搜索树中按顺序排序平板(让我们省略部分持久的bst)
- 醇>
不知何故,扇区在各自的BST中排序,即使划分它们的段几乎总是在某个角度。每个节点是否必须带有区域定义?
请参阅此示例图片:
问题:
我如何确定这一点是否位于Node c而不是Node b?是以某种方式通过区域?
我是否需要安排我的节点来包含有关细分的信息?然后,我可以检查查询点是否位于段之上(如果这是我应该如何确定我的扇区)?如果是这样,我会在之后搜索多边形列表,以查看该特定段属于哪个多边形?
也许我需要为每一行存储BST而不是平板?
那么我是否必须查看左边2行的BST和顶点右边的第2行?然后,我可以在每个树中按y坐标对顶点进行排序,并在查询点的正下方返回顶点的y坐标(段的末尾)。完成左右行后,我会做一个比较,看看这些顶点来自的段的名称是否实际匹配。
但是,这不会给我正确答案,因为即使名称匹配,我可能会低于或高于该段(如果我接近它)。此外,这意味着我必须进行3次二进制搜索(1行表示行,1表示左行y坐标,1表示右行),书籍说我只需要进行2次搜索(1表示平板,2表示对于部门)。
有人可以指点我这样做吗?
我可能只是错过了一些基本思想或其他东西。
修改
Here是另一篇很好的文章,它解释了问题的解决方案,但是,我不太明白我将如何实现以下目标:
“考虑任何查询点q∈R2。为了找到包含q的G的面,我们首先使用q的x坐标进行二分搜索,找到包含q的垂直板s。给定s,我们使用q坐标为q的二元搜索来找到其中q所在的Es的边缘。“
如何找到这两条边?它是否像检查点是否位于段下方一样简单?然而,这似乎是一项复杂的检查(而且很昂贵),因为我们沿着树下行,检查其他节点。
答案 0 :(得分:1)
嗯,这是在一年前问到的,所以我猜你不会接受这个答案。不过,这是一个有趣的问题,所以无论如何都要这样......
是的,您可以使用垂直线将平面划分为每个交叉点。重要的结果是,所有接触板的线段都将完全通过,并且这些线段的顺序在整个板上都是相同的。
在每个平板中,您创建这些线段的二叉搜索树,按其在平板中的顺序排序。你打电话的区域"节点"是树的叶子,线段是内部节点。我会打电话给树叶"区域"避免歧义。由于线段的顺序在整个板上是相同的,因此该树中的顺序对于板中的每个x坐标都有效。
确定包含任意点的区域,找到包含该点的平板,然后在BST中进行简单搜索以找到该区域。
假设您正在寻找C点,并且您在slab 2中包含(x2,y2) - (x3,y4)的节点。确定C是高于还是低于此线段,然后在树中获取该分支。
例如,如果C是(cx,cy),那么x = cx处的段的y坐标是:
testy =((cx-x2)/(x3-x2))*(y4-y2)+ y2
如果cy<暴躁,然后采取向上分支,否则采取向下分支。 (假设正Y向下)。
当你到达一片叶子时,那是包含C的区域。你已经完成了。
现在......为每个平板制作一个全新的树需要很大的空间,因为你可以有N ^ 2个交点,因此可以有N ^ 2个平板。在每个平板中存储一个单独的树将占用O(N ^ 3)空间。
然而,使用持久的红黑树,平板实际上可以共享很多节点。使用像Chris Okasaki的红黑树这样简单的纯功能实现,每个交叉点占用O(log N)空间,总共有O(N ^ 2 * log N)空间。
我似乎记得还有一个持续不断变换太空的持续红黑树会给你O(N ^ 2),但我没有参考。
请注意,对于大多数现实生活场景而言,更接近O(N)交叉点,因为线路不会交叉很多,但通过使用持久树来保存空间仍然很好。