DAB752: Algoritmteori Leif Grönqvist Graduate School of Language Technology (GSLT) Växjö universitet, MSI Göteborgs universitet, Institutionen för lingvistik Algoritmteori
Lärare på kursen och upplägg Maria Karlsson (moment 3 och 5, kursansvarig) maria.karlsson@msi.vxu.se Leif Grönqvist (moment 1 och 2) leif.gronqvist@msi.vxu.se Niklas Pettersson (moment 4 och 6) niklas.pettersson@msi.vxu.se Föreläsningar, övningar för varje moment 3 laborationer Tentamen Titta på webbsidan regelbundet! Algoritmteori
Algoritmer – vadå? Vad är en algoritm? Exempel: sortering av heltal En väldefinierad beräkningsprocedur som givet vissa indata ger utdata Enligt vissa: den terminerar alltid Exempel: sortering av heltal Indata: t1, t2, …, tn, där t1, t2, …, tn är heltal Utdata: samma uppsättning heltal permuterade så att de är sorterade En algoritm är korrekt om den terminerar med korrekt svar för varje korrekt indata Den är inkorrekt om den antingen: Ger fel svar för vissa indata Inte terminerar för vissa indata Algoritmteori
Kan alla problem lösas med algoritmer? Några exempel på program som inte är algoritmer: Microsoft Word: innehåller en massa delar som innehåller algoritmer, men Word som helhet uppfyller inte kraven Slumptalsgenerator: kan ses som en algoritm om man ser till hela sekvensen av utdata givet indata I form av ett frö, men inte annars Observera att även ineffektiva program kan vara algoritmer, exempel: slumpsortering Det finns alltså algoritmer som inte är praktiskt användbara! Men också program som inte är algoritmer men trots det användbara Algoritmteori
Behövs algoritmer? Vissa typer av teknologi verkar vara oberoende av algoritmer: Hårdvara Grafiska gränssnitt Nätverkskommunikation Fel! Dessa är exempel på saker som är mycket starkt beroende av effektiva algoritmer Algoritmteori
“Hårda” problem Det finns problem som inte kan lösas med effektiva algoritmer: NP-kompletta problem De kan inte lösa på polynomiell tid Effektiva algoritmer kan finnas för vissa indata Bra att känna till eftersom man kan undvika det onödiga arbetet att hitta en effektiv algoritm om problemet är NP-komplett Exempel: handelsresandeproblemet Mer om detta kommer senare i kursen Obs! Det är ej bevisat att det inte går att skriva en algoritm som effektivt löser ett NP-komplett problem Det är däremot bevisat att om man lyckas skriva en algoritm som löser ett NP-komplett problem på polynomtid så kan samtliga andra också lösas på polynomtid Algoritmteori
Effektivitet Effektivitet för datorprogram handlar om minnes- respektive tidseffektivitet Ofta kallas detta för algoritmens komplexitet och den man räknar mest på är tidskomplexiteten En långsam dator med en bra algoritm kan vara snabbare än en snabb dator och en dålig algoritm! Exempel: Algoritm #1 tar en (naturlig logaritm) Algoritm #2 tar 1000n2, n är storleken på indata För vilket minsta n>0 tar #2 kortare tid än #1? Svårt att räkna på men testning ger n=12 Omskrivning av en=1000n2 till n = ln 1000 + 2 ln n gör det möjligt att iterera fram svaret: ni+1 = ln 1000 + 2 ln ni Algoritmteori
Tidskomplexitet – Asymptotisk notation Ofta är det svårt att beräkna den exakta tidsåtgången för en algoritm som funktion av indata Värstafallskörtiden som funktion av storleken på indata betecknas med T(n) Enklare, och mer användbart, är att beräkna hur tiden växer med indata Hur mycket längre tid tar dubbla mängden indata? Beskrivs med Ordo- (O), Omega- (Ω) och Thäta-notation (Θ) Algoritmteori
Ordo (O), Omega (Ω) och Thäta (Θ) f(n) = Θ(g(n)) om: n0, c1, c2: n>n0 : c1g(n) ≤ f(n) ≤ c2g(n), c1, c2 >0.0 Exempel: Antag att tidsåtgången som funktion av indata (n) är f(n)=n2+5n Om c1 =1, c2 =2, n0=5 och g(n)=n2 Så ser vi att f(n)= Θ(n2) eftersom: 1n2 ≤ n2+5n ≤ 2n2 då n>5 Så vi har en övre och undre begränsning av tidsåtgången då indata är tillräckligt stort Algoritmteori
Ordo (O) och Omega (Ω) Θ gav både en undre och övre begränsning (asymptotiskt tajt) Ω en undre begränsning: f(n) = O(g(n)) om: n0, c1: n>n0 : c1g(n) ≤ f(n) O ger en övre begränsning: n0, c2: n>n0 : f(n) ≤ c2g(n) O(g(n)) betecknar en mängd av funktioner så: f(n) = O(g(n)) är ett förenklat skrivsätt av: f(n)O(g(n)) Θ(g(n)) O(g(n)) och Θ(g(n)) Ω(g(n)) Ett annat skrivsätt är: f(n) + Θ(g(n)) = Θ(h(n)) som betyder att: g’(n) Θ(g(n)) h’(n) Θ(h(n)) så att f(n)+g’(n) = h’(n) Exempelvis så är 2n2+Θ(n) = Θ(n2) Algoritmteori
Mer om O, Ω och Θ Ofta förekommer notationen O(n2) när man i själva verket menar Θ(n2) Algoritmer kan ibland gå väldigt olika fort beroende på indata, ta exempelvis insättningssortering: För vissa indata är f(n)=c1n För andra är f(n)=c2n2 Alltså är Ω(f(n))=n och O(f(n))=n2 Därför brukar man tala om medel- respektive värstafallskomplexitet Båda dessa är Θ(n2) för insättningssortering Algoritmteori
o och ω Om f(n)=O(g(n)) gäller men inte är “tajt” så skriver vi f(n)=o(g(n)) Skillnaden mellan O(g(n)) och o(g(n)) är att det i O-fallet skulle gå att hitta konstanter c och n0 så att n>n0 : f(n) ≤ c2g(n) För o-fallet skall olikheten gälla för alla konstanter c>0 vilket också kan uttryckas som: lim n f(n)/g(n) = 0 Exempelvis gäller: 2n=o(n2) 5+n log n=(n3) Men inte: 2n2=o(n2) På samma sätt är f(n)=ω(g(n)) om f(n)=Ω(g(n)) gäller men är icke-tajt: n0 : n>n0,c>0 lim n f(n)/g(n) = Algoritmteori
O, Ω, Θ, o och ω Det finns en hel del regler som kan underlätta beräkning av dem: De är transitiva, exempelvis: f(n)= Θ(g(n)) och g(n)= Θ(h(n)) f(n)= Θ(h(n)) f(n)= ω(g(n)) och g(n)= ω(h(n)) f(n)= ω(h(n)) osv. Reflexivitet: f(n)=Θ(f(n)), f(n)= Ω(f(n)), f(n)= O(f(n)) Gäller INTE o och ω Symmetri: f(n)=Θ(g(n)) omm g(n)=Θ(f(n)) Algoritmteori
O, Ω, Θ, o och ω, forts. Mer symmetri f(n)=O(g(n)) omm g(n)= Ω(f(n)) f(n)=o(g(n)) omm g(n)= ω(f(n)) Tänk på analogin med tal där a svarar mot f(n) och b mot g(n): f(n)= O(g(n)) ≈ a ≤ b f(n)= Ω(g(n)) ≈ a ≥ b f(n)= Θ(g(n)) ≈ a = b f(n)= o(g(n)) ≈ a < b f(n)= ω(g(n)) ≈ a > b Algoritmteori
Exempel på komplexitet Vad är O och Ω samt Θ i medelfallet för: Linjär sökning av en vektor f(n) = Ω(1), f(n) = O(n), fm(n)=Θ(n) Binärsökning av en vektor f(n) = Ω(1), f(n) = O(log n), fm(n) = Θ(log n) Insättning i en länkad lista f(n) = Ω(1), f(n) = O(1), fm(n) = Θ(1) Algoritmteori
Matematik vi behöver – borde vara repetition, annars läs 3.2 En funktion f(n) växer monotont om m≤n f(m)≤f(n) avtar monotont om m≤n f(m)≥f(n) är strängt växande om m<n f(m)<f(n) är strängt avtagande om m<n f(m)>f(n) Avrundning uppåt och nedåt: floor(x), ceiling(x) floor(x/2)+ceiling(x/2) = n a mod n = a – n floor(a/n), mod är alltså resten vid division Algoritmteori
Mer matematik Polynom och fakultet (!) vet ni vad det är… Exponenter, för reella tal a>0, n, m gäller: a0=1 a1=a a-1=1/a (am)n=(an)m=amn anam=am+n Om a, n≥1 så växer an monotont Algoritmteori
Ännu mer matematik För a>1 och b gäller lim n nb/an = 0 Alltså gäller: nb = o(an) dvs. varje exponentiell funktion med bas större än 1 växer snabbare än varje polynom ex kan skrivas som en oändlig serie: ex = 1 + x + x2/2! + x3/3! + x4/4!+… Ur definitionen följer att ex ≥ 1+x Då x 0 gäller: ex = 1 + x + Θ(x2) så: lim n (1+x/n)n = ex Algoritmteori
Logaritmer Lite notation: lg n = log2 n ln n = loge n lgk n = (lg n)k lg lg n = lg(lg n) För reella tal a,b,c>0 samt n gäller då basen1: a = blogba log(ab) = log a + log b log (an) = n log a logb a = logc a / logc a -log (1/a) = log a logb a = 1/loga b Dessa verifieras enkelt med miniräknare – lär inte in utantill! Algoritmteori