Lecture 3: More Convex Hull Algorithms

Reading: Today's material is not covered in the 4M's book. 
It is covered in O'Rourke's book on Computational Geometry.

Convex Hull by Divide and Conquer: Recall the convex hull problem,
which we introduced last time. We presented Graham's scan, which is an
O(n log n) time algorithm for this problem.  Next we will consider
another O(n log n) algorithm, which is based on the divide and conquer
design technique. It can be viewed as a generalization of the
MergeSort sorting algorithm (see Cormen, Leiserson, and Rivest). Here
is an outline of the algorithm. It begins by sorting the points by
their x coordinate, in O(n log n) time.

Divide and Conquer Convex Hull 

Hull(S) : 

(1) If |S| <= 3, then compute the convex hull by brute force in O(1)
time and return.

(2) Otherwise, partition the point set S into two sets A and B, where
A consists of half the points with the lowest x coordinates and B
consists of half of the points with the highest x coordinates.

(3) Recursively compute HA = Hull(A) and HB = Hull(B).

(4) Merge the two hulls into a common convex hull, H, by computing the
upper and lower tangents for HA and HB and discarding all the points
lying between these two tangents.

(See the figure below.)



Figure 10: Computing the lower tangent.

The asymptotic running time of the algorithm can be expressed by a
recurrence. Given an input of size n, consider the time needed to
perform all the parts of the procedure, ignoring the recursive
calls. This includes the time to partition the point set, compute the
two tangents, and return the final result. Clearly the first and third
of these steps can be performed in O(n) time, assuming a linked list
representation of the hull vertices. Below we will show that the
tangents can be computed in O(n) time. Thus, ignoring constant
factors, we can describe the running time by the following recurrence.

T(n) =

1 if n <= 3
n + 2T (n/2) otherwise.

This is the same recurrence that arises in Mergesort. It is easy to
show that it solves to T (n) 2 O(n log n) (see CLR).

All that remains is showing how to compute the two tangents.  One
thing that simplifies the process of computing the tangents is that
the two point sets A and B are separated from each other by a vertical
line (assuming no duplicate x coordinates).  Let's concentrate on the
lower tangent, since the upper tangent is symmetric. The algorithm
operates by a simple ``walking'' procedure. We initialize a to be the
rightmost point of HA and b is the leftmost point of HB . (These can
be found in linear time.) Lower tangency is a condition that can be
tested locally by an orientation test of the two vertices and
neighboring vertices on the hull. (This is a simple exercise.) We
iterate the following two loops, which march a and b down, until they
reach the points lower tangency.

Finding the Lower Tangent
LowerTangent(HA ; HB ) :
(1) Let a be the rightmost point of HA .
(2) Let b be the leftmost point of HB .
(3) While ab is not a lower tangent for HA and HB do
(a) While ab is not a lower tangent to HA do a = a - 1 (move a clockwise).
(b) While ab is not a lower tangent to HB do b = b + 1 (move b counterclockwise).
(4) Return ab.

Proving the correctness of this procedure is a little tricky, but not
too bad. Check O'Rourke's book out for a careful proof. The important
thing is that each vertex on each hull can be visited at most once by
the search, and hence its running time is O(m), where 

m = |HA| + |HB| <= |A| + |B|.

This is exactly what we needed to get the overall O(n log n) running time.

QuickHull: If the divide and conquer algorithm can be viewed as a sort
of generalization of Merge Sort, one might ask whether there is
corresponding generalization of other sorting algorithm for computing
convex hulls. In particular, the next algorithm that we will consider
can be thought of as a generalization of the QuickSort sorting
procedure. The resulting algorithm is called QuickHull.  Like
QuickSort, this algorithm runs in O(n log n) time for favorable inputs
but can take as long as O(n^2) time for unfavorable inputs. However,
unlike QuickSort, there is no obvious way to convert it into a
randomized algorithm with O(n log n) expected running
time. Nonetheless, QuickHull tends to perform very well in practice.


The intuition is that in many applications most of the points lie in
the interior of the hull. For example, if the points are uniformly
distributed in a unit square, then it can be shown that the expected
number of points on the convex hull is O(log n).  The idea behind
QuickHull is to discard points that are not on the hull as quickly as
pos sible. QuickHull begins by computing the points with the maximum
and minimum, x and y coordinates. Clearly these points must be on the
hull. Horizontal and vertical lines passing through these points are
support lines for the hull, and so define a bounding rectangle, within
which the hull is contained. Furthermore, the convex quadrilateral
defined by these four points lies within the convex hull, so the
points lying within this quadrilateral can be eliminated from further
consideration. All of this can be done in O(n) time.



Figure 11: QuickHull's initial quadrilateral.  Points inside are discarded.


To continue the algorithm, we classify the remaining points into the
four corner triangles that remain. In general, as this algorithm
executes, we will have an inner convex polygon, and associated with
each edge we have a set of points that lie ``outside'' of that
edge. (More formally, these points are witnesses to the fact that this
edge is not on the convex hull, because they lie outside the half
plane defined by this edge.) When this set of points is empty, the
edge is a final edge of the hull. Consider some edge ab. Assume that
the points that lie ``outside'' of this hull edge have been placed in
a bucket that is associated with ab. Our job is to find a point c
among these points that lies on the hull, discard the points in the
triangle abc, and split the remaining points into two subsets, those
that lie outside ac and those than lie outside of cb. We can classify
each point by making two orientation tests.



Figure 12: QuickHull elimination procedure.

How should c be selected? There are a number of possible selection
criteria that one might think of. The method that is most often
proposed is to let c be the point that maximizes the perpendicular
distance from the line ab. (For example, another possible choice might
be the point that maximizes the angle cba or cab. It turns out that
these can be are very poor choices because they tend to produce
imbalanced partitions of the remaining points.) We replace the edge ab
with the two edges ac and cb, and classify the points as lying in one
of three groups: those that lie in the triangle abc, which are
discarded, those that lie outside of ac, and those that lie outside of
cb. We put these points in buckets for these edges, and recurse. (We
claim that it is not hard to classify each point p, by computing the
orientations of the triples acp and cbp.)

The running time of Quickhull, as with QuickSort, depends on how
evenly the points are split at each stage. Let T (n) denote the
running time on the algorithm assuming that n points remain outside of
some edge. In O(n) time we can select a candidate splitting point c
and classify the points in the bucket in O(n) time. Let n1 and n2
denote the number of remaining points, where n1 + n2 <= n. Then the
running time is given by the recurrence:

T(n) =

1					  if n = 1
T(n1) + T (n2) where n1 + n2 <= n.        otherwise

In order to solve this recurrence, it would be necessary to determine
the ``reasonable'' values for n1 and n2 . If we assume that the
points are ``evenly'' distributed, in the sense that 
max(n1 ; n2 ) <= a * n for some constant a < 1, 

then by applying the same analysis as that used in QuickSort (see
Cormen, Leiserson, Rivest) the running time will solve to O(n log n),
where the constant factor depends on a. On the other hand, if the
splits are not balanced, then the running time can easily increase to
O(n^2).  

Does QuickHull outperform Graham's scan? This depends to a great
extent on the distribution of the point set. There are variations of
QuickHull that are designed for specific point distributions
(e.g. points uniformly distributed in a square) and their authors
claim that they manage to eliminate almost all of the points in a
matter of only a few iterations.


Gift Wrapping and Jarvis's March: The next algorithm that we will
consider is a variant on an O(n^2 ) sorting algorithm called
SelectionSort. For sorting, this algorithm repeatedly finds the next
element to add to the sorted order from the remaining items. The
corresponding convex hull algorithm is called Jarvis's march. which
builds the hull in O(nh) time by a process called ``gift
wrapping''. The algorithm operates by considering any one point that
is on the hull, say, the lowest point. We then find the ``next'' edge
on the hull in counterclockwise order.  Assuming that p(k) and p(k-1)
were the last two points added to the hull, compute the point q that
maximizes the angle  [ p(k-1) p(k) q ]. Thus, we can find the point q in
O(n) time. After repeating this h times, we will return back to the
starting point and we are done. Thus, the overall running time is
O(nh). Note that if h is o(log n) (asymptotically smaller than log n)
then this is a better method than Graham's algorithm.


One technical detail is how we to find an edge from which to
start. One easy way to do this is to let p(1) be the point with the
lowest y coordinate, and let p(0) be the point (Inf, 0), which is
infinitely far to the right. The point p(0) is only used for computing
the initial angles, after which it is discarded.  



An Output Sensitive Algorithm for Convex Hulls

Reading: Today's material is not covered in our text. Chan's
algorithm can be found in T.  Chan, ``Optimal output sensitive convex
hull algorithms in two and three dimensions'', Discrete and
Computational Geometry, 16, 1996, 361--368.



Figure 13: Jarvis's march.

The Omega(n log h) lower bound on convex hulls is given in the paper,
D. G. Kirkpatrick and R. Seidel, ``The ultimate planar convex hull
algorithm,'' SIAM J. Comput., 15, 1986, 287--299.  The O(logn) bound
on the complexity of the convex hull is folklore.

Output Sensitive Convex Hull Algorithms: It turns out that in the
worst case, convex hulls cannot be computed faster than in O( n log n)
time. One way to see this intuitively is to observe that the convex
hull itself is sorted along its boundary, and hence if every point
lies on the hull, then computing the hull requires sorting of some
form. Yao proved the much harder result that determining which points
are on the hull (without sorting them along the boundary) still
requiresO( n log n) time. However both of these results rely on the
fact that all (or at least a constant fraction) of the points lie on
the convex hull. This is often not true in practice.


The QuickHull and Jarvis's March algorithms that we saw last time
suggest the question of how fast can convex hulls be computed if we
allow the running time to be described in terms of both the input size
n and the output size h. Many geometric algorithms have the property
that the output size can be a widely varying function of the input
size, and worst case output size may not be a good indicator of what
happens typically. An algorithm which attempts to be more efficient
for small output sizes is called an output sensitive algorithm, and
running time is described as a asymptotic function of both input size
and output size.


Chan's Algorithm: Given than any convex hull algorithm must take at
least O(n) time, and given that ``log n'' factor arises from the fact
that you need to sort the at most n points on the hull, if you were
told that there are only h points on the hull, then a reasonable
target running time is O(n log h). (Below we will see that this is
optimal.) Kirkpatrick and Seidel discovered a relatively complicated
O(n log h) time algorithm, based on a clever pruning method in 1986.
The problem was considered closed until around 10 years later when
Timothy Chan came up with a much simpler algorithm with the same
running time. One of the interesting aspects of Chan's algorithm is
that it involves combining two slower algorithms (Graham's scan and
Jarvis's March) together to form an algorithm that is faster than
either one.

The problem with Graham's scan is that it sorts all the points, and
hence is doomed to having an Omega( n log n) running time, irrespective of
the size of the hull. On the other hand, Jarvis's march can perform
better if you have few vertices on the hull, but it takes O( n) time
for each hull vertex.

Chan's idea was to partition the points into groups of equal
size. There are m points in each group, and so the number of groups is
r = dn=me. For each group we compute its hull using Graham's scan,
which takes O(m log m) time per group, for a total time of O(rm log m)
= O(n log m). Next, we run Jarvis's march on the groups. Here we take
advantage of the fact that you can compute the tangent between a point
and a convex m gon in O(logm) time.  (We will leave this as an
exercise.) So, as before there are h steps of Jarvis's march, but
because we are applying it to r convex hulls, each step takes only 
O(r log m) time, for a total of O(hr log m) = ((hn/m) log m)
time. Combining these two parts, we get a total of

O((n + (hn/m)) log m) time. 

Observe that if we set m = h then the total running time will be O(n
log h), as desired.  There is only one small problem here. We do not
know what h is in advance, and therefore we do not know what m should
be when running the algorithm. We will see how to remedy this
later. For now, let's imagine that someone tells us the value of
m. The following algorithm works correctly as long as m – h. If we
are wrong, it returns a special error status.


Chan's Partial Convex Hull Algorithm (Given m)

PartialHull(P; m) :
(1) Let r = ceil(n/m). Partition P into disjoint subsets P(1),P(2),... P(r),
		       each of size at most m.
(2) For i = 1 to r do:

(a) Compute Hull(P(i)) using Graham's scan and store the vertices in
    an ordered array.
(3) Let p0 = (-Inf; 0) and let p1 be the bottommost point of P .
(4) For k = 1 to m do:
(a) For i = 1 to r do:
        Compute point q in P(i) that maximizes the angle
                  p(k-1)  p(k)  q
(b) Let p(k+1) be the point q in q(1),q(2),...q(r) than maximizes the angle
                  p(k-1)  p(k)  q
(c) If p(k+1) = p(1) then return {p(1), p(2), ... p(k)}.
(5) Return ``m was too small, try again.''


Figure 14: Chan's Convex Hull Algorithm.

We assume that we store the convex hulls from step (2a) in an ordered
array so that the step inside the for loop of step (4a) can be solved
in O(logm) time using binary search. Otherwise, the analysis follows
directly from the comments made earlier.


The only question remaining is how do we know what value to give to m?
The last trick, is a common trick used in algorithms to guess the
value of a parameter that affects the running time. We could try m =
1, 2, 3, ... , until we luck out and have m >= h, but this would take
too long. Binary search would be a more efficient option, but if we
guess to large a value for m (e.g. m = n=2) then we are immediately
stuck with O(n log n) time, and this is too slow.  Instead, the trick
is to start with a small value of m and increase it rapidly. Since the
dependence on m is only in the log term, as long as our value of m is
within a polynomial of h, that is, m = h^c for some constant c, then
the running time will still be O(n log h). So, our approach will be to
guess successively larger values of m, each time squaring the previous
value, until the algorithm returns a successful result. This trick is
often called doubling search (because the unknown parameter is
successively doubled), but in this case we will be squaring rather
than doubling.


Chan's Complete Convex Hull Algorithm

Hull(P ) :
(1) For t = 1; 2; : : : do:
(a) Let m = min(2^(2^t),n)
(b) Invoke PartialHull(P, m), returning the result in L.
(c) If L != ``try again'' then return L.


Note that 2^2^t has the effect of squaring the previous value of
m. How long does this take? The t-th iteration takes 

O(n log 2^2^t ) = O(n* 2^t ) time.

We know that it will stop as soon as 2^2^t >= h, that is if 
t = ceil(lg lg n). (We will use lg to denote logarithm base 2.)
So, the total running time (ignoring the constant factors) is:

Sum(t = 1 ... lg lg h) n*2^t =
n * Sum(t = 1 ... lg lg h) 2^t <= 
n * 2^(1+lg lg h) = 
2n lg h = 
O(n log h).

which is just what we want.

Lower Bound: Next we will show that Chan's result is asymptotically
optimal in the sense that any algorithm for computing the convex hull
of n points with h points on the hull requires O( n log h) time. The
proof is a generalization of the proof that sorting a set of n numbers
requires O( n log n) comparisons.  If you recall the proof that
sorting takes at least O( n log n) comparisons, it is based on the
idea that any sorting algorithm can be described in terms of a
decision tree. Each comparison has at most 3 outcomes (!, =, or
?). Each such comparison corresponds to an internal node in the
tree. The execution of an algorithm can be viewed as a traversal along
a path in the resulting 3-ary tree. The height of the tree is a lower
bound on the worst case running time of the algorithm. There are at
least n! different possible inputs, each of which must be reordered
differently, and so you have a 3-ary tree with at least n leaves. Any
such tree must have
 O(log(base 3) n!) height. Using Stirling's approximation which says 
(n! is approximately sqrt(2*PI*n)*(n/e)^n), 
this solves to O( n log n) height.

We will give an O( n log h) lower bound for the convex hull
problem. In fact, we will give an O( n log h) lower bound on the
following simpler decision problem, whose output is either yes or no.

Convex Hull Size Verification Problem (CHSV): 

Given a point set P and integer h, does the convex hull of P have h
distinct vertices?

Clearly if this takes O( n log h) time, then computing the hull must
take at least as long. As with sorting, we will assume that the
computation is described in the form of a decision tree.  Assuming
that the algorithm uses only comparisons is too restrictive for
computing convex hulls, so we will generalize the model of computation
to allow for more complex functions. We assume that we are allowed to
compute any algebraic function of the point coordinates, and test the
sign of the resulting function. The result is called a algebraic
decision tree.  The input to the CHSV problem is a sequence of 2n = N
real numbers. We can think of these numbers as forming a vector 
(z(1), z(2), ... z(N) = vector(z) in R^N, (a vector z in N-dimensional space),
 which we will call a configuration.


Each node of the decision tree is associated with a multivariate
algebraic formula of degree at most d. for example:

f(z) = z(1)*z(4) -  2z(3)z(6) + 5(z(6)^2).

would be an algebraic function of degree 2. The node branches in one
of three ways, depending on whether the result is negative, zero, or
positive. (Computing orientations and dot products both fall into this
category.) Each leaf of the resulting tree corresponds to a possible
answer that the algorithm might give.

For each input vector z to the CHSV problem, the answer is either
``yes'' or ``no''. The set of all ``yes'' points is just a subset of
points Y in R^N , that is a region in this space. Given an arbitrary
input z the purpose of the decision tree is to tell us whether this
point is in Y or not. This is done by walking down the tree,
evaluating the functions on z and following the appropriate branches
until arriving at a leaf, which is either labeled ``yes'' (meaning z
in Y) or ``no''. An abstract example (not for the convex hull problem)
of a region of configuration space and a possible algebraic decision
tree (of degree 1) is shown in the following figure. (We have
simplified it by making it a binary tree.) In this case the input is
just a pair of real numbers.


Figure 15: The geometric interpretation of an algebraic decision tree.

We say that two points u, v in  Y are in the same connected component
of Y if there is a path in R^N from u to v such that all the points
along the path are in the set Y . (There are two connected components
in the figure.) We will make use of the following fundamental result
on algebraic decision trees, due to Ben Or. Intuitively, it states
that if your set has M connected components, then there must be at
least M leaves in any decision tree for the set, and the tree must
have height at least the logarithm of the number of leaves.


Theorem: Let Y in R^N be any set and let T be any d th order algebraic
decision tree that determines membership in W . If W has M disjoint
connected components, then T must have height at least Omega(log M - N).


We will begin our proof with a simpler problem.  

Multiset Size Verification Problem (MSV):

Given a multiset of n real numbers and an integer k, confirm that the
multiset has exactly k distinct elements.

Lemma: The MSV problem requires O( n log k) steps in the worst case in
the d th order algebraic decision tree

Proof: In terms of points in R^n , the set of points for which the
answer is ``yes'' is 

Y = {(z(1), z(2),...  z(n) ) in R^n such that |{z(1), z(2), ... ,
z(n)}| = k}

It suffices to show that there are at least k!*k^(n-k) different
connected components in this set, because by Ben Or's result it would
follow that the time to test membership in Y would be
 Omega(log(k!*k^( n-k )) - n) =  
 Omega(k log k + (n - k) log k - n) = 
 Omega( n log k)

Consider the all the tuples (z(1) ... z(n) ) with z(1), ..., z(k) set
to the distinct integers from 1 to k, and z(k+1) ... z(n) each set to
an arbitrary integer in the same range. Clearly there are k! ways to
select the first k elements and k^(n-k) ways to select the
remaining elements.  Each such tuple has exactly k distinct items, but
it is not hard to see that if we attempt to continuously modify one of
these tuples to equal another one, we must change the number of
distinct elements, implying that each of these tuples is in a
different connected component of Y .

To finish the lower bound proof, we argue that any instance of MSV can
be reduced to the convex hull size verification problem (CHSV). Thus
any lower bound for MSV problem applies to CHSV as well.

Theorem: The CHSV problem requires O( n log h) time to solve.  Proof:
Let Z = (z(1), ..., z(n) ) and k be an instance of the MSV problem. We
create a point set p(1), ...,p(n) in the plane where p(i) = (z(i),
z(i)^), and set h = k.

(Observe that the points lie on a parabola, so that all the points are
on the convex hull.) Now, if the multiset Z has exactly k distinct
elements, then there are exactly h = k points in the point set (since
the others are all duplicates of these) and so there are exactly h
points on the hull.  Conversely, if there are h points on the convex
hull, then there were exactly h = k distinct numbers in the multiset
to begin with in Z.

Thus, we cannot solve CHSV any faster than O( n log h) time, for
otherwise we could solve MSV in the same time.

The proof is rather unsatisfying, because it relies on the fact that
there are many duplicate points. You might wonder, does the lower
bound still hold if there are no duplicates? Kirkpatric and Seidel
actually prove a stronger (but harder) result that the O( n log h)
lower bound holds even you assume that the points are distinct.


Expected Number of Hull Points 

For different distributions a different number of points is ex pected
to lie on the hull. One of the simplest cases to analyze is that of
points uniformly distributed in a unit square.

Theorem: If n points are sampled from a uniform distribution in a unit
square, then the expected number of points on the convex hull is O(log
n).  Proof: First, we will break the hull into four parts, the upper
left, upper right, lower left, and lower right hulls. This is done by
breaking the hull at its leftmost, rightmost, topmost and bottommost
points. We will show that each has O(log n) points. By symmetry, we
may consider one, say the upper right hull.

Rather than bounding the number of points on the hull, we will bound a
larger quantity.  A point p(i) = (x(i), y(i) ) is said to be dominated
by another point p(j) if x(j) >= x(i) and y(j) >= y(i) .  The maxima
of a point set P are the points that are not dominated by any other
point in P . Observe that each vertex of the convex hull is a maxima
(but not vice versa), and therefore there are at least as many maxima
points as convex hull vertices. So it suffices to prove that the
expected number of maxima is O(log n).  

Suppose that the points are sorted in decreasing order of x
coordinate. We will assume that all points have distinct coordinates
to simplify things. Clearly p(i) is in the maxima if and only if p(i)
has the largest y coordinate among the subset {p(1), p(2),
... p(i)}. What is the probability that this is true? The y
coordinates of these points are independent and identically
distributed. Therefore each of these points is equally likely to be
the maximum, and so the probability that p(i) has the largest y
coordinate is just 1/i.  Thus, each point p(i) is a maxima with
probability 1/i.


Figure 16: Upper right hull and maxima.

The expected number of maxima is the sum of these expectations: 

sum(i = 1..n) 1/i

The sum is the harmonic series and it is well known that it is very
close to ln n (see Cormen, Leiserson, and Rivest). From the comments
made earlier it follows that the expected number of points on all the
hulls is at most four times this quantity, which is O(log n).

This course is modeled on the Computational Geometry Course taught by Dave Mount, at the University of Maryland. These notes are modifications of his Lecture Notes, which are copyrighted as follows: Copyright, David M. Mount, 2000, Dept. of Computer Science, University of Maryland, College Park, MD, 20742. These lecture notes were prepared by David Mount for the course CMSC 754, Computational Geometry, at the University of Maryland, College Park. Permission to use, copy, modify, and distribute these notes for educational purposes and without fee is hereby granted, provided that this copyright notice appear in all copies.