cgal/SearchStructures/doc_tex/SearchStructures/rangesegmentuser.tex

539 lines
21 KiB
TeX

% +------------------------------------------------------------------------+
% | CGAL User Manual: rangesegmentuser.tex
% +------------------------------------------------------------------------+
% | Range and Segment Tree User Manual
% |
% | 28.03.2000 Gabriele Neyer
% | Start writing the user manual
% |
\RCSdef{\hdsRev}{$Revision$}
\RCSdefDate{\hdsDate}{$Date$}
% +------------------------------------------------------------------------+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%5
%\def\ccTagRmEigenClassName{\ccFalse}
%\def\ccLongParamLayout{\ccTrue}
%
%\ccSetThreeColumns{CGAL_Oriented_side}{}{\hspace*{10cm}}
%\ccThreeToTwo
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%% Range_tree %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%\ccSetThreeColumns{CGAL_Oriented_side}{}{\hspace*{10cm}}
%\ccThreeToTwo
%
%\ccChapterSubTitle{\rangetreeRevision, \rangetreeDate}
%
%\chapter{Search Structures} \label{Trees}
\section{Range and Segment Trees}
\label{User:s-rangesegment}
%\section{Introduction}
This section presents $d$-dimensional range and segment trees.
A one-dimensional range tree is a binary search tree on
{\bf{one-dimensional point data}}.
Here we call all one-dimensional data types having a strict ordering
(like integer and double) {\em point data}.
{\bf{$d$-dimensional point data}} are $d$-tuples of one-dimensional
point data.
A one-dimensional segment tree is a binary search tree as well, but with
{\bf{one-dimensional interval data}} as input data.
One-dimensional interval data is a pair (i.e., 2-tuple) $(a,b)$, where $a$
and $b$ are one-dimensional point data of the same type and $a< b$.
The pair $(a,b)$ represents a half open interval $[a,b)$.
Analogously, a $d$-dimensional interval is represented by a $d$-tuple of
one-dimensional intervals.
The {\bf{input data type}} for a $d$-dimensional tree is a container
class consisting of a $d$-dimensional point data type, interval data type
or a mixture of both, and optionally a {\bf{value type}}, which
can be used to store arbitrary data.
E.g., the $d$--dimensional bounding box of a $d$--dimensional polygon
may define the interval data of a $d$--dimensional segment tree and
the polygon itself can be stored as its value.
An {\bf{input data item}} is an instance of an input data type.
The range and segment tree classes are fully generic in the sense that they
can be used to define {\bf{multilayer trees}}.
A multilayer tree of dimension (number of layers) $d$ is a simple tree in
the $d$-th layer, whereas the $k$-th layer, $1\leq k\leq d-1$, of the tree
defines a tree where each (inner) vertex contains a multilayer tree of
dimension $d-k+1$.
The $k-1$-dimensional tree which is nested in the $k$-dimensional tree
($T$) is called the {\em sublayer tree} (of $T$).
For example, a $d$-dim tree can be a range tree on the first layer,
constructed with respect to the first dimension of $d$-dimensional data
items.
On all the data items in each subtree, a $(d-1)$-dimensional tree is built,
either a range or a segment tree, with respect to the second dimension of
the data items.
And so on.
%E.g., for each inner vertex of a range tree, a sublayer tree is created
%according to all data items of the subtree of that vertex.
%For each vertex of a segment tree an instance (tree) is created according
%to all data items of that vertex.
%E.g., one can define a segment tree for which each vertex contains a
%range tree.
\begin{ccTexOnly}
Figures~\ref{User:fig:range.eps}, \ref{User:fig:d-range.eps} and
\ref{User:fig:d-segment.eps} illustrate the meaning of a sublayer tree
graphically.
\end{ccTexOnly}
\begin{ccHtmlOnly}Figures
<A HREF="Chapter_spez.html#fig:d-segment.eps">here</A> explain the meaning
of a sublayer tree graphically.
\end{ccHtmlOnly}
After creation of the tree, further insertions or deletions of data items
are disallowed.
The tree class does neither depend on the type of data nor on the concrete
physical representation of the data items.
E.g., let a multilayer tree be a segment tree for which each vertex
defines a range tree.
We can choose the data items to consist of intervals of type \ccStyle{double}
and the point data of type \ccStyle{integer}.
As value type we can choose \ccStyle{string}.
For this generality we have to
define what the tree of each dimension looks like and how the
input data is organized.
For dimension $k$, $1\le k\le 4$, \cgal\/ provides ready-to-use
range and segment trees that can store k-dimensional keys
(intervals resp.).
Examples illustrating the use of these classes are given in
Section~\ref{User:RangeSegment:User:Range}
and~\ref{User:RangeSegment:User:Segment}.
The description of the functionality of these classes as well as
the definition of higher dimensional trees and mixed multilayer
trees is given in the reference manual.
We now give a short definition of the version of
the range tree and segment tree implemented here. The
presentation closely follows~\cite{bkos-cgaa-97}.
\subsection{Definition of a Range Tree}
A one-dimensional range tree is a binary search tree on one-dimensional
point data.
The point data of the tree is stored in the leaves.
Each inner vertex stores the highest entry of its left subtree.
The version of a range tree implemented here is static, which means that
after construction of the tree, no elements be inserted or deleted.
A $d$-dimensional range tree is a binary leaf search tree according to the
first dimension of the $d$-dimensional point data, where each vertex contains
a $(d-1)$-dimensional search tree of the points in the subtree (sublayer tree)
with respect to the second dimension.
See~\cite{bkos-cgaa-97} and~\cite{s-dasds-90} for more detailed information.
A $d$-dimensional range tree can be used to determine all
$d$-dimensional points that lie inside a given $d$-dimensional
interval (\ccStyle{window\_query}).
\begin{ccTexOnly}
Figure~\ref{User:fig:range.eps} shows a two-dimensional range tree,
Figure~\ref{User:fig:d-range.eps} a $d$-dimensional one.
\end{ccTexOnly}
\begin{ccHtmlOnly}
The pictures below show a two-dimensional and a <MATH>d</MATH>-dimensional
range tree.
\end{ccHtmlOnly}
\begin{ccTexOnly}
\begin{figure}[htbp]
\begin{minipage}{7cm}
\begin{center}
\includegraphics[width=7cm,clip]{SearchStructures/range2}
\end{center}
\caption{\label{User:fig:range.eps}A two-dimensional range tree. The
tree is a binary search tree on the first dimension. Each
sublayer tree of a vertex $v$ is a binary search tree on the second
dimension. The data items in a sublayer tree of $v$ are
all data items of the subtree of $v$.}
\end{minipage}
\hspace*{1em}
\begin{minipage}{7cm}
\begin{center}
\includegraphics[width=7cm,clip]{SearchStructures/d-range}
\end{center}
\caption{\label{User:fig:d-range.eps}A d-dimensional range tree. For
each layer of the tree, one
sublayer tree is illustrated.}
\vspace{2\baselineskip}
%
\end{minipage}
\end{figure}
\end{ccTexOnly}
\begin{ccHtmlOnly}
<!2><TABLE BORDER=0 CELLSPACING=2 CELLPADDING=0 WIDTH=650>
<TR><TD ALIGN=LEFT VALIGN=TOP WIDTH=50% NOWRAP COLSPAN=2>
<img border=0 src="./range2.gif" alt="A two-dimensional range tree">
</TD>
<TD ALIGN=LEFT VALIGN=TOP WIDTH=50%><img border=0 src="./d-range.gif"
alt="A
d-dimensional range tree">
</TD></TR></TABLE>
<!2><TABLE BORDER=0 CELLSPACING=2 CELLPADDING=0 WIDTH=650>
<TR><TD ALIGN=LEFT VALIGN=TOP WIDTH=45% COLSPAN=2>
A two-dimensional range tree. The
tree is a binary search tree on the first dimension. Each
sublayer tree of a vertex <MATH>v</MATH> is a binary search tree on the
second
dimension. The data items in a sublayer tree of <MATH>v</MATH> are
all data items of the subtree of <MATH>v</MATH>
</TD><TD ALIGN=LEFT VALIGN=TOP WIDTH=50%>
A d-dimensional range tree. For
each layer of the tree, one
sublayer tree is illustrated.
</TD></TR>
</TABLE><!2>
\end{ccHtmlOnly}
%The tree can be built in ${\cal O}(n\log^{d-1} n)$ time and
%needs ${\cal O}(n\log^{d-1} n)$ space. The $d$-dimensional points that lie in the
%$d$-dimensional query interval can be reported in ${\cal O}(\log^dn+k)$ time,
%where $n$ is the total number of points and $k$ is the number of
%reported points.
The tree can be built in $O(n\log^{d-1} n)$ time and
needs $O(n\log^{d-1} n)$ space. The $d$-dimensional points that lie in the
$d$-dimensional query interval can be reported in $O(\log^dn+k)$ time,
where $n$ is the total number of points and $k$ is the number of
reported points.
\subsection{Definition of a Segment Tree}
%\definition
A segment tree is a static binary search tree for a given set of
coordinates. The set of coordinates is defined by the endpoints
of the input data intervals. Any two adjacent coordinates
build an elementary interval. Every leaf corresponds to an
elementary interval.
Inner vertices
correspond to the union of the subtree intervals of the vertex.
Each vertex or leaf $v$ contains a sublayer type (or a
list, if it is one-dimensional) that will contain all intervals $I$, such that
$I$ contains the interval of vertex $v$ but not the interval
of the parent vertex of $v$.
A $d$-dimensional segment tree can be used to solve the following problems:
\begin{itemize}
\item Determine all $d$-dimensional intervals that contain a
$d$-dimensional point. This query type is called ``inverse
range query''.
\item Determine all $d$-dimensional intervals that enclose a
given $d$-dimensional interval
(\ccStyle{enclosing\_query}).
\item Determine all $d$-dimensional intervals that partially overlap or are
contained in a given $d$-dimensional interval (\ccStyle{window\_query}).
\end{itemize}
\begin{ccTexOnly}
In Figure~\ref{User:fig:segment2.eps} an example of a one-dimensional segment tree
is
given. Figure~\ref{User:fig:d-segment.eps} shows a two-dimensional
segment tree.
\end{ccTexOnly}
\begin{ccHtmlOnly}
An example of a one-dimensional segment tree and an example
of a two-dimensional
segment tree is shown below.
\end{ccHtmlOnly}
\begin{ccTexOnly}
\begin{figure}[htbp]
\centering
\begin{minipage}{11cm}
\begin{center}
\includegraphics[width=8cm,clip]{SearchStructures/segment2}
\end{center}
\caption{\label{User:fig:segment2.eps}A one-dimensional segment
tree. The segments and the corresponding elementary intervals
are shown below the tree. The arcs from the nodes point to
their subsets.}
\vspace{2\baselineskip}
\end{minipage}
\hspace*{1em}
\begin{minipage}{11cm}
\begin{center}
\includegraphics[width=8cm,clip]{SearchStructures/d-segment}
\end{center}
\caption{\label{User:fig:d-segment.eps}A two-dimensional segment
tree. The first layer of the tree is built according to the
elementary intervals of the first dimension. Each
sublayer tree of a vertex $v$ is a segment tree according to
the second dimension of all data items of $v$.}
\end{minipage}
\end{figure}
\end{ccTexOnly}
\begin{ccHtmlOnly}
<!2><TABLE BORDER=0 CELLSPACING=2 CELLPADDING=0 WIDTH=650>
<TR><TD ALIGN=LEFT VALIGN=TOP WIDTH=50% NOWRAP COLSPAN=2>
<img border=0 src="./segment2.gif" alt="A one-dimensional segment
tree">
</TD>
<TD ALIGN=LEFT VALIGN=TOP WIDTH=50%><img border=0
src="./d-segment.gif" alt="A
d-dimensional segment tree">
</TD></TR></TABLE>
<!2><TABLE BORDER=0 CELLSPACING=2 CELLPADDING=0 WIDTH=650>
<TR><TD ALIGN=LEFT VALIGN=TOP WIDTH=50% COLSPAN=2>
A one-dimensional segment
tree. The segments and the corresponding elementary intervals
are shown below the tree. The arcs from the nodes point to
their subsets.
</TD><TD ALIGN=LEFT VALIGN=TOP WIDTH=45%>
A two-dimensional segment
tree. The first layer of the tree is built according to the
elementary intervals of the first dimension. Each
sublayer tree of a vertex <MATH>v</MATH> is a segment tree according to
the second dimension of all data items of <MATH>v</MATH>.
</TD></TR>
</TABLE><!2>
\end{ccHtmlOnly}
%The tree can be built in ${\cal O}(n\log^{d} n)$ time and
%needs ${\cal O}(n\log^{d} n)$ space.
%The processing time for inverse range
%queries in an $d$-dimensional segment tree is ${\cal O}(\log^d n
%+k)$ time, where $n$ is the total number of intervals and $k$ is
%the number of reported intervals.
The tree can be built in $O(n\log^{d} n)$ time and
needs $O(n\log^{d} n)$ space.
The processing time for inverse range
queries in an $d$-dimensional segment tree is $O(\log^d n
+k)$ time, where $n$ is the total number of intervals and $k$ is
the number of reported intervals.
One possible application of a two-dimensional segment tree is the
following. Given a set of convex polygons in two-dimensional
space (CGAL::Polygon\_2), we want to determine all polygons
that intersect a given rectangular query window. Therefore, we define a
two-dimensional segment tree, where the two-dimensional interval of
a data item corresponds to the bounding box of a polygon and the
value type corresponds to the polygon itself. The segment tree is created
with a sequence of all data items, and a window query is
performed. The polygons of the resulting data items are finally
tested independently for intersections.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\section{Examples of Range Trees}
\label{User:RangeSegment:User:Range}
\subsection{Range Tree on Map-like Data}
%\ccExample
The following example program uses the predefined \ccc{
Range_tree_2} data structure together with the predefined traits
class \ccc{Range_tree_map_traits_2} which has two template
arguments specifying the
type of the point data in each dimension
(\ccc{CGAL::Cartesian<double>}) and the value type of the
2-dimensional point data (\ccc{char}). Therefore the \ccc{
Range_tree_2} is defined on 2-dimensional point data
(\ccc{CGAL::Point_2<Cartesian<double> >}) each of which is
associated with a character.
Then, a few data items are created and put into a list. After
that the tree is constructed according to that list, a window
query is performed, and the query elements are given out.
\begin{cprog}
#include <CGAL/Cartesian.h>
#include <CGAL/Point_2.h>
#include <CGAL/Range_segment_tree_traits.h>
#include <CGAL/Range_tree_k.h>
typedef CGAL::Cartesian<double> Representation;
typedef CGAL::Range_tree_map_traits_2<Representation, char> Traits;
typedef CGAL::Range_tree_2<Traits> Range_tree_2_type;
int main()
{
typedef Traits::Key Key;
typedef Traits::Interval Interval;
std::vector<Key> InputList, OutputList;
InputList.push_back(Key(CGAL::Point_2<Representation>(8,5.1), 'a'));
InputList.push_back(Key(CGAL::Point_2<Representation>(1,1.1), 'b'));
InputList.push_back(Key(CGAL::Point_2<Representation>(3,2.1), 'c'));
Range_tree_2_type Range_tree_2(InputList.begin(),InputList.end());
Interval win(Interval(CGAL::Point_2<Rep>(4,8.1),CGAL::Point_2<Rep>(5,8.2)));
std::cout << "\n Window Query:\n ";
Range_tree_2.window_query(win, std::back_inserter(OutputList));
std::vector<Key>::iterator current=OutputList.begin();
while(current!=OutputList.end()){
std::cout << (*current).first.x() << "," << (*current).first.y()
<< ":" << (*current++).second << std::endl;
}
}
\end{cprog}
\subsection{Range Tree on Set-like Data}
This example illustrates the use of the range tree on
2-dimensional point data (no value is associated to a data item).
After the definition of the tree, some input data items are
created and the tree is constructed according to the input data
items.
After that, a window query is performed and the query elements
are given to standard out.
\begin{cprog}
#include <CGAL/Cartesian.h>
#include <CGAL/Point_2.h>
#include <CGAL/Range_segment_tree_traits.h>
#include <CGAL/Range_tree_k.h>
typedef CGAL::Cartesian<double> Representation;
typedef CGAL::Range_segment_tree_set_traits_2<Representation> Traits;
typedef CGAL::Range_tree_2<Traits> Range_tree_2_type;
int main()
{
typedef Traits::Key Key;
typedef Traits::Interval Interval;
std::vector<Key> InputList, OutputList;
std::vector<Key>::iterator first, last, current;
InputList.push_back(Key(8,5.1));
InputList.push_back(Key(1,1.1));
InputList.push_back(Key(3,2.1));
Range_tree_2_type Range_tree_2(InputList.begin(),InputList.end());
Interval win=Interval(Key(4,8.1),Key(5,8.2));
std::cout << std::endl << "Window Query: lower left point: (4.0,5.0),";
std::cout << "upper right point: (8.1,8.2)" << std::endl;
Range_tree_2.window_query(win, std::back_inserter(OutputList));
current=OutputList.begin();
while(current!=OutputList.end()){
std::cout << (*current).x()<< "-" << (*current).y() << std::endl;
current++;
}
}
\end{cprog}
\section{Examples of Segment Trees}
\label{User:RangeSegment:User:Segment}
\subsection{Segment Tree on Map-like Data}
The following example program uses the predefined \ccc{
Segment_tree_2} data structure together with the predefined traits
class \ccc{Segment_tree_map_traits_2} which has two template arguments
specifying the
type of the point data in each dimension
(\ccc{CGAL::Cartesian<double>}) and the value type of the
2-dimensional point data (\ccc{char}). Therefore the \ccc{
Segment_tree_2} is defined on 2-dimensional point data
(\ccc{CGAL::Point_2<Cartesian<double> >}) each of which is
associated with a character.
Then, a few data items are created and put into a list. After
that the tree is constructed according to that list, a window
query is performed, and the query elements are given out.
\begin{cprog}
#include <CGAL/Cartesian.h>
#include <CGAL/Point_2.h>
#include <CGAL/Segment_tree_k.h>
#include <CGAL/Range_segment_tree_traits.h>
typedef CGAL::Cartesian<double> Representation;
typedef CGAL::Segment_tree_map_traits_2<Representation, char> Traits;
typedef CGAL::Segment_tree_2<Traits > Segment_tree_2_type;
int main()
{
typedef Traits::Interval Interval;
typedef Traits::Pure_interval Pure_interval;
typedef Traits::Key Key;
std::list<Interval> InputList, OutputList1, OutputList2;
InputList.push_back(Interval(Pure_interval(Key(1,5), Key(2,7)),'a'));
InputList.push_back(Interval(Pure_interval(Key(2,7), Key(3,8)),'b'));
InputList.push_back(Interval(Pure_interval(Key(6,9), Key(9,13)),'c'));
InputList.push_back(Interval(Pure_interval(Key(1,3), Key(3,9)),'d'));
Segment_tree_2_type Segment_tree_2(InputList.begin(),InputList.end());
Interval a=Interval(Pure_interval(Key(3,6), Key(7,12)),'e');
Segment_tree_2.window_query(a,std::back_inserter(OutputList1));
std::list<Interval>::iterator j = OutputList1.begin();
std::cout << "\n window_query (3,6),(7,12)\n";
while(j!=OutputList1.end()){
std::cout << (*j).first.first.x() << "-" << (*j).first.second.x() << " "
<< (*j).first.first.y() << "-" << (*j).first.second.y() << std::endl;
j++;
}
Interval b=Interval(Pure_interval(Key(6,10),Key(7,11)), 'f');
Segment_tree_2.enclosing_query(b,std::back_inserter(OutputList2));
j = OutputList2.begin();
std::cout << "\n enclosing_query (6,10),(7,11)\n";
while(j!=OutputList2.end()){
std::cout << (*j).first.first.x() << "-" << (*j).first.second.x() << " "
<< (*j).first.first.y() << "-" << (*j).first.second.y() << std::endl;
j++;
}
return 0;
}
\end{cprog}
\subsection{Segment Tree on Set-like Data}
This example illustrates the use of the predefined segment tree
on 3-dimensional interval data (with no value associated). After
the definition of the traits type and tree type, some intervals
are constructed and the tree is build according to the
intervals. Then, a window query is performed and the query
elements are given out.
\begin{cprog}
#include <CGAL/Cartesian.h>
#include <CGAL/Point_3.h>
#include <CGAL/Segment_tree_k.h>
#include <CGAL/Range_segment_tree_traits.h>
typedef CGAL::Cartesian<int> Representation;
typedef CGAL::Range_segment_tree_set_traits_3<Representation> Traits;
typedef CGAL::Segment_tree_3<Traits > Segment_tree_3_type;
int main()
{
typedef Traits::Interval Interval;
typedef Traits::Key Key;
std::list<Interval> InputList, OutputList;
InputList.push_back(Interval(Key(1,5,7), Key(2,7,9)));
InputList.push_back(Interval(Key(2,7,6), Key(3,8,9)));
InputList.push_back(Interval(Key(6,9,5), Key(9,13,8)));
InputList.push_back(Interval(Key(1,3,4), Key(3,9,8)));
Segment_tree_3_type Segment_tree_3(InputList.begin(),InputList.end());
Interval a(Key(3,6,5), Key(7,12,8));
Segment_tree_3.window_query(a,std::back_inserter(OutputList));
std::list<Interval>::iterator j = OutputList1.begin();
std::cout << "\n window_query (3,6,5),(7,12,8) \n";
while(j!=OutputList.end()){
std::cout << (*j).first.x() << "," << (*j).first.y() << ",";
std::cout << (*j).first.z() <<", " << (*j).second.x() << ",";
std::cout << (*j).second.y() << "," << (*j).second.z() << std::endl;
j++;
}
}
\end{cprog}