计算几何 W46 More Orthogonal problems
Kd-Trees
Problem set
given a set of points in
store in a data structure s.t. given a query rectangle , we can find the points in efficiently.
idea
- generalize BST to
- every node corresponds to a rectangular region ; the points in the subtree of lie in .
Build Kd-Tree
BuildKDTree()
if then return a leaf node representing .
if is even then
partition into using a vertical line through the point with median x-coordinate
else
partition into using a horizontal line through the point with median y-coordinate
BuildKDTree()
BuildKDTree()
return a tree with root and left subtree and right subtree .
Analysis
running time:
size:
Search in Kd-Tree
SearchKDTree()
if is a leaf then report the point stored at if .
else
if then ReportSubstree()
else if intersects then SearchKDTree()
if then ReportSubstree()
else if intersects then SearchKDTree()
Analysis
query time is proportional to number of regions in intersected by .
rectangles visited by ReportSubtree produce output, so their cost
We bound number of regions intersected by a vertical line:
assume corresponds to a vertical splitting time, in one region of and , this suggests
4 regions after two steps. any vertical or horizontal lines, intersects 2 regions
Theorem
a Kd-Tree uses space, can be built in time, and can report all points in a query rectangle in time.
Windowing Queries
Problem set
given a set of disjoint line segments in the plane.
store in data structure s.t. given a query rectangle , we can find the segments in intersecting efficiently.
The segments that intersect
have an endpoint in
find them using a range query with on the set of end points
intersect the boundary of
**先考虑一种退化的情况:**what if the disjoint lines are orthogonal?
store in a data structure s.t. given a vertical query segment , we can find the segments in interesting efficiently.
Interval Stabbing Queries
问题:一些平行的线段和一条直线相交的查询
given a set of intervals in
store in a data structure s.t. given a query value , we can find the intervals in intersecting efficiently.
we store in a segment tree (aka interval tree)
线段树,太典了
is balanced BST on the end points
the root of the tree stores the intervals that contain .
the left subtree of stores the intervals that lie completely left of .
the right subtree of stores the intervals that lie completely right of .
store these intervals twice:
- sorted on increasing left endpoint
- sorted on decreasing right end point
Pseudo code
Query
if is left of then
report intervals from using the list of left-end points, stop at the first interval right of .
Query
else if is right of then
report intervals from using the list of right-end points, stop at the first interval left of .
Query
Analysis
space usage:
query time: , is numbers of intervals reported
preprocessing time:
Segment stabbing queries
问题:一些平行的线段和一条线段相交的查询
相当于两个维度上的覆盖问题
space usage:
query time: , is numbers of intervals reported
preprocessing time:
Unparalleled stabbing queries
再进一步,如果给出的线段不平行呢?(问题进一步变成:给出一些不平行的线段和一条直线,求和这条直线相交的线段个数)
那么线段树 + 优先搜索树方法就行不通了。
split the problem into elementary intervals in which a vertical line intersects the same segments
storing all segments segments in all elementary intervals uses space.
再将这些 elementary segments 投影到一个方向上,变成平行的。Project the segments onto the x-axis, yielding intervals. we build a different data structure for interval stabbing.
问题又转成了 interval stabbing
Store the elementary intervals as leaves in a balanced BST .
Every node corresponds to an interval , which is the union of the elementary intervals stored in its subtree.
store a canonical subset of intervals s.t. if and only if but .
这里有点 tricky,为了尽量少的节点存下这些 element intervals,尽量往上面的祖先节点存,aka 节点存储的是包含 element intervals 的最大正规集 maximal canonical set。这样复杂度就是 级别的了(对于每根线段,有 个线段树节点存储)
is a segment tree.
query: find all nodes s.t. , and for each such node report all intervals in .
query time: where is the output size.
space: every interval is stored times, at most twice per level. in total.
how do we build ?
build a BST on the elementary intervals, insert the intervals in one by one.
to insert we visit at most 4 nodes per level.
preprocessing time:
把查询的直线换成线段呢?
space
query
preprocessing time
Come back to window queries
the segment that intersect
have an endpoint in
find them using a range query with on the set of end points
( query, space)
intersect the boundary of
find them using a segment tree
( query, space)
Theorem
we can solve windowing queries in time, using space after preprocessing time.
这个 可以优化成 ???