You are on page 1of 25

Subject:

Algorithm Design and Analysis

Submitted by:
Md. Ali Azam
CE-13025
2012-2013
2nd Year 2nd Semester

Submitted to:
Mahfuz Reza
Lecturer
Dept. of CSE
MBSTU
CONVEX HULL
Convex hull is a branch of computational geometry problem.
Convex hull is solved by processing data with respect to
geometric manner.

Definition: Let, there are given a set of points which are


denoted with their co-ordinates.
Convex Hull is the polygon (convex hull must be a polygon)
which joints some points so that other points are inside the
polygon or on the edges of the polygon. So, no points are
outside of that polygon. Below example explains the scenario,
Let, there are given these points. Now, we have to find out the
convex polygon.

Here is the convex polygon. We see, all points are inside the
convex polygon (gray colored) or on the edge (light blue
colored).So, this the Convex ploygon where red colored points
are vertices.
No other polygon would be a convex polygon for these points as
there is only one case is possible under the scenario.

Condition to be a convex polygon:


i. All points cannot be colinear.There must be at least
one point which is non-colinear with the others.
(As polygon must have an area grater than zero,this condition is
much intuitive.)
This is not a convex polygon.

ii. No two points can be identical on convex polygon.

Algorithm: There are many algorithms to solve this


problem. They come with different approaches and
complexities.
i. Brute-Force Algorithm
ii. Chan’s Algorithm
iii. Jarvis March
iv. Quick Hull
v. Graham Scan
Among these, Graham Scan has worst, average case complexity
of where Quick Hull has the same for average case.
2
But, Quick Hull has complexity for the worst case.
All of the algorithms can be implemented for n-dimensions.
Though they are extended from 2-dimension.
However, to avoid complications only 2-dimension is
considered throughout the rest of the report and Quick hull
implementation will be explained.
Quick-Hull Algorithm: Quick Hull algorithm is a divide and
conquer problem solving approach.
Quick Hull came from Quick Sort + Convex Hull. It has the same
approach as the Quick Sort (Time complexities are also same).

The solving process can be divided into 5 steps to get better


understanding. Below is the stepwise explanation,

Step-01: Let, these points are given:

As, this is a divide-conquer algorithm, First we have to divide


the problem into smaller part. Our target is to find the vertices
of the convex polygon. If we can find two vertex of the polygon,
the problem can divided into two smaller parts.
To do this, we will first find the leftmost and rightmost point on
the convex as they are surely on convex polygon.
The lowest x-coordinate point is the leftmost and the highest x-
coordinate point is rightmost point. If two or more points have
lowest or highest coordinate choosing anyone will be okay.

A B

Now, we have found our leftmost and rightmost points. We will


add A and B. Thus the points are divided into two sets. The two
sets will be considered separately.

Step-02: So far, we know two sets are generated for points.


But, we don’t know which points are on which set. We will
determine the two sets in this step.
P (any point except A and B)

A B

Here, we need to know whether p is on the left side (the upper


part of AB) or right side (the lower part of AB). To determine
this, there are some approaches.
i. Geometric Approach: we can find the angle sign of p
with AB from geometric equations.
ii. Polar Angle: we can find the polar angle of p with
respect to AB. If angle is positive, p is on the left, otherwise
right.
These two methods are perfect for human. But for
computer they will show complications as both approach may
result in floating point value. Comparing floating point value is
much hectic for computer. Moreover, we lose precision and it is
CPU-expensive. So, to avoid floating-point operations we will
calculate in another way which is perfect for computers. We will
use cross-product approach.
𝐴𝐵 x AP
𝑥1 − 𝑥0 𝑥2 − 𝑥0
P 𝒙𝟏 , 𝒚𝟏 = 𝑦 −𝑦
1 0 𝑦2 − 𝑦0
= 𝑥1 − 𝑥0 𝑦2 − 𝑦0 − 𝑥2 − 𝑥0 𝑦1 − 𝑦0
𝜃

A 𝒙𝟎 , 𝒚𝟎 B 𝒙𝟏 , 𝒚𝟏
𝐴𝐵 x AP
P 𝟒, 𝟏
5−0 4−0
=
0−0 1−0
𝜃
=5
A 𝟎, 𝟎 B 𝟓, 𝟎 When, 𝜃 is anticlockwise or, p is on
the left side 𝐴𝐵 x 𝐴𝑃 is positive.

𝐴𝐵 x AP

A 𝟎, 𝟎 𝜃 5−0 4−0
B 𝟓, 𝟎 =
0−0 −1 − 0
= −5
P 𝟒, −𝟏
When, 𝜃 is clockwise or, p is on the
right side 𝐴𝐵 x 𝐴𝑃 is negative.

So, when x positive, p is on left side.


When x negative, p is on right side.
When x equals zero, p is on the line.

This way we can get the left side points and right side points.
Step-03: We have two sets of points. Left side points and
right side points have the same procedure for further
operations. So, we will consider left side points set.
At first, from left side points set we will find out another
convex hull vertex. To do that, we have to find out the farthest
point from AB as we can surely say the farthest point from AB
will be a vertex on convex hull.

P (any point on left side points


set except A and B)

A B

To find the farthest point we have to find perpendicular


distance from each p to AB line. Now, there is a geometric
equation to find such value but again it will have floating point
value which will be difficult to compare later on. So, we will
develop another equation which will be modified for computer
later.
Let, the perpendicular line = v
P 𝒙𝒑 , 𝒚𝒑
Slope of 𝐴𝐵 = 𝑚1
𝒅 𝑚2 Slope of v = 𝑚2
v
Distance = 𝑑
𝑚1
A 𝒙𝟏 , 𝒚𝟏 B 𝒙𝟐 , 𝒚𝟐 We have to find the value of 𝑑.
We know,
𝑦 𝑦
𝑚1 =
𝑥 𝑥

− 𝑥2 − 𝑥1 𝒚 − 𝒄𝒐𝒐𝒓𝒅𝒊𝒏𝒂𝒕𝒆
𝑚2 =
𝑦2 − 𝑦1 𝒙 − 𝒄𝒐𝒐𝒓𝒅𝒊𝒏𝒂𝒕𝒆

− 2 1 𝒙 − 𝒄𝒐𝒐𝒓𝒅𝒊𝒏𝒂𝒕𝒆
So, v = (− )
2− 1 𝒚 − 𝒄𝒐𝒐𝒓𝒅𝒊𝒏𝒂𝒕𝒆

Now, v =v =v 𝒅 𝜃

P 𝒙𝒑 , 𝒚𝒑

𝒅 v

A 𝒙𝟏 , 𝒚𝟏 B 𝒙𝟐 , 𝒚𝟐

( )
So, = =
| | √

As, we will only compare , we don’t need the exact value of .


So, we can omit the denominator of as it will remain constant
for every p point. So,
( − 1) 2 − 1 − − 1 2 − 1
Step-04: We have so far got the farthest point of left side
points set. Now, the left side points set are divided into three
parts in following way.
P (farthest point from AB)

Left side of AP Left side of PB

A B

Here, we see orange colored vertices are outside of the


polygon. It means, left side points set of AP and left side points
set of PB are outside of the polygons.
In Step-04, we will recursively do from Step-02 to Step-04
for left side points set of PA and left side points of PB. Finally we
will get the vertices when we have only one or no point on each
left side.

Step-05: We now have the convex hull vertices of left side


points set. We will do the same process (Step-02 to Step-04) for
right side points set. Finally we get the full convex hull vertices
set which will be our result.
Space Complexity: Quick Hull Algorithm has same space
complexity as Quick Sort.
Best Case:
Average Case:
Worst Case:

Best Case, Average Case analysis:


𝑛

𝑛 𝑛
2 2

𝑛 𝑛 𝑛 𝑛
4 4 4 4

At first, stack memory will have to store points. The next


levels it reduces to 2, 4, , .
Here, the sequence of denominator is: 1,2,4, ,
This can be written as: 20 , 21 , 22 , 23 , ,2
Clearly, m is the height of the tree.

So, 2 = = 2

Thus, representing in -asymptotic notation we get .


Worst case analysis: In the worst case the tree changes to,

1 𝑛−1

1 𝑛−2

1 𝑛−3

It will go up to − . So, Height of the tree is


The complexity is .

Time Complexity: Quick Hull Algorithm has same time


complexity as Quick Sort.
Best Case:
Average Case:
2
Worst Case:

Best Case, Average Case analysis:


The partition is determined by the line passing through two
distinct extreme points. Finding the extreme points require
time as it has to check all points.
Let, is the time complexity of points.
= 2 2
= 2 2 4 2
= 4 4
= 4 4 2
= 4 2 4 2
= 2
= 3
= 2 16 3
= 16 3
= 16 16 4
= 32 32 5

= 2

= 1 2

= 1 2

= 1 2

= 2 [𝑇 1 = 𝐶;

= 2 𝑎𝑠 𝑤ℎ𝑒𝑛 𝑡ℎ𝑒𝑟𝑒 𝑖𝑠 𝑜𝑛𝑙𝑦 𝑜𝑛𝑒 𝑝𝑜𝑖𝑛𝑡,

= 𝑡ℎ𝑒 𝑟𝑒𝑐𝑢𝑟𝑠𝑖𝑣𝑒 𝑓𝑢𝑛𝑐𝑡𝑖𝑜𝑛 𝑤𝑖𝑙𝑙 𝑛𝑜𝑡

𝑖𝑡𝑒𝑟𝑎𝑡𝑒, 𝑡𝑖𝑚𝑒 𝑐𝑜𝑚𝑝𝑙𝑒𝑥𝑖𝑡𝑦

𝑤𝑖𝑙𝑙 𝑏𝑒 𝑐𝑜𝑛𝑠𝑡𝑎𝑛𝑡 ]
Worst Case analysis:
The partition is determined by the line passing through two
distinct extreme points. Finding the extreme points require
time as it has to check all points.
For, worst case we have to iterate for every given points.
Let, is the time complexity of points.

= 1 −1
= 1 1 −2
= 2 −2 2

= −
= 0
2
=
2
=
Code Implementation:
Here is my C++ code for quick hull implementation:
1 #include<iostream>
2
#include<list>
3
#include<iterator>
4
5
#include<limits>
6
7 using namespace std;
8
9
struct POINT
10
11
{
12 int x;
13 int y;
14
};
15
16
17
18 class QuickHull
19 {
20
public:
21
22
23
list<struct POINT> quickHull(list<struct POINT>
points)
24
25 {
26 list<struct POINT> convexHull;
27 // convexHull list will contain final vertices
28
29 if (points.size() < 3)
30 // if there is two point,no calculation needed.
31
return points;
32
33
34
struct POINT minPoint = {-1,-1}, maxPoint = {-1,-1};
35 // minPoint,maxPoint stores leftmost and rightmost
36 value.
37
int minX = numeric_limits<int>::max();
38
// initialize maximum value for minimum x.
39
40
int maxX = numeric_limits<int>::min();
41 // initialize minimum value for maximum x.
42
43
list<struct POINT>::iterator i;
44 // declare an iterator to iterate through points.
45
list<struct POINT>::iterator dltA;
46
// declare another two for deleting leftmost and
47
48 list<struct POINT>::iterator dltB;
49
//rightmost points from points.
50
51 for(i = points.begin(); i!=points.end(); i++)
52
// iterate from first points to last points.
53
{
54
55
if (i->x < minX)
// find the leftmost point.
56
57 {
58 minX = i->x;
59 minPoint.x = i->x;
60
minPoint.y = i->y;
61
dltA = i;
62
63
}
64 if (i->x > maxX)
65 // find the rightmost point.
66 {
67 maxX = i->x;
68
maxPoint.x = i->x;
69
70
maxPoint.y = i->y;
71 dltB = i;
72 }
73 }
74
75
76 struct POINT A = minPoint;
77
struct POINT B = maxPoint;
78
points.erase(dltA);
79
80
// delete both point from points so that these won't
81 points.erase(dltB);
82 // be computed again when we pass this to hullSet().
83 //cout<<A.x << " "<<A.y << " "<<B.x << "
84 "<<B.y;
85
86
list<struct POINT> leftSet;
87 //declaring two other list to separate leftTurned
88 points
89 list<struct POINT> rightSet;
90
//and rightTurned points.
91
92
93 for ( i = points.begin(); i !=points.end(); i++)
94 {
95 struct POINT p;
96
p.x = i->x;
97
98
p.y = i->y;
99
100 if (pointLocation(A, B, p) == -1)
101 rightSet.push_front(p);
102
else if (pointLocation(A, B, p) == 1)
103
104
leftSet.push_front(p);
105 }
106
107 convexHull.push_back(A);
108 //insert the leftmost point into convexHull
109
convexHull = hullSet(A, B, rightSet, convexHull);
110
// hullSet finds convex from leftside and rightside
111
through two
112
convexHull.push_back(B);
113
//insert the rightmost point into convexHull
114
115
convexHull = hullSet(B, A, leftSet, convexHull);
116 // different call.
117
118
//cout << convexHull.size() << " " <<
119
points.size() << endl;
120
121
122 return convexHull;
123
124 }
125
126
list<struct POINT> hullSet( struct POINT A, struct
127
POINT B, list<struct POINT> Set, list<struct POINT>
128
hull )
129
{
130
131
list<struct POINT>::iterator j;
132 j = Set.begin();
133
134
if (Set.size() == 0)
135
return hull;
136
137
if (Set.size() == 1)
138 {
139 struct POINT p;
140
p.x = j->x;
141
p.y = j->y;
142
143
Set.erase(j);
144 hull.push_back(p);
145 //cout <<hull.size() <<endl;
146
return hull;
147
}
148
149
150 int dist = numeric_limits<int>::min();
151 list<struct POINT>::iterator furthestPoint;
152
for ( j = Set.begin(); j!=Set.end(); j++ )
153
{
154
155
struct POINT p;
156 p.x = j->x;
157
p.y = j->y;
158
159
160
int distanceVal = distance(A, B, p);
161
162 if (distanceVal > dist)
163
{
164
dist = distanceVal;
165
166
furthestPoint = j;
167 }
168 }
169
170
struct POINT P;
171
172
P.x = furthestPoint->x;
173 P.y = furthestPoint->y;
174
175
Set.erase(furthestPoint);
176
hull.push_back(P);
177
178
//cout << P.x << " " << P.y << " " <<
Set.size() << " " << hull.size()<< endl;
179
180
181 // Determine who's to the left of AP
182 list<struct POINT> leftSetAP;
183
184
for ( j = Set.begin(); j!=Set.end(); j++ )
185
186 {
187 struct POINT M;
188 M.x = j->x;
189
M.y = j->y;
190
if (pointLocation(A, P, M) == -1)
191
192 {
193 leftSetAP.push_front(M);
194 }
195
196 }
197
198
// Determine who's to the left of PB
199
200
list<struct POINT> leftSetPB;
201
202 for (j = Set.begin(); j!=Set.end(); j++)
203
{
204
struct POINT M;
205
206
M.x = j->x;
207 M.y = j->y;
208
209
if (pointLocation(P, B, M) == -1)
210
{
211
212
leftSetPB.push_front(M);
213 }
214 }
215
216
//cout << leftSetAP.size() << " " <<
217
leftSetPB.size()<<" "<<hull.size() <<endl;
218
219
220 hull = hullSet(A, P, leftSetAP, hull);
221 hull = hullSet(P, B, leftSetPB, hull);
222
223
//cout << leftSetAP.size() << " " <<
224 leftSetPB.size()<<" "<<hull.size() <<endl;
225
226
227
return hull;
228
229 }
230 int pointLocation(struct POINT A, struct POINT B,
231 struct POINT P)
232
{
233
int cp1 = (B.x - A.x) * (P.y - A.y) - (B.y -
234
A.y) * (P.x - A.x);
235
236
237
if (cp1 > 0)
238
return 1;
239
240
else if (cp1 == 0)
241 return 0;
242 else
243
return -1;
244
}
245
246
247 int distance(struct POINT A, struct POINT B,
248 struct POINT C)
249 {
250 int ABx = B.x - A.x;
251
int ABy = B.y - A.y;
252
int num = ABx * (A.y - C.y) - ABy * (A.x -
253
C.x);
254
255
256 if (num < 0)
257 num = -num;
258
259
return num;
260
261
}
262
263 };
264
265
int main()
266
267
{
268 cout << "Quick Hull Test " << endl;
269
270 //take the total number of points on plane
271
cout << "Enter the number of points:" << endl;
272
int N;
273
274 cin >> N;
275
278
279
280
//coordinates of the points
281
282
cout << "Enter the coordinates of each points :
<x> <y>" << endl;
283
284 struct POINT getPoint;
285 list<struct POINT>points;
286
287
for(int i = 0; i < N; i++)
288
{
289
290 cin >> getPoint.x >> getPoint.y;
291 points.push_front(getPoint);
292 }
293
294
//call to quickhull function.Operation starts
295
296 QuickHull qh;
297 list<struct POINT> p = qh.quickHull(points);
298
299
300
//output
301
302 cout << "The points in the Convex hull using Quick
303
Hull are: " << endl;
304
305 list<struct POINT>::iterator i;
306
307
for(i = p.begin(); i!=p.end(); i++)
308
309
{
310 cout << i->x << " " << i->y << endl;
311 }
312
313
314
return 0;
315
}
[This code has its limitations. As no dynamic memorization and optimization is
used, it may show “time limit exceeded” in some compiler. But most will run the
code and the underlying algorithm will work.]

i. Step-01 and Step-02 are implemented in quickhull


function. (from line 23 to line 124)

ii. Step-03 and Step-04 are implemented in hullset


function. (from line 126 to line 229)

iii. The equation from Step-02 is implemented in


pointLocation function. (at line 230)

iv. The equation from Step-03 is implemented in


distance function. (at line 247)
References:
i. Introduction to Algorithms by CLRS
ii. Fundamentals of Computer Algorithms by SAHNI
iii. Quick Hull Implementation::
http://www.ahristov.com/tutorial/geometry-
games/convex-hull.html
iv. Asymptotic Notation::
https://www.khanacademy.org/computing/comp
uter-science/algorithms/asymptotic-
notation/a/asymptotic-notation