330 likes | 345 Views
מבוא מורחב למדעי המחשב בשפת Scheme. תרגול 3. Outline. Let High order procedures. Orders of Growth. We say that function R(n) O(f(n)) if there is a constant c > 0 such that for all n ≥1 R(n) ≤ c f(n).
E N D
Outline • Let • High order procedures
Orders of Growth • We say that function R(n)O(f(n))if there is a constant c>0such that for all n≥1 • R(n) ≤cf(n) • We say that function R(n)(f(n))if there are constants c1,c2> 0 such that for all n≥1 c1 f(n) ≤ R(n) ≤ c2 f(n) • We say that function R(n)(f(n))if there is a constant c>0such that for all n≥1 • cf(n)≤R(n)
Asymptotic version • Suppose f(n) < g(n) for all n≥N • There is always a constant c such that f(n) < c*g(n) for all n ≥ 1 • C=(max{f(n): n<N}+1)/min{g(n): n<N}
Practice 5n3 + 12n + 300n1/2 + 1 n2 + 30 350 25 n1/2 + 40log5n + 100000 12log2(n+1) + 6log(3n) 22n+3 + 37n15+ 9 (n3) (n2) (1) (n1/2) (log2n) (4n)
Comparing algorithms • Running time of a program implementing specific algorithm may vary depending on • Speed of specific computer(e.g. CPU speed) • Specific implementation(e.g. programming language) • Other factors (e.g. input characteristics) • Compare number of operation required by different algorithms asymptotically, i.e. order of growth as size of input increases to infinity
Efficient Algorithm • Algorithm for which number of operations and amount of required memory cells do not grow very fast as size of input increased • What operations to count? • What is input size (e.g. number of digits for representing input or input number itself)? • Different input of the same size can cause different running time.
Efficient algorithms cont’d • Input size: usually the size of input representation (number of bits/digits) • Usually interested in worst case running time ,i.e. number of operations for worst case • Usually we count primitive operations (arithmetic and/or comparisons)
Complexity Analysis • Reminder: • Space complexity - number of deferred operations(Scheme) • Time complexity - number of primitive steps • Method I – Qualitative Analysis • Example: Factorial • Each recursive call produce one deferred operation(multiplication) which takes constant time to perform • Total number of operations(time complexity) (n) • Maximum number of deferred operations(n) during the last call • Method II – Recurrence Equations
Recurrence Equations Code (define (sum-squares n) (if (= n 1) 1 (+ (square n) (sum-squares (- n 1)) ))) Recurrence T(n) = T(n-1) + (1) Solve T(n) T(n-1) + c T(n-2) + c + c T(n-3) + c + c + c … = T(1) + c + c + … + c = c + c + … + c = nc O(n)
Recurrence Equations Code (define (fib n) (cond ((= n 0) 0) ((= n 1) 1) (else (+(fib (- n 1))(fib (- n 2)) )))) Recurrence T(n) = T(n-1) + T(n-2) + (1) Solve For simplicity, we will solve T(n) = 2T(n-1) + (1), Which will give us an upper bound
(1) T(n-1) T(n-1) 2(1) T(n-2) T(n-2) T(n-2) T(n-2) 4(1) T(1) T(1) T(1) T(1) 2n-1(1) Total: (2n) Recursion Trees T(n)
Fibonacci - Complexity • Time complexity • T(n) < 2T(n-1)+(1) • Upper Bound: O(2n) • Tight Bound: (n)where =(5+1)/2 • Space Complexity: (n)
Common Recurrences T(n) = T(n-1) + (1) (n) T(n) = T(n-1) + (n) (n2) T(n) = T(n/2) + (1) (logn) T(n) = T(n/2) + (n) (n) T(n) = 2T(n-1) + (1) (2n) T(n) = 2T(n/2) + (1) (n) T(n) = 2T(n/2) + (n) (nlogn)
Back to GCD (define (gcd a b) (if (= b 0) a (gcd b (remainder a b)))) • Claim: The small number (b) is at least halved every second iteration • For “double iterations” we have T(b) T(b/2) + (1) • T(a) O(log(b))
Syntactic sugar - let Adding new local variables (let ((var1 exp1) (var2 exp2) ... (varN expN)) body) Equivalent to (syntactic saugar) ((lambda (var1 var2…varN) body) exp1…expN)
Let – finger examples (let ((x 3)) (+ x (* x 10))) ((lambda (x) (+ x (* x 10))) 3) (define x 5) (+ (let ((x 3)) (+ x (* x 10))) x) (+ ((lambda (x) (+ x (* x 10))) 3) x) (let ((x 3) (y (+ x 2))) (* x y)) ((lambda (x y) (* x y)) 3 (+ x 2))
Input: • Continuous function f(x) • a, b such that f(a)<0<f(b) • Goal: Find a root of the equation f(x)=0 • Relaxation: Settle with a “close-enough” solution Finding roots of equations
General Binary Search • Search space: set of all potential solutions • e.g. every real number in the interval [a b] can be a root • Divide search space into halves • e.g. [a (a+b)/2) and [(a+b)/2 b] • Identify which half has a solution • e.g. r is in [a (a+b)/2) or r is in [(a+b)/2 b] • Find the solution recursively in reduced search space • [a (a+b)/2) • Find solution for small search spaces • E.g. if abs(a-b)<e, r=(a+b)/2
Back to finding roots • Theorem: if f(a)<0<f(b) and f(x) is continuous, then there is a point c(a,b) such that f(c)=0 • Note: if a>b then the interval is (b,a) • Half interval method • Divide (a,b) into 2 halves • If interval is small enough – return middle point • Otherwise, use theorem to select correct half interval • Repeat iteratively
Example a b
Example (continued) a b And again and again…
Scheme implementation x (search f a x) (search f x b) x (define (search f a b) (let ((x (average a b))) (if (close-enough? a b) (let ((y (f x))) (cond ((positive? y) ) ((negative? y) ) (else ))))))
We need to define (define (close-enough? x y) (< (abs (- x y)) 0.001)) Determine positive and negative ends (define (half-interval-method f a b) (let ((fa (f a)) (fb (f b))) (cond ((and ) (search f a b)) ((and ) (search f b a)) (else (display “values are not of opposite signs”))) )) (negative? fa) (positive? fb) (negative? fb) (positive? fa)
Examples: sin(x)=0, x(2,4) (half-interval-method 2.0 4.0) x3-2x-3=0, x(1,2) (half-interval-method 1.0 2.0) sin 3.14111328125… (lambda (x) (- (* x x x) (* 2 x) 3)) 1.89306640625
Double (define (double f) (lambda (x) (f (f x)))) (define (inc x) (+ x 1)) ((double inc) 5) => 7 inc(x) = x + 1 f(f(x)) = x + 2 ((double square) 5) => 625 square(x) = x^2 f(f(x)) = x^4
Double Double (((double double) inc) 5) => 9 (double double) = double twice ((double double) inc) = (double (double inc)) inc = x + 1 ((double double) inc) = x + 4 (((double double) square) 5) => 152587890625 square = x^2 (double square) = x^4 ((double double) square) = x^16
Double Double Double (((double (double double)) inc) 5) => 21 (double double) = double twice (double (double double) = twice, then twice again (4 times) inc = x + 1 ((double (double double)) inc) = x + 16
Compose • Compose f(x), g(x) to f(g(x)) (define (compose f g) (lambda (x) (f (g x)))) (define (inc x) (+ x 1)) ((compose inc square) 3) 10 ((compose square inc) 3) 16
Compose now Execute later Repeated f f(x), f(f(x)), f(f(f(x))), … apply f, n times (define (compose f g) (lambda (x) (f (g x)))) (= n 1) f (repeated f (- n 1)) (define (repeated f n) (if (compose f ))) ((repeated inc 5) 100) => 105 ((repeated square 2) 5) => 625
Do nothing until called later Repeated f - iterative (define (repeated-iter f n x) (if (= n 1) (f x) (repeated-iter f (- n 1) (f x)))) (define (repeated f n) (lambda (x) (repeated-iter f n x)))
Compose now Execute later Repeated f – Iterative II (define (repeated f n) (define (repeated-iter count accum) (if (= count n) accum (repeated-iter (+ count 1) (compose f accum)))) (repeated-iter 1 f))
Repeatedly smooth a function (define (repeated-smooth f n) ) Smooth a function f: g(x) = (f(x – dx) + f(x) + f(x + dx)) / 3 (define (smooth f) (let ((dx 0.1)) )) (define (average x y z) (/ (+ x y z) 3)) (lambda (x) (average (f (- x dx)) (f x) (f (+ x dx)))) ((repeated smooth n) f)