Analyse av Algoritmer Lars Vidar Magnusson 10.1.2014 Asymptotisk notasjon (kapittel 3) Kompleksitetsklasser Uløselige problem
Asymptotisk Notasjon Asymptotisk analyse innebærer å finne en algoritmes kjøretid for store nok inputstørrelser til å gjøre alt annet enn algoritmens order of growth neglisjerbart. Asymptotisk notasjon benyttes for å antyde en algoritmes kjøretid når inputstørrelsen blir stor nok. Navnet kommer fra det faktum at vi ser på grenser.
Θ-Notasjon Definisjon Gitt en funksjon g(n) så er Θ(g(n)) et sett av funksjoner Θ(g(n)) = {f (n) : det finnes positive konstanter c 1, c 2 og n 0 slik at 0 c 1 g(n) f (n) c 2 g(n) for alle n > n 0 } Siden Θ(g(n)) er et sett er det vanlig å skrive f (n) Θ(g(n)) hvis f (n) er i Θ(g(n)). Når man analyserer algoritmer er det også vanlig med f (n) = Θ(g(n)).
Θ-Notasjon Eksempel Figure : Et eksempel på en funkjson f (n) Θ(g(n))
Θ-Notasjon Vi kan se både i definisjonen av Θ-notasjon og eksempelet på forrige side at hvis f (n) Θ(g(n)) så er f (n) lik g(n) innenfor en konstant faktor. Vi sier at g(n) er en asymptotisk stram grense (asymptotically tight bound) for f (n).
Hvordan Finne Θ(f (n)) Forrige forelesning analyserte vi Insertion-Sort og kom fram til at i hverstefall er algoritmen kvadratisk. Jeg sa at vi kunne neglisjere de lavere-ordens leddene i utregningen av kjøretiden. La oss se på et eksempel som viser at 1 2 n2 3n = Θ(n 2 ). For å gjøre det må vi finne de tre positive konstantene c 1, c 2 og n 0. Dividering med n 2 gir c 1n 2 1 2 n2 3n c 2n 2 n > n 0 c 1 1 2 3 n c2 En løsning på denne ulikheten vil være å sette c 1 = 1/14, c 2 = 1/2 og n 0 = 7.
Hvordan Finne Θ(f (n)) Vi har polynomisk funksjon f (n) = an 2 + bn + c hvor a, b og c er konstanter og a > 0. Ved å neglisjere de lavere-ordens leddene ender vi opp med f (n) = Θ(n 2 ). Formelt kan vi vise at dette stemmer ved å sette c 1 = a/4, c 2 = 7a/4 og n 0 = 2max( b /a, c /a) og sjekke at det oppfyller ulikheten i definisjonen. Generelt kan vi si for alle polynomer p(n) = d i=0 a in i, hvor a i er konstanter og a d > 0, at p(n) = Θ(n d ). Alle konstanter er et 0-ordens polynom, så vi kan si at alle konstanter er Θ(n 0 ) = Θ(1).
Hvordan Finne Θ(f (n)) - Telle Løkker Å finne Θ(f (n)) når f (n) er en enkel algoritme som f.eks Insertion-Sort reduseres oppgaven til å telle løkker. En løkke gjennom hele inputstørrelsen n gir Θ(n) En løkke gjennom halve inputstørrelsen n gir Θ(n) En løkke gjennom hele inputstørrelsen n to ganger gir Θ(n) Forskjeller i konstanter kan neglisjeres! En løkke gjennom hele inputstørrelsen n med en indre løkke gjennom den samme størrelsen gir Θ(n 2 ) En løkke gjennom hele inputstørrelsen n med en indre løkke gjennom den samme størrelsen med en indre løkke gjennom den samme størrelsen gir Θ(n 3 )
Θ(Insertion-Sort) Som vi gikk gjennom forrige forelesning er Insertion-Sort i hverstefall Θ(n 2 ). Vi kan derimot ikke si at Insertion-Sort er Θ(n 2 ) for alle input siden vi vet at i bestefall er algoritmen Θ(n). Å telle løkker vil ofte bare lede til asymptotisk grense for hverstefall input.
O-Notasjon Definisjon Θ-notasjon avgrenser en funksjon både ovenfra og underfra. Når vi bare har en øvre grense benytter vi O-notasjon (big-oh). Vi sier da at vi har en asymptotisk øvre grense. O(g(n)) = {f (n) : det finnes positive konstanter c og n 0 slik at 0 f (n) cg(n) for alle n > n 0 } Hvis f (n) = Θ(g(n)) så er f (n) = O(g(n)) men ikke nødvendigvis omvendt En lineær funksjon f (n) = n er O(n 2 ) men ikke Θ(n 2 ) Θ(g(n)) O(g(n)) O-notasjon er velegnet for å telle løkker siden teknikken egner seg for å finne asymptotisk grense for hverstefall input, og siden O notasjon bare gir en øvre grense i.e. vi finner øvre grense for hverstefall input.
O-Notasjon Eksempel Figure : Et eksempel på en funkjson f (n) O(g(n))
Ω-Notasjon Definisjon Hvor O-notasjon benyttes når vi har en øvre grense, benyttes Ω-notasjon når vi har en nedre grense i.e en asymptotisk nedre grense. O(g(n)) = {f (n) : det finnes positive konstanter c og n 0 slik at 0 cg(n) f (n) for alle n > n 0 } Hvis f (n) = Θ(g(n)) så er f (n) = Ω(g(n)), men ikke nødvendigvis omvendt. En kvadratisk funksjon f (n) = n 2 er Ω(n) men ikke Θ(n) Ω-notasjon egner seg for å gi en nedre grense for kjøretid for alle input i.e. en nedre grense for bestefall input.
Ω-Notasjon Eksempel Figure : Et eksempel på en funkjson f (n) Ω(g(n))
Koblingen Mellom Θ-, O- og Ω-notasjon Vi har allerede sett på koblingen mellom Θ- og O-notasjon, og Θ- og Ω-notasjon. Her kommer et teorem som utfyller det vi allerede har etablert. Teorem For hvilke som helst to funksjoner f (n) og g(n) så har vi f (n) = Θ(n) hvis og bare hvis f (n) = O(g(n)) og f (n) = Ω(g(n)). Dette teoremet kan benyttes for å bevise asymptotisk stram grense.
o-notasjon O-notasjon gir en asymptotisk øvre grense som kan være tett (tight). o-notasjon gir en øvre grense som ikke er tett. o(g(n)) = {f (n) : for alle konstanter c > 0 det finnes en konstant n 0 > 0 slik at 0 f (n) < cg(n) for alle n > n 0 } Holder for alle konstanter c > 0 f (n) blir insignifikant i forhold til g(n) når n går mot uendelig f (n) lim n g(n) = 0
ω-notasjon Ω-notasjon gir en asymptotisk nedre grense som kan være tett (tight). ω-notasjon gir en nedre grense som ikke er tett. ω(g(n)) = {f (n) : for alle konstanter c > 0 det finnes en konstant n 0 > 0 slik at 0 cg(n) < f (n) for alle n > n 0 } Holder for alle konstanter c > 0 g(n) blir insignifikant i forhold til f (n) når n går mot uendelig f (n) lim n g(n) = f (n) ω(g(n)) hvis og bare hvis g(n) o(f (n))
Asymptotisk Notasjon Egenskaper Alle de asymptotiske notasjonene er transitive e.g. f (n) = Θ(g(n)) og g(n) = Θ(h(n)) impliserer f (n) = Θ(h(n)). De tre store er også refleksive e.g. f (n) = Θ(f (n)). Symmetri er mulig på to måter Normal symmetri e.g. f (f ) = Θ(g(n)) hvis og bare hvis g(n) = Θ(f (n)) Transponert symmetri e.g. f (n) = O(g(n)) hvis og bare hvis g(n) = Ω(f (n))
Asymptotisk Notasjon vs Sammenligning Det er vanlig å relatere asymptotisk notasjon til sammenligning mellom flyttall. f (n) = O(g(n)) er som a b f (n) = Ω(g(n)) er som a b f (n) = Θ(g(n)) er som a = b f (n) = o(g(n)) er som a < b f (n) = ω(g(n)) er som a > b
To Siste Lærdomer om Asymptotisk Notasjon For alle reelle tall a og b hvor a > 1 så har vi. n b = o(a n ) Alle polynomiske funksjoner er mindre enn selv den minste eksponensielle. For alle konstanter a > 0 så har vi lg b n = o(n a ) Alle polylogaritmiske funksjoner er mindre enn alle positive polynomiske funksjoner.
Kompleksitetsklasser Kompleksitetsklasser er relatert til asymptotisk notasjon, men her spiller også andre faktorer inn. Figure : Vanlige kompleksitetsklasser satt i et diagram
Kompleksitetsklasser Den uten tvil mest myteomspunnede kompleksitetsklassen er co-np, eller NP-komplette problem. Problem som per i dag ikke har en effektiv algoritme Hvis en effektiv algoritme oppdages vil det samtidig løse alle de andre NP-komplette problemene effektivt også [Cook(1971)]. Vi kommer i dette kurset stort sett bare til å se på problem i den indre oransje sirkelen i.e. problemer som kan løses effektivt. Disse refereres gjerne til som tractable, og de utenfor intractable.
Uløselige Problem Alan Turing er datamaskinenes far. Han definerte lenge før datamaskinene faktisk ble til hvordan en general purpose datamaskin kan fungere (se Turing machines) Ennå mer imponerende er at lenge før maskiner ble til, fant han ut hva datamaskiner aldri kan gjøre [Turing(1936-7)].
Uløselig Problem - Stoppe-problemet Det mest kjente av disse problemen er det såkalte Stoppe-problemet (Halting problem). Given a description of an arbitrary computer program, decide whether the program finishes running or continues to run forever Gitt en algoritme og en input. Vil algoritmen stoppe eller kjøre for alltid? Vanskeligheten ligger i de uendelige mulighetene
Bibliography Stephen A. Cook. The complexity of theorem-proving procedures. In Proceedings of the third annual ACM symposium on Theory of computing, STOC 71, pages 151 158, New York, NY, USA, 1971. ACM. Alan M. Turing. On computable number with an application to the Entscheidugsproblem. Proc. Amer. Math. Soc., 42(2):230 265, 1936-7.