Time and space behaviour. Chapter 20

Similar documents
The Limits of Sorting Divide-and-Conquer Comparison Sorts II

Elementary maths for GMT. Algorithm analysis Part II

asymptotic growth rate or order compare two functions, but ignore constant factors, small inputs

CS240 Fall Mike Lam, Professor. Algorithm Analysis

Fundamental mathematical techniques reviewed: Mathematical induction Recursion. Typically taught in courses such as Calculus and Discrete Mathematics.

Elementary maths for GMT. Algorithm analysis Part I

CS240 Fall Mike Lam, Professor. Algorithm Analysis

Adam Blank Lecture 2 Winter 2017 CSE 332. Data Structures and Parallelism

Complexity of Algorithms

Data Structures and Algorithms Key to Homework 1

CSE373: Data Structures and Algorithms Lecture 4: Asymptotic Analysis. Aaron Bauer Winter 2014

Testing. Wouter Swierstra and Alejandro Serrano. Advanced functional programming - Lecture 2. [Faculty of Science Information and Computing Sciences]

11. Divide and Conquer

Algorithm Analysis. (Algorithm Analysis ) Data Structures and Programming Spring / 48

DESIGN AND ANALYSIS OF ALGORITHMS. Unit 1 Chapter 4 ITERATIVE ALGORITHM DESIGN ISSUES

Run Times. Efficiency Issues. Run Times cont d. More on O( ) notation

Lecture 6: Sequential Sorting

[ 11.2, 11.3, 11.4] Analysis of Algorithms. Complexity of Algorithms. 400 lecture note # Overview

Unit 1 Chapter 4 ITERATIVE ALGORITHM DESIGN ISSUES

PROGRAMMING IN HASKELL. CS Chapter 6 - Recursive Functions

Pseudo code of algorithms are to be read by.

Then you were asked to paint another fence that is 2m high and 400m long for the price of $80. Should you accept it?

Lecture 2: Algorithm Analysis

Analysis of Algorithms. CSE Data Structures April 10, 2002

Recall from Last Time: Big-Oh Notation

Data Structures Question Bank Multiple Choice

Introduction to Programming: Lecture 6

PROGRAMMING IN HASKELL. Chapter 5 - List Comprehensions

Algorithms A Look At Efficiency

How do we compare algorithms meaningfully? (i.e.) the same algorithm will 1) run at different speeds 2) require different amounts of space

Measuring algorithm efficiency

Midterm solutions. n f 3 (n) = 3

Algorithm Analysis. College of Computing & Information Technology King Abdulaziz University. CPCS-204 Data Structures I

Chapter 2: Complexity Analysis

Plotting run-time graphically. Plotting run-time graphically. CS241 Algorithmics - week 1 review. Prefix Averages - Algorithm #1

The University of Nottingham

Algorithms and Data Structures

Computer Science 210 Data Structures Siena College Fall Topic Notes: Complexity and Asymptotic Analysis

Introduction to Computers & Programming

Analysis of Algorithm. Chapter 2

CMPSCI 187: Programming With Data Structures. Lecture 5: Analysis of Algorithms Overview 16 September 2011

10/5/2016. Comparing Algorithms. Analyzing Code ( worst case ) Example. Analyzing Code. Binary Search. Linear Search

Algorithms and Theory of Computation. Lecture 2: Big-O Notation Graph Algorithms

For searching and sorting algorithms, this is particularly dependent on the number of data elements.

Computer Algorithms. Introduction to Algorithm

UNIT 1 ANALYSIS OF ALGORITHMS

Multiple-choice (35 pt.)

CS 137 Part 7. Big-Oh Notation, Linear Searching and Basic Sorting Algorithms. November 10th, 2017

CSE373: Data Structure & Algorithms Lecture 21: More Comparison Sorting. Aaron Bauer Winter 2014

The Running Time of Programs

University of Toronto Department of Electrical and Computer Engineering. Midterm Examination. ECE 345 Algorithms and Data Structures Fall 2010

Why study algorithms? CS 561, Lecture 1. Today s Outline. Why study algorithms? (II)

csci 210: Data Structures Program Analysis

(Refer Slide Time: 1:27)

9/10/2018 Algorithms & Data Structures Analysis of Algorithms. Siyuan Jiang, Sept

Algorithm Performance. (the Big-O)

Java How to Program, 9/e. Copyright by Pearson Education, Inc. All Rights Reserved.

Computer Science Approach to problem solving

TREES AND ORDERS OF GROWTH 7

Shell CSCE 314 TAMU. Functions continued

CS/ENGRD 2110 Object-Oriented Programming and Data Structures Spring 2012 Thorsten Joachims. Lecture 10: Asymptotic Complexity and

Data Structures and Algorithms

Module 5: Hashing. CS Data Structures and Data Management. Reza Dorrigiv, Daniel Roche. School of Computer Science, University of Waterloo

CSE 146. Asymptotic Analysis Interview Question of the Day Homework 1 & Project 1 Work Session

HOMEWORK FILE SOLUTIONS

Data Structures and Algorithms. Part 2

1 The smallest free number

Classic Data Structures Introduction UNIT I

Basic Data Structures (Version 7) Name:

Final Examination: Topics and Sample Problems

CS S-02 Algorithm Analysis 1

CSI33 Data Structures

Algorithm Analysis and Design

CS 61B Asymptotic Analysis Fall 2018

W4231: Analysis of Algorithms

Lecture 5: Running Time Evaluation

CS126 Final Exam Review

PROGRAM EFFICIENCY & COMPLEXITY ANALYSIS

CS:3330 (22c:31) Algorithms

Haske k ll An introduction to Functional functional programming using Haskell Purely Lazy Example: QuickSort in Java Example: QuickSort in Haskell

Sorting. Bubble Sort. Selection Sort

CSE 332 Spring 2013: Midterm Exam (closed book, closed notes, no calculators)

Complexity of Algorithms. Andreas Klappenecker

The Complexity of Algorithms (3A) Young Won Lim 4/3/18

Algorithms in Systems Engineering IE172. Midterm Review. Dr. Ted Ralphs

Week - 03 Lecture - 18 Recursion. For the last lecture of this week, we will look at recursive functions. (Refer Slide Time: 00:05)

An introduction introduction to functional functional programming programming using usin Haskell

Unit 6 Chapter 15 EXAMPLES OF COMPLEXITY CALCULATION

15 150: Principles of Functional Programming Sorting Integer Lists

Computational Complexity: Measuring the Efficiency of Algorithms

Choice of C++ as Language

Chapter 6 INTRODUCTION TO DATA STRUCTURES AND ALGORITHMS

You should know the first sum above. The rest will be given if you ever need them. However, you should remember that,, and.

CS 580: Algorithm Design and Analysis. Jeremiah Blocki Purdue University Spring 2018

Chapter 3, Algorithms Algorithms

Shell CSCE 314 TAMU. Haskell Functions

A general introduction to Functional Programming using Haskell

Intro. Speed V Growth

CSCE 314 TAMU Fall CSCE 314: Programming Languages Dr. Flemming Andersen. Haskell Functions

CSE 332, Spring 2010, Midterm Examination 30 April 2010

Transcription:

Time and space behaviour Chapter 20

Algorithmic complexity How many steps does it take to execute an algorithm given an input of size n?

Complexity of functions Consider: f n = 2 n 2 + 4 n + 13 This function has three components: a constant, 13 a term 4 n a term 2 n 2 As the value of n increases: the constant component is unchanged the 4 n component grows linearly the 2 n 2 component grows quadratically

Complexity of functions: big-oh O For large n, the quadratic term dominates in f. So, we say that f is of order n 2 and we write O(n 2 ) A function f::integer->integer is O(g) if there are positive integers m and d such that for all n m: f n d (g n) i.e., that f is bounded above by g: for sufficiently large n the value of f is no larger than a multiple of the function g. e.g., f from the previous slide is O(n 2 ), since for n 1: 2 n 2 + 4 n + 13 2 n 2 + 4 n 2 + 13 n 2 19 n 2

Complexity of functions: big-theta Θ For a tight bound, a function f is Θ(g) when: both f is O(g) and g is O(f) When f is O(g) but g is not O(f) we write f g. Also, when f is Θ(g) we write f g. n 0 n 1 n 2 n k 2 n n 0 log n n 1 n (log n) n 2

28 y=10 x y=10x 2 24 20 y=x 16 12 y=10 8 4 0 0.25 0.5 0.75 1 1.25 1.5 1.75 2

y=x 2 y=x log x y=x 1 10 7.5 5 2.5 y=log x y=x 0 0 2.5 5 7.5 10 12.5 15

Bisection Given a list of length n, how many times can it be bisected before all the pieces are of length one? After p cuts the length of each piece is n/(2 p ). We are looking for p such that ( n/(2 p ) ) 1 and ( n/(2 p-1 ) ) > 1, i.e. n 2 p and n > 2 p-1 : 2 p n > 2 p-1 p log 2 n > p-1 The function giving the number of steps in terms of the length n is Θ(log 2 n)

We are looking for p such: p log 2 n > p-1 log 2 n > p-1 => p < 1 + log 2 n p is a function of n (the length of a list) f(n) < 1 + log 2 n A function f::integer->integer is O(g) if there are positive integers m and d such that for all n m: f n d (g n) There exists m (e.g.: 10) and d (e.g.: 3) such that f(n) d * log 2 n for all n m For example f(10) < 1 + log 2 (10) <= 3 * log 2 (10) f(11) < 1 + log 2 (11) <= 3 * log 2 (11) Therefore, F(n) is O(log 2 n) (the upper bound). Similarly we can prove the lower bound, the other direction usung the other inequality. Hence, Θ(log 2 n).

Size of a balanced binary tree A tree is balanced if all of its branches are the same length. Given a balanced binary tree whose branches are length b, how many nodes are there in the tree? 1 + 2 + 4 + + 2 k-1 +... + 2 b = 2 b+1 1 Thus, the size of the tree is Θ(2 b ) in the length of the branches. Conversely, a balanced tree will have branches of length Θ(log 2 n) in the size of the tree.

Apples Given an apple a day for n days we will end up with n apples. Given n apples a day for n days we will end up with n 2 apples. Given 1 apple on the first day, 2 apples on the second day, etc., how many apples do we end up with? That is, what is the sum of the list [1..n]? 1 + 2 + 3 + + (n-1) + n = n + (n-1) + (n-2) + + 2 + 1 = ((n+1) + (n+1) + (n+1) + + (n+1) + (n+1)) / 2 = n (n+1) / 2 which is quadratic, Θ(n 2 ).

Measuring complexity Time taken to compute a result is given by the number of steps in a calculation. Space necessary for the computation. During calculation the expression being calculate grows and shrinks we need space to hold the largest expression. This is called the residency of the calculation, or its space complexity. Total space used by a computation, reflecting not just the size of the expression but the sizes of the values as well.

Factorial fac :: Integer -> Integer fac 0 = 1 fac n = n * fac (n-1) fac n n * fac (n-1) n * ((n-1) *... * (2 * (1 * 1))... ) n * ((n-1) *... * (2 * 1)... ) n * ((n-1) *... * 2... ) n! This takes 2n+1 steps and the largest expression contains n multiplication symbols. So, time and space is linear, Θ(n)

Insertion sort isort :: Ord a => [a] -> [a] isort [] = [] isort (x:xs) = ins x (isort xs) ins :: Ord a => a -> [a] -> [a] ins x [] = [x] ins x (y:ys) (x<=y) = x:y:ys otherwise = y:ins x ys

isort [] = [] isort (x:xs) = ins x (isort xs) isort [a 1, a 2,..., a n-1, a n ] ins a 1 (isort [a 2,..., a n-1, a n ])... ins a 1 (ins a 2 (... (ins a n-1 (ins a n []))... )) So, n steps followed by n invocations of ins.

ins x [] = [x] ins x (y:ys) (x<=y) = x:y:ys otherwise = y:ins x ys Assume[a 1,,..., a n ] is sorted. ins a [a 1, a 2,..., a n-1, a n ] Best case: a<=a 1, takes one step Worst case: a>a n, takes n steps Average case: takes n/2 steps

So for isort: ins a 1 (ins a 2 (... (ins a n-1 (ins a n []))... )) Best case: each ins takes one step, so n more steps, so 2n steps overall which is O(n) Worst case: first ins 1 step, second 2,, so overall O(n 2 ) Average case: ins s will take 1/2 + 2/2 + + (n-1)/2 + n/2 steps, so overall O(n 2 ) isort takes quadratic time in most cases, linear for (almost) sorted lists. Space usage is linear in all cases.

++ [a 1, a 2,..., a n-1, a n ] ++ x a 1 : ([a 2,..., a n-1, a n ] ++ x) a 1 : (a 2 : ([a 3,..., a n-1, a n ] ++ x)) n-3 steps a 1 : (a 2 :... : (a n :x)) So, the time taken is linear in the length of the first list.

Quick sort qsort :: Ord a => [a] -> [a] qsort [] = [] qsort (x:xs) = qsort [z z<-xs,z<=x] ++ [x] ++ qsort [z z<-xs,z>x] When the list is sorted and without duplicates the calculation goes: qsort [a 1, a 2,..., a n-1, a n ] n steps [] ++ [a 1 ] ++ qsort [a 2,..., a n-1, a n ] n-1 steps a 1 : ([] ++ [a 2 ] ++ qsort [a 3,..., a n-1, a n ]) n-2 steps a 1 : (a 2 : (a 3 :... a n : [])) [a 1, a 2,..., a n-1, a n ] So, overall 1+2+...+n steps, so qsort is quadratic for sorted lists: O(n 2 )

qsort :: Ord a => [a] -> [a] qsort [] = [] qsort (x:xs) = qsort [z z<-xs,z<=x] ++ [x] ++ qsort [z z<-xs,z>x] In the average case: qsort [a 1, a 2,..., a n-1, a n ] qsort [b 1,..., b n/2 ] ++ [a 1 ] ++ qsort [c 1,..., c n/2 ] Forming the two sublists takes O(n 1 ) steps, and O(n 1 ) steps to join the results. It takes O(log 2 n) bisections to obtain singleton lists. So qsort is on average O(n(log 2 n)).

Logarithmic behaviour is characteristic of divide-and-conquer algorithms: we split the problem into two smaller problems, solve them and recombine the results. They reach their base case in O(log 2 n) rather than O(n) steps.

Lazy evaluation arguments to functions are evaluated only when this is necessary for evaluation to continue an argument is not necessarily evaluated fully: only the parts that are needed are examined an argument is evaluated at most once (expressions are replaced by graphs and calculation is done over the graphs) evaluation order is from the outside in (for nested functions, e.g.: f 1 e 1 (f 2 e 2 5)) and from left to right (e.g.: f 1 e 1 + f 2 e 2 ).

Space behaviour: lazy evaluation Rule of thumb for space is the size of the largest expression produced during evaluation. This is accurate for computing numbers or Booleans, but not for data structures. Lazy evaluation means partial results are outputted, and discarded, once computed.

Space behaviour: lazy evaluation Consider: [m.. n] n >= m = m:[m+1.. n] otherwise = [] [1..n]?? n >= 1 1:[1+1.. n]?? n >= 1+1?? n >= 2 1:[2.. n] 1:2:[2+1.. n] 1:2:3: :n:[] The underlined pieces are printed and discarded as soon as possible. To measure space complexity we look at the non-underlined part (the residual evaluation), which is of constant size. So, space complexity is O(n 0 ).

Space behaviour: where clauses exam1 = [1..n] ++ [1..n] Takes time O(n 1 ) and space O(n 0 ) but calculates [1..n] twice! exam2 = list ++ list where list = [1..n] After evaluating list, the whole of the list is stored, giving space complexity O(n 1 )

Space behaviour: where clauses exam3 = [1..n] ++ [last [1..n]] exam4 = list ++ [last list] where list = [1..n] Space is O(n 0 ) Space is O(n 1 ) This is a space leak, since we only need one element of list.

Space behaviour: where clauses Avoiding redundant computation is (usually) always sensible, but it comes at the cost of space.

Saving space? fac 0 = 1 fac n = n * fac (n-1) Has O(n 1 ) space complexity from: n * ((n-1) *... * (2 * (1 * 1))... ) before it is evaluated. Alternative is to perform multiplication as we go: newfac :: Integer -> Integer newfac n = afac n 1 afac :: Integer -> Integer -> Integer afac 0 p = p afac n p = afac (n-1) (p*n)

newfac :: Integer -> Integer newfac n = afac n 1 afac :: Integer -> Integer -> Integer afac 0 p = p afac n p = afac (n-1) (p*n) newfac n afac n 1 afac (n-1) (1*n)?? (n-1) == 0 False afac (n-2) (1*n*(n-1)) afac 0 (1*n*(n-1)*(n-2)* *2*1) (1*n*(n-1)*(n-2)* *2*1) Still forms a large unevaluated expression, since its value is not needed until the end.

Consider: afac 0 p = p afac n p (p==p) = afac (n-1) (p*n) The guard test forces evaluation of the intermediate multiplications. This version has constant space behaviour. afac 4 1 afac (4-1) (1*4)?? (4-1) == 0 False?? (1*4) == (1*4)?? 4 == 4 True afac (3-1) (4*3)?? (3-1) == 0 False?? (4*3) == (4*3)?? 12 == 12 True afac (2-1) (12*2) afac 0 (24*1) (24*1) 24

Strictness A function is strict in an argument if the result is undefined whenever the argument is undefined. Examples: (+) is strict in both arguments (&&) is strict in only its first argument: True && x = x False && x = False A function that is not strict in an argument is said to be non-strict or lazy in that argument.