Algoritmteori - effektivitet Viktiga egenskaper hos algoritmer: korrekthet beräkningsbarhet - computability användbarhet - feasibility effektivitet elegans lättförståelighet underhållsvänlighet Problem: Vi har en sociolog som vill göra en gallupundersökning. Tyvärr är inte alla de intervjuade villiga att ange sin ålder, och i dessa fall har intervjuaren satt dit en 0 istället för åldern. För att nu inte få alltför konstiga resultat gäller det att rensa ut nollorna innan man behandlar de samlade data vidare. Vi har talen som ska beteckna intervjuobjektens ålder i en lista. Nu gäller det att hitta på ett maximalt effektivt sätt att avlägsna nollorna ur listan och räkna hur många verkliga, legitima, åldrar man har kvar. 15 28 30 0 14 0 65 72 41 0 13 14 Introduktion till datateknik/cs3, A. Soini 1
Idé 1: Ny lista - Vi tar en ny, tom lista och kopierar dit alla talen olika 0: lista: 15 28 30 0 14 0 65 72 41 0 13 14 nylista: 15 28 30 14 65 72 41 13 14 Vi kopierade 9 st. element, alltså är antalet legitima tal 9. Algoritm: Givet: lista[1]..lista[n], en ny tom lista nylista med utrymme för n element. 1. left < 1 2. nypos < 1 3. Så länge left <= n, repetera: 3.1. Om lista[left] 0 så 3.1.1. nylista[nypos] < lista[left] 3.1.2. left < left + 1 3.1.3. nypos < nypos + 1 annars 3.2. left < left + 1 4. legitima < nypos -1 5. Slut Introduktion till datateknik/cs3, A. Soini 2
Idé 2: Flytta block - För att undvika behovet av två listor, låter vi nollorna överskrivas av de legitima talen: 15 28 30 0 14 0 65 72 41 0 13 14 15 28 30 14 0 65 72 41 0 13 14 14 legit = 11 15 28 30 14 0 65 72 41 0 13 14 14 15 28 30 14 65 72 41 0 13 14 14 14 legit = 10 15 28 30 14 65 72 41 0 13 14 14 14 15 28 30 14 65 72 41 13 14 14 14 14 legit = 9 Introduktion till datateknik/cs3, A. Soini 3
För varje 0 vi överskriver minskar vi antalet legitima med 1. För att överskriva nollan, flyttar vi varje tal bakom det framåt med ett steg, börjande från talet bakom nollan. 1. left < 1 2. right < 2 3. legitima < n {optimistisk antagande} 4. Så länge left <= legitima, repetera: 4.1. Om lista[left] 0, så 4.1.1. left < left + 1 4.1.2. right < right + 1 4.2. annars 4.2.1. så länge right < n repetera: 4.2.1.1. lista[right-1] < lista[right] 4.2.1.2. right < right + 1 4.2.2. right < left + 1 4.2.3. legitima < legitima - 1 5. Slut 1 2 3 4 0 0 left right 1 2 3 4 0// 0 0 left right n = 3 left = 1 right = 2 legitima = 3 n = 3 left = 2 right = 3 legitima = 3 lista[1] <> 0, left <- 2 right <- 3 lista[2] = 0, lista[2] <- lista[3] right <- 4 right <- 3 legitima <- 2 1 2 3 4 0// 0 0 left right villkor 4.: left <= legitima (2 <= 1) blir false, programmet slutar. Introduktion till datateknik/cs3, A. Soini 4 n = 3 left = 2 right = 3 legitima = 2 lista[2] = 0, lista[2] <- lista[3] right <- 4 right <- 3 legitima <- 1
Idé 3: Byte vid behov - vi söker efter ersättare från högerdelen av listan. När left och right möts, tar det legitima utrymmet slut. 15 28 30 0 14 0 65 72 41 0 13 14 15 28 30 14 14 13 65 72 41 0 13 14 1. left < 1 2. right < n 3. legitima < n {optimistisk antagande} 4. Så länge left < right, repetera: 4.1. Om lista[left] 0, så 4.1.1. left < left + 1 4.2. annars 4.2.1. legitima < legitima - 1 4.2.2. lista[left] < lista[right] 4.2.3. right < right - 1 5. Om lista[left] = 0, så legitima < legitima - 1 6. Slut Introduktion till datateknik/cs3, A. Soini 5
Analys av algoritmer - en första introduktion: Centrala termer: Storleksordning - Order of magnitude O(f(n)) eller (f(n)). (omega = tid) Best case B(n) Worst case W(n) Average case A(n) Ny lista Flytta block Byte vid behov tid utrymme tid utrymme tid utrymme Best case O(n) n O(n) n O(n) n Worst case O(n) 2n O(n 2 ) n O(n) n Aver. case O(n) n x 2n O(n 2 ) n O(n) n Är bästa fallet för algoritmens effektivitet även bästa fallet för vår sociolog? Hur räknar man ut en algoritms O-klass? Välj den dominerande operationen (den som utförs oftast när antalet dataenheter att bearbeta, n, växer) Analysera hur ofta operationen utförs med avseende på n Anta, att du får som resultat en polynom, ex. 3n 3 + 100n 2 + 2000n + 50. Titta bara på den största termen, den som växer snabbast när n växer (här 3n 3 ). Utelämna ännu koefficienten: du har O(n 3 ). Introduktion till datateknik/cs3, A. Soini 6
Standardlösningar - binärsökning: En snabbare sökrutin än sekventiell sökning. Förutsätter att listan är sorterad Idé: pröva i mitten - om det inte lyckas, välj vilken del det lönar sig att pröva nästa gång (jfr. en telefonkatalog; du läser inte genom katalogen från Aalto, Aalto, Aaltonen... när du söker efter Wetterström...) Givet: söknamn, katalogen namn[1].. namn[n] och respektive telefonnummer tel[1].. tel[n] 1. start < 1 2. slut < n 3. hittad < false 4. Repetera tills hittad = true eller slut < start: 4.1. mitten < (start + slut) DIV 2 {medelpunkten m beräknas, DIV står för heltalsdivision} 4.2. Om söknamn = namn[mitten] {vi hade tur!!!} så 4.2.1. skriv ut motsvarande nummer tel[mitten] 4.2.2 hittad < true annars 4.3. om söknamn < namn[mitten] så 4.3.1 slut < mitten - 1 {vi ska söka i första halvan} annars {söknamnet måste komma efter mitten} 4.3.2. start < mitten + 1 5. Om hittad = false så skriv ut sorry, namnet finns inte 6. Slut Introduktion till datateknik/cs3, A. Soini 7
Exempel med tal i stället för namn: hitta 54! index talen försöken 2 14 18 21 23 27 31 42 44 54 62 70 1 2 4! 3 start slut mitten 1 12 (1 + 12) div 2 = 6 7 12 (7 + 12) div 2 = 9 10 12 (10 + 12) div 2 = 11 10 10 (10 + 10) div 2 = 10 - hittat! Exempel med tal i stället för namn: hitta 13! index talen försöken 2 14 18 21 23 27 31 42 44 54 62 70 3 4 2 1 start slut mitten 1 12 (1 + 12) div 2 = 6 1 5 (1 + 5) div 2 = 3 1 2 (1 + 2) div 2 = 1 2 2 (2 + 2) div 2 = 2 sista chansen 2 1 slut > start, sökrymden tom Introduktion till datateknik/cs3, A. Soini 8
Analys av tidigare exempel: problem operation algoritm best case worst case average case sökning jämförelser sekventiell s. 1 O(n) O(n) sortering jämförelser, swap binärsökning 1 O(log 2 n) O(log 2 n) selektionssortering O(n 2 ) O(n 2 ) O(n 2 ) Rensa lista testa, kopiera flytta block O(n) O(n 2 ) O(n 2 ) ny lista O(n) O(n) O(n) byte vid behov delsträngar jämförelser forward march O(n) O(n) O(n) O(n) O(mn) - Realistiskt lösbara (feasible) problem måste vara polynomiellt bundna, dvs. av typen O(n c ) - och konstanten c får inte vara alltför stort heller... Det finns dock problem som inte kan lösas i polynomiell tid, dvs. problem av typen O(2 n ) - eller mera allmänt O(C n ), där c är någon konstant. Dessa algoritmer kallas exponentiella. De är praktiskt omöjliga att exevera (intractable, infeasible) annat än på mycket små värden på n. I praktiken utnyttjar man enklare algoritmen som ger en tillräckligt bra lösning även om den inte är optimal, ex. schackalgoritmer. Introduktion till datateknik/cs3, A. Soini 9
Comparing rates of growth - en jämförelse av algoritmernas effektivitet och tidsförbrukning (efter Dale & Lilly: Pascal Plus Data Structures) N log 2 N Nlog 2 N N 2 N 3 2 N 1 0 1 1 1 2 2 1 2 4 8 4 4 2 8 16 64 16 8 3 24 64 512 256 16 4 64 256 4096 65536 32 5 160 1024 32768 4294967296 64 6 384 4096 262144 128 7 896 16384 2097152 ca. ett år på en superdator? 256 8 2048 65536 16777216 Don t ask! ca. 300 000 gånger universumets ålder (med 13.6 miljarder års estimering Introduktion till datateknik/cs3, A. Soini 10