Algoritm analys och rekursiva metoder kap 5,7 Algoritmernas exekveringstid kan representeras som funktioner Big-Oh notationen för uppskattning av exekveringstiden -Exekveringstiden för linjär sökning och binärt sökning Kap 5 ( inget om Big-Omega, Big-Theta)
En algoritm? En algoritm är ett sätt av instruktioner som datorn skall följa för att lösa ett problem. public static int seach( int [ ] a, int key) { // söka genom arrayen a tills man hittar ett // ellement==key eller till slutet av arrayen // returnera index för element eller -1 }
Exempel T(N)=N/1.6 +2 Efter 2 sek delay kan vi ladda ner 1.6 K/sec. För en fil med N Kbyte . Hur lång tid tar nedladningen? T(N)=N/1.6 +2 Tiden som tar för en algoritm att exekveras beror på storleken av data som algoritmen behandlar.
Algoritm analys Att beräkna en algoritms komplexitet kallas algoritm analys. Algoritm komplexitet kan handlar om: ”Algorithm time complexity”. Tiden som tar för exekvering ”Algorithm space complexity”. Minnet som krävs för att exekvering.
Experimental analys - genom att exekvera programmmet med olika input och räkna tiden long tid1=System.curentTimeMillis() algoritm long tid2=System.curentTimeMillis() long tid=tid2-tid1
Exekveringstiden som en funktion av input storlek t(ms) 50 * 10 n 5000 10000
Nackdelar med experimental anlys Algoritmen måste implementeras Experiment kan göras på en begränsad antal input, och kan inte vara relevant för andra input storlekar Om du ska jämföra två algoritmer måste dessa testas med samma hårdvaru och mjukvaru förutsättningar Den exakta ex.tiden kräver mycket arbete och är inte relevant i valet av algoritmen I stället: Använd en high-level beskrivning av algoritmen och uppskatta ex.tid
Att uppskatta exekveringstiden Hitta en funktion av f(n) som har samma beteende som algoritmens exekveringstid. Detta kallas tillväxtfunktion. Du jämför två algoritmer genom att titta på tillväxt funktionerna för dessa algoritmer.
Hur? Gör en algoritm som beräknar summan av 1+2+3+ .... + n, alla positiva tal. Algoritm A Algoritm B Algoritm C sum=0 for i=1 to n for j=1 to i sum=sum+1 sum=n*(n+1)/2 sum=0 for i=1 to n sum=sum+ i; Vilken algoritm har den bästa ex.tiden?
Hur många operationer utförs för varje algoritm sum=0 for i=1 to n for j=1 to i sum=sum+1 sum=0 for i=1 to n sum=sum+ i; sum=n*(n+1)/2 tilldelning n+1 1+n(n+1)/2 1 addition n n(n+1)/2 multiplikation div Total operationer 2n+1 n^2+n+1 4 Bra att veta: 1+2+3+..+n =n(n+1)/2 och 1+2+3+...+n-1= n(n-1)/2
Exekveringstiden, en funktion av inputdata B n^2+n+1 T(n) A 2n+1 C 4 n
Big-Oh, notationen Om tillväxthastigheten för en algoritm är proportionell med n -> algoritmen är O(n) Om tillväxthastigheten för en algoritm är konstant -> algoritmen är O(1) Om tillväxthastigheten är proportionell med n^2 -> algoritmen är O(n^2)
Varför kan vi ignorera operationer? Det som är intressant är tillväxthastigheten och inte det exakta exekveringstiden. Big-Oh regel : En algoritm kan representeras med en funktion t(n) ( till ex. n^2+100n ) är O(n^2) om det finns funktionen f(n) (till ex n^2) som för en konstant c och en n0 <n då alltid t(n)<=c*f(n) för alla n>n0 För tillräckligt stora input den dominanta termern avgör funktionens värde
Varför kan operationer ignorerars? for N = 1000 10N3 + N2 + 40N + 80 10001040080 N3 10000000000 For N = 1000 skillnaden is 0.01% !!
Funktioner sorterade efter tillväxthastigheten c Constant log(N) Logarithmic log2(N) Log-squared N Linear Nlog(N) N log N N2 Quadratic N3 Cubic 2N Exponential
Tidskomplexitet N2 N log N N
I praktiken Linear Quadratic public void myAlgorithm() { int s = 0; for (int i = 0; i < N; i++) { s += i; } for (int j = 0; j < N; j++) { s *= (j - i); System.out.println(”s=” + s); Linear Quadratic
I praktiken… Linear Quadratic Bara den dominanta termern public void myAlgorithm() { int s = 0; for (int i = 0; i < N; i++) { s += i; } for (int j = 0; j < N; j++) { s *= (j - i); System.out.println(”s=” + s); Linear Quadratic Bara den dominanta termern
Generellt 1. Ex.tiden för en loop är högst exekverings tiderna för satserna i loopen * antal iterationer 2. Ex.tiden för en grundoperation är konstant O(1) 3. Ex.tiden för en följd av satser är exekveringstiden för den dominanta satsen 4. För n>10 tillväxthastigheten för algoritmer växer enligt O(1) < O(logn) < O(N) < O(nlogn) < O(n^2) < O(n^3) < O(2^n)
Hitta ett element i en osorterad array public static boolean badSearch(int [] arr, int key){ boolean found=false for(i=0;i<arr.length;i++){ if(arr[i]==key) faund=true; } return faund; Best case: Worst case: Average case:
BinarySearch - exkveringstiden public static int binarySearch(int [ ] arr,int key) { int first=0; int last=a.length-1 // index av sista elementet int mid; while(first<=last) mid=first+last/2 if(arr[mid]<key) first=mid+1 else if last=mid-1 else return mid; } return -1; Exekverinstiden är?
2 4 6 8 10 12 14 16 18 20 22 24 26 28