Professional Documents
Culture Documents
CS-E3190 Lect01 PDF
CS-E3190 Lect01 PDF
CS-E3190 Lect01 PDF
CS-E3190
Pekka Orponen
Department of Computer Science
Aalto University
Autumn 2017
1 Introduction and overview
CE-3190 PAT
Autumn 2017
2/37
1.2 Example: selection sort
Consider the common task of arranging n integers contained in
array A[1 . . . n] in increasing order. A high-level pseudocode
presentation of the simple selection sort algorithm for this task
is as follows:
Algorithm 1: The selection sort algorithm
1 function S ELECT S ORT (A[1 . . . n])
Input: Integer array A[1 . . . n].
Output: Array A, with same items in increasing order.
2 Set i 1.
3 Find smallest of items A[i], . . . , A[n]. Let this have index imin .
4 Exchange elements A[i] and A[imin ].
5 Set i i + 1; if i < n, go back to line 3.
6 When i = n, the items in A are in increasing order.
CE-3190 PAT
Autumn 2017
3/37
The algorithm can be implemented in, e.g., the Python
programming language (V.3) as follows:
def select_sort(A):
n = len(A)
for i in range(n-1):
imin = i
for j in range(i+1, n):
if A[j] < A[imin]:
imin = j
A[i], A[imin] = A[imin], A[i]
return A
CE-3190 PAT
Autumn 2017
4/37
Let us embed this Python function in a complete executable
module, with some timing features, and test it:
import random
import time
def select_sort(A):
[...]
while True:
try:
n = int(input("Number of items = "))
except EOFError:
break
if n < 1:
print("Number must be positive. Try again.")
continue
CE-3190 PAT
Autumn 2017
5/37
if n > nmax:
print("Number too large. Try again.")
continue
select_sort(A)
stop = time.time()
print("Done. Time = %.4f seconds." % (stop - start))
print("\n")
CE-3190 PAT
Autumn 2017
6/37
> python3 selectsort.py
Number of items = 2000
Generating 2000 random numbers in the range 0..2147483647.
Beginning selection sort of 2000 items.
Done. Time = 0.2238 seconds.
Number of items = 4000
Generating 4000 random numbers in the range 0..2147483647.
Beginning selection sort of 4000 items.
Done. Time = 0.8275 seconds.
Number of items = 6000
Generating 6000 random numbers in the range 0..2147483647.
Beginning selection sort of 6000 items.
Done. Time = 1.8435 seconds.
...
Number of items = 20000
Generating 20000 random numbers in the range 0..2147483647.
Beginning selection sort of 20000 items.
Done. Time = 19.7716 seconds.
CE-3190 PAT
Autumn 2017
7/37
Runtime of selection sort
20
15
10
0
3
0 2 4 6 8 10 12 14 16 18 20 x10
CE-3190 PAT
Autumn 2017
9/37
A priori analysis of selection sort (2/2)
Assuming each elementary operation of the algorithm
requires 1 time unit, then for each value of index i
(i = 1 . . . n 1) one obtains the computation times:
I Row 3: 1 time unit.
I Rows 46: (n i) time units.
I Row 7: 1 time unit.
CE-3190 PAT
Autumn 2017
10/37
1.3 Merge sort (1/2)
An alternative sorting method is the merge sort algorithm
based on repeated partitioning of the input array. (In the
following, assume for simplicity that n is of the form 2k for some
k = 0, 1, 2, . . . .)
CE-3190 PAT
Autumn 2017
11/37
Merge sort (2/2)
E.g. on input sequence A = [3 1 4 2] the algorithm proceeds as
follows:
[3 1 4 2]
partition
[3 1] [4 2]
partition
merge
[1 3] [2 4]
merge
[1 2 3 4]
CE-3190 PAT
Autumn 2017
12/37
A Python implementation of merge sort:
def merge_sort(A):
n = len(A)
if n == 1:
return A
else:
h = n//2
return merge(merge_sort(A[0:h]),
merge_sort(A[h:n]))
CE-3190 PAT
Autumn 2017
13/37
def merge(A, B):
C = []
m, n = len(A), len(B)
i, j = 0, 0
while (i < m) and (j < n):
if A[i] <= B[j]:
C.append(A[i])
i = i+1
else:
C.append(B[j])
j = j+1
if i < m:
C.extend(A[i:m])
if j < n:
C.extend(B[j:n])
return C
CE-3190 PAT
Autumn 2017
14/37
Runtime of merge sort
1,4
1,2
1,0
0,8
0,6
0,4
0,2
0
3
0 20 40 60 80 100 120 140 160 180 200x10
T (1) = 1,
T (n) = 2T (n/2) + n, when n = 2k , k 1.
CE-3190 PAT
Autumn 2017
16/37
A priori analysis of merge sort (2/2)
T (n) = n log2 n + n.
CE-3190 PAT
Autumn 2017
17/37
1.4 Fibonacci numbers
Let us consider another example where the choice of a proper
algorithm leads to an even more dramatic improvement in
efficiency.
The sequence of Fibonacci numbers F0 , F1 , . . . is defined by
the well-known recursion formula:
0,
if n = 0,
Fn = 1, if n = 1,
Fn1 + Fn2 , if n 2.
CE-3190 PAT
Autumn 2017
18/37
It is tempting to use the definition of Fibonacci numbers directly
as the basis of a simple recursive method for computing them:
CE-3190 PAT
Autumn 2017
19/37
The reason for the inefficiency is that the algorithm recomputes
most of the values several (in fact, exponentially many) times:
Fn
Fn1 Fn2
CE-3190 PAT
Autumn 2017
20/37
The recomputations can, however, be easily avoided by
computing the values iteratively bottom-up and tabulating
them:
Algorithm 5: Improved algorithm for Fibonacci numbers
1 function F IB 2 (n)
2 if n = 0 then return 0
3 else
4 Introduce auxiliary array F [0 . . . n]
5 F [0] 0; F [1] 1
6 for i 2 to n do
7 F [i] F [i 1] + F [i 2]
8 end
9 return F [n]
10 end
The computation time is now just O(n) a huge improvement!
CE-3190 PAT
Autumn 2017
21/37
Lecture 2: Algorithms and their analysis
CE-3190 PAT
Autumn 2017
22/37
Lecture 3: Divide-and-conquer I
CE-3190 PAT
Autumn 2017
23/37
Lecture 4: Divide-and-conquer II
CE-3190 PAT
Autumn 2017
24/37
Lecture 5: Graph algorithms I
CE-3190 PAT
Autumn 2017
25/37
Lecture 6: Graph algorithms II
CE-3190 PAT
Autumn 2017
26/37
Lecture 7: Graph algorithms III
CE-3190 PAT
Autumn 2017
27/37
Lecture 8: Greedy algorithms
CE-3190 PAT
Autumn 2017
28/37
Lecture 9: Dynamic programming
CE-3190 PAT
Autumn 2017
29/37
Lecture 10: NP-completeness
CE-3190 PAT
Autumn 2017
30/37
Lecture 11: Approximation algorithms
CE-3190 PAT
Autumn 2017
31/37
Lecture 12: Randomised algorithms
CE-3190 PAT
Autumn 2017
32/37
Lecture 13: Algorithms with numbers I
CE-3190 PAT
Autumn 2017
33/37
Lecture 14: Algorithms with numbers II
CE-3190 PAT
Autumn 2017
34/37
Lecture 15: The fast Fourier transform
CE-3190 PAT
Autumn 2017
35/37
Lecture 16: Fundamental data structures
CE-3190 PAT
Autumn 2017
36/37
Lecture 17: Epilog & exam information
CE-3190 PAT
Autumn 2017
37/37