![]()
![]()
In 1972, R. L. Graham proposed an efficient algorithm for planar convex hull.
Historically, this is the first publication that showed convex hull
computation in O(n log n) time in the worst case. In 1981, A. C. Yao proved that it is optimal in the worst-case sense. The problem with
Graham’s algorithm is that it has no obvious extension to three dimensions.
The reason is that the Graham’s scan depends on angular sorting, which has no
direct counterpart in three dimensions.
First, select a base point po, normally this is the point
with minimum y-coordinate. We select leftmost point in the set in case of the
tie. Next, sort the points of Q lexicographically by polar angle,
measured in radians. Interior points on the ray cannot be a convex hull points
and remove these points during sort. Sort remaining points in counterclockwise
order with respect to po. Push each point of set Q onto the
stack once and the points that are not of CH(Q) are eventually
popped from the stack.
GRAHAM_SCAN(Q)
- Let po be the point in given set Q with the minimum y-coordinate or leftmost point.
- Let <p1, p2, …, pm> be the remaining points in Q, sorted by polar angle in counterclockwise order with respect to po.
- TOP [S] = 0
- PUSH (po, S)
- PUSH (p1, S)
- PUSH (p2, S)
- for i = 3 to m do
- while {angle between NEXT_TO_TOP[S], TOP[S], and pi makes a nonleft turn} do
- PUSH (S, pi)
- return S
Line 1 requires O(n) time to find po (i.e., point with minimum y-coordinate). Line 2 requires O(n lg n) time, using merge or heap sort to sort polar angles. Lines 3, 4, 5, and 6 require constant time i.e., O(1). We use the aggregate method of amortized analysis to analyze while loop. As in analysis of MULTIPOP, we observe there is at most one ‘pop’ for each ‘push’ operation. In case of GRAHM’S SCAN, atleast three points (po, p1 and pm) are never popped from the stack. So infact, at most m - 2 pop operations are performed. Therefore, the mortised cost of each Iteration of while loop is O(n)/n = O(1). It implies that the overall worst-case for for-loop is O(n). The worst case running time of GRAHAM_SCAN is
T(n) = O(n) + O(n lg n) + O(1) + O(n) = O(n lg n)
where n = |Q|
The correctness of Graham’s scan lies in two situations.
Claim 1 Each point popped from the stack is not a vertex of CH(Q) and lies inside new CH(S).
FIGURE
Proof of Claim 1
Suppose that point pj is popped from the stack
because <pkpjpi makes a nonleft turn.
Since points are ordered in increasing polar angle w.r.t.
po,
there exists a triangle ∆ popipk with
pj either in the interior of the triangle or on the line
segment line(pipk) (geometric property).
Either case, point pj cannot be a vertex of CH(Q).
And this completes the proof of claim 1. □
Claim 2 The points on stack always form the vertices of a convex
polygon.
Proof of Claim 2
The claim holds immediately after line 6, since points po, p1, and p2 form a convex polygon. Now examine how stack changes during the course of an algorithm. Stack changes in two ways. When:
Case in which points are popped
Here we rely on geometric property: If a vertex is removed from a convex polygon, the resulting polygon is convex.
Case in which points are pushedTo analyze this case, we rely on the following geometric property.
FIGURES of Bounded region and unbounded region
If we add point ps in the shaded regions to polygon P then the resulting
polygon is convex.
Back to the case (when points are pushed).
Subclaim
If a point pi is pushed onto the stack, the resulting
points form a convex polygon.
FIGURE
Proof of Subclaim:
By choice of po and p1, pi
lies above pop1. By fact, a left turn occurs at
pj, pi lies below pjpk.
By fact, pi occurs later in the sequence then pj,
the polar angle of popi is greater than polar
angle of popj - pi of lies left
of line(popj).
As a result pi lies in the shaded region. Therefore after
pi has been pushed onto the stack, the points on stack form a
convex polygon. This completes the proof. □
Since each point popped from the stack is not a vertex of CH(Q)
( by claim 1). And the points on stack always form the vertices of a convex
polygon (by claim 2). Therefore Graham’s scan is correct.
Graham's scan starts with 25 random points, and then computes their convex hull.
The algorithm works in three phases:
Thanks Alejo
Hausner for codes.
![]()