Presentasjon lastes. Vennligst vent

Presentasjon lastes. Vennligst vent

Kompleksitetsanalyse

Liknende presentasjoner


Presentasjon om: "Kompleksitetsanalyse"— Utskrift av presentasjonen:

1 Kompleksitetsanalyse
:: Kompleksitetsanalyse Åsmund Eldhuset asmunde *at* stud.ntnu.no

2 Motivasjon Vi ønsker å måle hvor rask en algoritme er
:: Motivasjon Vi ønsker å måle hvor rask en algoritme er Lite mening i å måle kjøretid i sekunder Forskjeller i programmeringsspråk og maskinvare Kjøretiden kan variere drastisk med dataene algoritmen blir brukt på Datamaskiner blir kraftigere, og algoritmer vil bli brukt på større data Hvordan ser kjøretiden ut når inputstørrelsen nærmer seg uendelig?

3 :: Analyse Vi trenger et matematisk uttrykk for hva kjøretiden blir, gitt inputstørrelsen – altså tiden som en funksjon av inputstørrelsen Vi analyserer trinnene i algoritmen for (i = 0; i < n; i ++) doSomething(); for (i = 0; i < n; i ++) for (j = 0; j < n; j ++) doSomethingElse(); Kjøretid: f(n) = c1 · n + c2 · n2, hvor c1 er kjøretiden til doSomething(), og c2 er kjøretiden til doSomethingElse()

4 Største ledd c1 og c2 kommer an på maskinvaren
:: Største ledd c1 og c2 kommer an på maskinvaren La oss anta at c1 = 2 og c2 = 100 Når bare n blir stor nok (n > 200), blir 2n2 større enn 100n, og når n vokser mer og mer, blir 2n2 MYE større enn 100n Kun det største leddet (2n2) er interessant, fordi dette leddet vil dominere de andre når n blir stor nok Siden konstanten foran n2 kan variere fra maskin til maskin, kutter vi ut den også Ignorerer derfor c1 og c2 fordi de er vanskelige å regne ut og avhenger av teknologi (maskinvare og språk). La oss for eksempelets skyld si at vi har klart å måle disse. Konstantledd foran er altså uinteressante, både fordi de endrer seg med teknologien, og fordi de ikke hjelper små ledd til å vinne over store ledd når n blir stor

5 -notasjon Hvordan uttrykke dette? Vi sier at 2n2 + 100n = (n2)
:: -notasjon Hvordan uttrykke dette? Vi sier at 2n n = (n2) Viktig:  er en mengde! (n2) består av alle funksjoner som vokser ”like raskt” som n2 når n går mot uendelig Likhetstegnet misbrukes – det skulle egentlig ha vært f(n)  (g(n)) f(n) = (g(n)) betyr altså: ”f(n) er en av de funksjonene som vokser like raskt som g(n)” Vi trenger nå en måte å uttrykke at n^2 er den viktigste delen av funksjonen vår – til dette bruker vi Theta-notasjon. En forenklet forklaring er at Theta(n^2) er en mengde av alle funksjoner som har n^2 som det dominerende leddet. Eksempler på dette er n^2, 100n^2 – 1000 og n^2 + n + 1. n eller n^3 er IKKE med i Theta(n^2) ”vokser like raskt som” er en forenkling. Nå vil vi ta den formelle definisjonen, som (i dette eksempelet) går på at n^2 kan brukes som en grense for n^ n Grunnen til misbruket er at Theta(n^2) leses som ”en eller annen funksjon som har n^2 som dominerende ledd”. Man kan f.eks si h(n) = n^3 + Theta(n^2)

6 :: Definisjon (g(n)) = {f(n) : det finnes positive konstanter c1, c2 og n0 slik at 0  c1g(n)  f(n)  c2g(n) for alle n  n0} Altså: (g(n)) består av alle funksjoner som g(n) kan brukes som både øvre og nedre grense for Hvis vi skal vise at f(n) = (g(n)), må vi bevise ulikhetene og finne c1, c2 og n0 Nå skal vi ta den formelle definisjonen. Konseptet er at en funksjon skal kunne brukes til å ”sperre inne” en annen. Hvis vi bare ganger g med en passe liten faktor, vil den holde seg under f, men hvis vi ganger den med en passe stor faktor, vil den holde seg over f. g skal altså kunne ligge og ”vokte” f på begge sider.

7 Eksempel – polynomer Gitt f(n) = n3 – 100n2 + n
:: Eksempel – polynomer Gitt f(n) = n3 – 100n2 + n Vi trikser med leddene: f(n) = n3 – 100n2 + n  n3 + n  n3 + n3 = 2n3 f(n) = n3 – 100n2 + n  n3 – n3 / 2 + n  n3 / 2 Vi finner ut når overgangene gjelder: –100n2  0 : uansett n  n3 : for n  1 –100n2  –n3 / 2 : for n  200 n  0 : for n  0 Altså kan vi sette n0 = 200 Vi ser at det er n^3 som er det dominerende leddet her, og at f(n) derfor er Theta(n^3). Men vi kan bli bedt om å vise det formelt, og da må vi gjøre som følger. Merk nå at dette her hadde funket om det så stod foran n^2 – det gjelder bare å velge n_0 stor nok

8 :: Eksempel – polynomer Nå vet vi at 0  n3 / 2  f(n)  2n3 når n > n0 = 200 Vi kan nå sette c1 = ½, c2 = 2 og g(n) = n3 Kravene for at f(n) = (g(n)) er oppfylt Altså er n3 – 100n2 + n = (n3) Grunnen til at vi ikke kan bytte ut –100n^2 med –100n^3 er at da blir uttrykket negativt, og det er ikke lov

9 Grafisk fremstilling 2n3 n3 – 100n2 + n n3 / 2 ::
Grenser: n=100, n=200, n=400, n = For små datasett er det –100n^2 som dominerer kjøretiden.

10 Grafisk fremstilling 2n3 n3 – 100n2 + n n3 / 2 ::
Grenser: n=100, n=200, n=400, n = For små datasett er det –100n^2 som dominerer kjøretiden.

11 Grafisk fremstilling 2n3 n3 – 100n2 + n n3 / 2 ::
Grenser: n=100, n=200, n=400, n = For små datasett er det –100n^2 som dominerer kjøretiden.

12 Grafisk fremstilling 2n3 n3 – 100n2 + n n3 / 2 ::
Grenser: n=100, n=200, n=400, n = For små datasett er det –100n^2 som dominerer kjøretiden.

13 :: O - og -notasjon f(n) = (g(n)) sier at g er både en øvre og en nedre grense for f Hvis vi bare vil si at g er en øvre grense for f, bruker vi O-notasjon: f(n) = O(g(n)) Hvis vi bare vil si at g er en nedre grense for f, bruker vi -notasjon: f(n) = (g(n)) Disse grensene er ikke tette: f.eks er n = O(2n), og n100 = (n) Se Cormen kap. 3.1 for definisjoner. Regning med O og  er helt tilsvarende det vi gjorde med 

14 Relasjoner mellom O,  og 
:: Relasjoner mellom O,  og  f(n) = O(g(n))  g(n) = (f(n)) f(n) = (g(n))  f(n) = O(g(n))  f(n) = (g(n)) f(n) = (g(n))  g(n) = (f(n))  (f(n)) = (g(n)) (f(n)) = O(f(n))  (f(n) Se side 49 i Cormen for nyttige relasjoner Prøv å bevise disse selv! Bruk definisjonene av O (side 44),  (side 45) og  (side 42) er ganske logisk – hvis g er en øvre grense for f, bør jo f være en nedre grense for g (2) ser vi fordi Theta både er en øvre og nedre grense; dermed bør den kunne oppnås ved å kreve både O og Omega (3) oppnås ved å bruke (1) på (2). Merk at den siste delen sier at de to mengdene er like. (4) er i praksis det samme som (2) De to siste uttrykkene er likheter mellom mengder.

15 Kompleksitetsklasser
:: Kompleksitetsklasser Grovinndeling i stigende rekkefølge: Konstant: 1 Polylogaritmisk: (logb n)k Polynomisk: nk Eksponentiell: 2n Faktoriell: n! Alt som er enda verre, f.eks. nn ALLE polynomer med k > 0 vokser raskere enn polylogaritmer ALLE eksponentialfunksjoner med gruntall > 1 vokser raskere enn polynomer

16 Kompleksitetsklasser
:: Kompleksitetsklasser Eksempler – alle på samme linje er ”like raske” (de er  av hverandre) 1, 2, e, lg n, ln n, log10 n, lg n100 (lg n)2, (ln n)2, (log10 n)2, (lg n100)2 n, n lg n n lg n, n log42 n n2 2n 3n n! nn Uansett hvor stor en konstant er, har det ikke noe å si Grunntallet til en logaritme har ikke noe å si Hva logaritmer er opphøyd i har betydning Konstanter foran eller langsommere ledd har ikke noe å si Vær så snill å passe på at i produkter kan man IKKE stryke langsommere ledd!

17 :: Fallgruver Grunntallet til en logaritme har ikke noe å si for kompleksiteten: lga n = (lgb n) Grunntallet til en potens har mye å si for kompleksiteten: an  (bn) Er 2n + c = (2n)? Er 2cn = (2n)? Vær forsiktig med transitivitet: Følgende er korrekt: f(n) = O(g(n))  g(n) = O(h(n))  f(n) = O(h(n)) Men kan vi slutte noe av det følgende? f(n) = O(g(n))  g(n) = (h(n)) (2) med mindre a = b, naturligvis... (3) 2^(n+c)=2^c * 2^n, 2^(cn) = (2^c)^n (4) nei; g kan være hva som helst som er >= h, og f kan være hva som helst som er <= g, så f kan godt være < h

18 Fallgruver Ikke alle funksjoner kan sammenlignes med O,  og 
:: Fallgruver Ikke alle funksjoner kan sammenlignes med O,  og  Eksempel: n og n1 + sin n 1 + sin n oscillerer mellom 0 og 2, så n1 + sin n veksler hele tiden mellom å være større enn og mindre enn n O angir en mengde funksjoner Det er ikke i seg selv et mål på worst case-kjøretid, selv om det ofte brukes til å angi dette Å si ”kjøretiden er minst O(n)” er meningsløst Det samme gjelder for  og best case-kjøretid Spør folk om n^2 kan sammenlignes med n^(2 sin n) (ja, n^(2 sin n) = O(n^2)) O(g(n)) angir ikke worst case-kjøretid, men den sier noe om en hvilken som helst slags kjøretid. Kan godt si at best-case-kjøretiden er f.eks. O(n^2) – da sier du at kjøretiden i beste tilfelle er en eller annen funksjon som ikke vokser raskere enn n^2

19 Fallgruver O,  og  er rent matematiske konsepter
:: Fallgruver O,  og  er rent matematiske konsepter De beskriver funksjoner, og bryr seg ikke om hva funksjonene representerer Derfor: O er ikke knyttet til worst case,  er ikke knyttet til best case, og  er ikke knyttet til algoritmer hvor worst case = best case Men: O brukes ofte for å angi kjøretiden i worst case, og  brukes ofte for best case Merk at hvis en algoritme er O(f(n)) i worst case og (g(n)) i best case, er algoritmen O(f(n)) og (g(n)) i alle tilfeller

20 Pseudopolynomialitet
:: Pseudopolynomialitet Gitt en algoritme som tar tallet n som input og har kjøretid O(n) – hvilken kompleksitetsklasse er dette? n betegner her ikke størrelsen på input, men er selv en del av inputen Størrelsen til n = antall bits som kreves = lg n n = 2lg n = 2w Oi sann – eksponentiell kjøretid! Dukker ofte opp som lureoppgave på eksamen! Vær altså veldig obs på om et tall angir antall elementer i inputen, eller er en del av inputen selv!

21 Pseudopolynomialitet
:: Pseudopolynomialitet Merk: omskrivningen på forrige side (n = 2lg n) er det alltid lov å foreta – spørsmålet er bare hvilken form som er mest hensiktsmessig: Hvis n faktisk beskriver inputstørrelsen, bør uttrykket baseres på n Hvis n er et tall som er en del av input, bør uttrykket baseres på lg n Eksempel fra eksamen 2006: En algoritme for å sjekke om tallet n er et primtall kjører på Theta(lg n). Er dette subpolynomisk? Nei, siden inputstørrelsen er lg n, så dette er en lineær kjøretid ifht. inputstørrelsen Vær altså veldig obs på om et tall angir antall elementer i inputen, eller er en del av inputen selv!

22 Pseudopolynomialitet
:: Pseudopolynomialitet Til de oppvakte som sier "men en talliste av lengde n består jo av tallene a1, a2, ..., an – bør ikke størrelsen på disse tallene tas med i beregningen?" Bra observasjon! Strengt tatt burde de det, men det hadde ført til ekstremt tungvindte uttrykk I alle situasjoner vi vil komme borti vil vi anta at alle tallene i en liste er av begrenset størrelse (typisk 32 bit) og således opptar konstant plass Vær altså veldig obs på om et tall angir antall elementer i inputen, eller er en del av inputen selv!

23 Hvordan velge algoritme?
Analyser algoritmene du vurderer å bruke Finn ut hvordan inputen din forventes å være (vil det oftest være best case, average case eller worst case?) Hvor stor forventes inputen å være? Vil den være så liten at konstantleddene blir viktige? (I sortering går man ofte over til insertion sort når listene er små nok.) Har du råd til worst case-kjøretiden? (dette har du ikke alltid i real-time-applikasjoner)


Laste ned ppt "Kompleksitetsanalyse"

Liknende presentasjoner


Annonser fra Google