Well-separated pair decomposition
In computational geometry, a well-separated pair decomposition (WSPD) of a set of points , is a sequence of pairs of sets , such that each pair is well-separated, and for each two distinct points , there exists precisely one pair which separates the two.
The graph induced by a well-separated pair decomposition can serve as a k-spanner of the complete Euclidean graph, and is useful in approximating solutions to several problems pertaining to this.{{cite web | url=http://people.scs.carleton.ca/~michiel/aa-handbook.pdf | title=The well-separated pair decomposition and its applications | date=16 August 2005 | accessdate=26 March 2014 | author=Smid, Michiel}}
Definition
File:Visual representation of well-separated pair.svg
Let be two disjoint sets of points in , denote the axis-aligned minimum bounding box for the points in , and denote the separation factor.
We consider and to be well-separated, if for each of and there exists a d-ball of radius containing it, such that the two spheres have a minimum distance of at least .{{cite journal | title=A Decomposition of Multidimensional Point Sets with Applications to k-Nearest-Neighbors and n-Body Potential Fields |author1=Callahan, P. B. |author2=Kosaraju, S. R. |name-list-style=amp | journal=Journal of the ACM |date=January 1995 | volume=42 | issue=1 | pages=67–90 | doi=10.1145/200836.200853| doi-access=free }}
We consider a sequence of well-separated pairs of subsets of , to be a well-separated pair decomposition (WSPD) of if for any two distinct points , there exists precisely one , , such that either
Construction
= Split tree =
By way of constructing a fair split tree, it is possible to construct a WSPD of size in time.
The general principle of the split tree of a point set {{math|S}} is that each node {{math|u}} of the tree represents a set of points {{math|Su}} and that the bounding box {{math|R(Su)}} of {{math|Su}} is split along its longest side in two equal parts which form the two children of {{math|u}} and their point set. It is done recursively until there is only one point in the set.
Let {{math|Lmax(R(X))}} denote the size of the longest interval of the bounding hyperrectangle of point set {{math|X}} and let {{math|Li(R(X))}} denote the size of the i-th dimension of the bounding hyperrectangle of point set {{math|X}}. We give pseudocode for the Split tree computation below.
{{math|SplitTree(S)}}
Let {{math|u}} be the node for {{math|S}}
if {{math|{{!}}S{{!}} {{=}} 1}}
{{math|R(u) :{{=}} R(S)}} // {{math|R(S)}} is a hyperrectangle which each side has a length of zero.
Store in {{math|u}} the only point in S.
else
Compute {{math|R(S)}}
Let the i-th dimension be the one where {{math|Lmax(R(S)) {{=}} Li(R(S))}}
Split {{math|R(S)}} along the i-th dimension in two same-size hyperrectangles and take the points contained in these hyperrectangles to form the two sets {{math|Sv}} and {{math|Sw}}.
{{math|v :{{=}} SplitTree(Sv)}}
{{math|w :{{=}} SplitTree(Sw)}}
Store {{math|v}} and {{math|w}} as, respectively, the left and right children of {{math|u}}.
{{math|R(u) :{{=}} R(S)}}
return {{math|u}}
This algorithm runs in time.
We give a more efficient algorithm that runs in time below. The goal is to loop over the list in only operations per step of the recursion but only call the recursion on at most half the points each time.
Let {{math|Sij}} be the i-th coordinate of the j-th point in {{math|S}} such that {{math|Si}} is sorted according to the i-th coordinate and {{math|p(Sij)}} be the point. Also, let {{math|h(R(S))}} be the hyperplane that splits the longest side of {{math|R(S)}} in two. Here is the algorithm in pseudo-code:
{{math|SplitTree(S, u)}}
if {{math|{{!}}S{{!}} {{=}} 1}}
{{math|R(u) :{{=}} R(S)}} // {{math|R(S)}} is a hyperrectangle which each side has a length of zero.
Store in {{math|u}} the only point in {{math|S}}.
else
{{math|size :{{=}} {{!}}S{{!}}}}
repeat
Compute {{math|R(S)}}
{{math|R(u) :{{=}} R(S)}}
{{math|j : {{=}} 1}}
{{math|k : {{=}} {{!}}S{{!}}}}
Let the i-th dimension be the one where {{math|Lmax(R(S)) {{=}} Li(R(S))}}
{{math|Sv : {{=}} ∅}}
{{math|Sw : {{=}} ∅}}
while {{math|Sij+1 < h(R(S))}} and {{math|Sik-1 > h(R(S))}}
{{math|size :{{=}} size - 1}}
{{math|Sv : {{=}} Sv ∪ {p(S_i^j)}}}
{{math|Sw : {{=}} Sw ∪ {p(S_i^k)}}}
{{math|j :{{=}} j + 1}}
{{math|k :{{=}} k - 1}}
Let {{math|v}} and {{math|w}} be respectively, the left and right children of {{math|u}}.
if {{math|Sij+1 > h(R(S))}}
{{math|Sw :{{=}} S \ Sv}}
{{math|u :{{=}} w}}
{{math|S :{{=}} Sw}}
{{math|SplitTree(Sv,v)}}
else if {{math|Sik-1 < h(R(S))}}
{{math|Sv :{{=}} S \ Sw}}
{{math|u :{{=}} v}}
{{math|S :{{=}} Sv}}
{{math|SplitTree(Sw,w)}}
until {{math|size ≤ {{frac|n|2}}}}
{{math|SplitTree(S,u)}}
To be able to maintain the sorted lists for each node, linked lists are used. Cross-pointers are kept for each list to the others to be able to retrieve a point in constant time. In the algorithm above, in each iteration of the loop, a call to the recursion is done. In reality, to be able to reconstruct the list without the overhead of resorting the points, it is necessary to rebuild the sorted lists once all points have been assigned to their nodes. To do the rebuilding, walk along each list for each dimension, add each point to the corresponding list of its nodes, and add cross-pointers in the original list to be able to add the cross-pointers for the new lists. Finally, call the recursion on each node and his set.
= WSPD computation =
File:Visual representation of a well-separated pair computed with the bounding boxes.svg
The WSPD can be extracted from such a split tree by calling the recursive {{math|FindPairs(v,w)}} function on the children of every node in the split tree. Let {{math|ul}} / {{math|ur}} denote the children of the node {{math|u}}. We give pseudocode for the {{math|FindWSPD(T, s)}} function below.
FindWSPD(T, s)
for each node u that is not a leaf in the split tree T do
FindPairs(ul, ur)
We give pseudocode for the {{math|FindPairs(v, w)}} function below.
FindPairs(v, w)
if {{math|Sv}} and {{math|Sw}} are well-separated with respect to {{math|s}}
report {{math|pair(Sv, Sw)}}
else
if( {{math|Lmax(R(v)) ≤ Lmax(R(w))}} )
Recursively call {{math|FindPairs(v, wl)}} and {{math|FindPairs(v, wr)}}
else
Recursively call {{math|FindPairs(vl, w)}} and {{math|FindPairs(vr, w)}}
Combining the {{math|s}}-well-separated pairs from all the calls of {{math|FindPairs(v,w)}} gives the WSPD for separation {{math|s}}.
{{collapse top|title=Proof of correctness of the algorithm}}
It is clear that the pairs returned by the algorithm are well-separated because of the return condition of the function {{math|FindPairs}}.
Now, we have to prove that for any distinct points and in , there is a unique pair so that (i) and or (ii) and . Assume without loss of generality that (i) holds.
Let be the lowest common ancestor of and in the split tree and let and be the children of . Because of the last assumption, is in the subtree of and in the subtree of . A call to {{math|FindPairs(v,w)}} is necessarily done in {{math|FindWSPD}}. Because, each time there is a recursion, the recursion tree creates two branches that contain all the points of the current recursion call, there will be a sequence of call to {{math|FindPairs}} leading to having in and in .
Because is the lowest common ancestor of and , calling {{math|FindPairs}} on the children of a higher node would result of and not being in a pair and calling {{math|FindPairs}} on the children in one of the nodes of one of the subtrees of would result by or not being in any pair. Thus, the pair is the unique one separating and .
{{collapse bottom}}
Each time the recursion tree split in two, there is one more pair added to the decomposition. So, the algorithm run-time is in the number of pairs in the final decomposition.
Callahan and Kosaraju proved that this algorithm finds a Well-separated pair decomposition (WSPD) of size .
Properties
Lemma 1: Let be a well-separated pair with respect to . Let and . Then, .
Proof: Because and are in the same set, we have that where is the radius of the enclosing circle of and . Because and are in two well-separated sets, we have that . We obtain that:
& \frac
pp' |
pq |
\Leftrightarrow & \\
& \frac
pp' |
pq |
\Leftrightarrow & \\
& |pp'| \leq \frac{2}{s}|pq| \\
\end{align}
Lemma 2: Let be a well-separated pair with respect to . Let and . Then, .
Proof: By the triangle inequality, we have:
From Lemma 1, we obtain:
|p'q'| & \leq (2/s)|pq| + |pq| + (2/s)|pq| \\
& = (1+4/s)|pq|
\end{align}
Applications
The well-separated pair decomposition has application in solving a number of problems. WSPD can be used to:
- Solve the closest pair problem in time.
- Solve the k-closest pairs problem in time.
- Solve the k-closest pair problem in time.{{cite journal|last1=Bespamyatnikh|first1=Sergei|last2=Segal|first2=Michael |title=Fast Algorithms for Approximating Distances.|journal=Algorithmica |volume=33 |issue=2 |pages=263–269|date=2002|doi=10.1007/s00453-001-0114-7|s2cid=9758120 }}
- Solve the all-nearest neighbors problem in time.
- Provide a -approximation of the diameter of a point set in time.
- Directly induce a t-spanner of a point set.
- Provide a t-approximation of the Euclidean minimum spanning tree in d dimensions in time.
- Provide a -approximation of the Euclidean minimum spanning tree in d dimensions in time.{{cite journal|last1=Arya|first1=Sunil|last2=Mount|first2=David M.|title=A fast and simple algorithm for computing approximate euclidean minimum spanning trees|journal=Proceedings of the Twenty-Seventh Annual ACM-SIAM Symposium on Discrete Algorithms|date=2016|pages=1220–1233 |doi=10.1137/1.9781611974331.ch85 |isbn=978-1-61197-433-1 }}
References
{{reflist}}