Mattematisk bevismetode
P(n):=pa˚stand for et gitt heltall n
P(0)
P(k−1)⇒P(k)
Mattematisk bevismetode
P(n):=pa˚stand for et gitt heltall n
P(0)
P(k−1)⇒P(k)
Vi har bevist
Grunntilfelle
P(0)
Induktivt steg
P(k−1)⇒P(k)
Sum av oddetall
P(n):=summen av de første n oddetallene=n2
i=1∑n2i−1=n2
altså prøver vi å si at:
1+3+5+⋯+(2n−1)=n2
Sum av oddetall (cont.)
P(n):=summen av de første n oddetallene=n2
P(0):=summen av de første 0 oddetallene=02
Sum av oddetall (cont.)
P(n):=summen av de første n oddetallene=n2
Vi antar at P(k−1) er sant. Dette kalles induksjonshypotesen.
Vi skal vise at det medfører P(k).
summen av de første k−1 oddetallene=(k−1)2
summen av de første k oddetallene=(k−1)2+(2k−1)
summen av de første k oddetallene=k2
P(k)
Sum av oddetall (cont.)
P(n):=summen av de første n oddetallene=n2
Vi har nå bevist P(n) ∀n∈N
Hva har induksjon med algoritmer å gjøre?
Domenet til en algoritme er mengden med gyldige input-instanser.
MAKS(LISTE):Det største tallet i LISTE
P(n):=MAKS(LISTE) gir største elementet i en liste med n elementer.
Induksjonsbevis for at MAKS(LISTE) er korrekt
P(n):=MAKS(LISTE) gir største elementet i en liste med n elementer.
MAKS(LISTE[1:k−1])
LISTE[k]
Implementasjon av MAKS(LISTE)
def maks(liste): if len(liste) == 1: return liste[0] delinstans = liste[0:-1] # Hele listen unntatt siste element delløsning = maks(delinstans) if delløsning > liste[-1]: return delløsning else: return liste[-1]
def maks(liste): if len(liste) == 1: return liste[0] delinstans = liste[0:-1] # Hele listen unntatt siste element delløsning = maks(delinstans) if delløsning > liste[-1]: return delløsning else: return liste[-1]
Denne gangen for delinstanser
MAKS(LISTE) med konstant minnebruk!
def maks(liste): storst = float("-inf") for tall in liste: if tall > storst: storst = tall return storst
def maks(liste): storst = float("-inf") for tall in liste: if tall > storst: storst = tall return storst
Hvordan formalisere dette?
Hvor mye jobb gjør rekursjonen?
Et kall til MAKS(LISTE) gjør:
Hvis LISTE bare har ett element:
T(1)T(n)=1=T(n−1)+1
Fra eksamen August 2021
Dette er i praksis induksjon igjen
Fint nå én T(n) blir til mange
Vi har en rekkurens på formen
T(n)=aT(n/b)+f(n)
Avhengig av hvordan f(n) ser ut får vi en av følgende:
f(n) | T(n) |
---|---|
O(nlogba−ϵ) | Θ(nlogba) |
Θ(nlogba) | Θ(nlogba⋅logbn) |
Ω(nlogba+ϵ) | Θ(f(n)) |
Eksamen desember 2018
Vi bryr oss bare om hva som skjer når n blir stor
Uttales "store O", "store Omega" og "store Theta"
O(g(n)) - mengden funksjoner som vokser ≤c⋅g(n)
Ω(g(n)) - mengden funksjoner som vokser ≥c⋅g(n)
Θ(g(n))≡O(g(n))∩Ω(g(n))
n+4log(n)=O(n2)
En øvre grense
f(n)=O(g(n))⇔ f(n)≤C⋅g(n), ∀n∈[n0,∞)
n3n23n2+n+4=O(n2)=O(n2)=O(n2)
Grenseverdier anyone?
f(n)=O(g(n)) ⇔ n→∞limg(n)f(n)<∞
Grenseverdien er en "kamp" mellom teller og nevner.
Hvis f(n) går raskest mot ∞ vil brøken gå til ∞.
Hvis g(n) går raskest mot ∞ vil brøken gå mot 0.
Hvis de er asymptotisk "like" vil brøken konvergere mot et tall C>0.
Også viktige!
f(n)=O(g(n)) | g(n)=O(f(n)) | Ekvivalent med |
---|---|---|
Ja | Nei | f(n)=o(g(n)) |
Ja | f(n)=Ω(g(n)) | |
Nei | Ja | f(n)=ω(g(n)) |
Ja | Ja | f(n)=Θ(g(n)) |
1log(n)logk(n)nnnlognnknkan=o(log(n))=o(log2(n))=o(n),∀k=o(n)=o(nlogn)=o(n2)=o(nk+ϵ), ∀k=o(an),∀k,a=o(n!), ∀a
4n2+3nlogn+1000nn3=o(n2n)=o(n4+n2+n)
Den populære storebroren
Hvis f(n)=o(g(n)), medfører det automatisk f(n)=O(g(n)).
4n3+5n2−10n+72n(n−1)4nlog2(n)+5log2(n)=O(n3)=O(n2)=O(nlog2(n))=O(n2)
Motsatt av de forrige
Rett og slett bare det motsatte av henholdsvis o og O.
hva som helst positivtn2n2n2+nn6n2=Ω(1)=Ω(n2)=Ω(n2+n)=Ω(n2)=ω(n2)=ω(nlog(n))
Når de er like
Hvis f(n)=O(g(n)) og f(n)=Ω(g(n)), er de asymptotisk like.
⇒f(n)=Θ(g(n))
C1⋅g(n) er en øvre grense, C2⋅g(n) er en nedre grense for f(n).
3n2+3n+lognn2log2(n)=Θ(n2)=Θ(3n2+3n+logn)=Θ(log10(n))
Attentat på notasjon
Når vi skriver disse symbolene på venstre side, betyr det noe nytt!
O(n2)+nO(n2)+nO(n2)+nO(n2)+nO(n2)+n=O(n2)=o(n3)=Ω(n)=O(n2)+Ω(n)=ω(1)
Uansett hva vi setter inn på venstresiden, må det finnes noe å sette på høyresiden
Øving 1 oppgave 9
Øving 1 oppgave 10
Eksamen Desember 2017, 2b
De er ikke det samme!
o,O,Θ,Ω,ω er matematisk asymptotisk notasjon.
Vi går fort gjennom
Først inn, sist ut
Først inn, først ut
Følg pekerne
Kobling mellom nøkkel og tabell-plassering
Indirekte kobling mellom nøkkel og tabell-plassering
Med kjeding av kollisjoner
Så lenge det ikke skjer så ofte går det fint!
j er lengden på den lengste kjeden.
Hvis h(k) er god, er j≃mn(⋅2)
Hvis vi øker n slik at j holdes under e.g. 10
Blir lookup O(j)=O(1).
Men! Det koster å resize! Θ(n+m)
Det samme gjelder for dynamiske tabeller
Vi ønsker en tabell som alltid har plass til mer.
Sett av plass til n elementer.
De første n TABLE-INSERT blir O(1).
Når det er fullt, øk n med en faktor 2. Dette koster O(2n)=O(n).
Til gjengjeld er det n ARRAY-INSERT til neste gang.
TABLE-INSERT er amortisert O(1).
Eksamen desember 2018
Funker fjell for små tabeller
Sorterer de første k elementene i lista, fra k=1 opp til k=n.
Gjør dette ved å swappe element k ned dit den skal, for hver k.
Best case: Θ(n)
Worst case: Θ(n2)
Average case: Θ(n2)
Eksamen august 2018
2 Hva er kjøretiden til INSERTION-SORT på en sortert tabell
Splitt og hersk!
Del listen i to. Løs hver delinstans for seg.
Flett sammen de to sorterte listene.
Best case: Θ(nlogn)
Worst case: Θ(nlogn)
Average case: Θ(nlogn)
Eksamen august 2018
11 . Hvordan kan vi si at MERGE-SORT er optimal? Forklar.
Rask, men med en hake
Velg et element som pivot.
Bruk PARTITION(liste, pivot). Θ(n)
Dette deler lista inn i to deler, adskilt av pivot.
[a,b,c…]≤[pivot]≤[x,y,z,…]
Nå vet vi at pivot er på rett plass. Sorter hver av sidene for seg.
Hvis vi er heldige (som regel) er listen delt omtrent i 2.
T(n)≃2T(n/2)+n
Vi er uheldige om vi velger en veldig høy eller lav pivot.
Kryss fingrene
Hindrer oss fra å ha "slemme" inputs.
QUICKSORT: alltid ta bakerste som pivot
RANDOMIZED-QUICKSORT:
Best case: Θ(nlogn)
Worst case: Θ(n2)
Forventet kjøretid: Θ(nlogn)
Navn | Best case | Worst case | Average | In place? |
---|---|---|---|---|
Insertion sort | Θ(n) | Θ(n2) | Θ(n2) | Ja! |
Merge sort | Θ(nlogn) | Θ(nlogn) | Θ(nlogn) | Nei |
Quicksort | Θ(nlogn) | Θ(n2) | Θ(nlogn)[1] | ja |
[1]: Vi bruker ordet forventet, ikke gjennomsnittlig, når det er randomized
Eksamen november 2020
Bedre enn Θ(nlogn) sier du?
Hvis den eneste operasjonen vår er (a<b)?, vil gjennomsnittlig kjøretid alltid være Ω(nlogn).
RANDOMIZED-SELECT
Det er mulig å finne det k minste elementet på forventet Θ(n) tid.
Bruker PARTITION fra quicksort, men ser bare på én av resultatlistene.
Worst case fortsatt Θ(n2).
Kan telle hver mulige verdi for seg
Tabellen som skal sorteres har k mulige verdier.
Vi kan lage en tabell av lengde k for å telle forekomster av hver.
Etterpå bruker vi denne tabellen for å finne intervallene til hver verdi.
Vi kan gjøre stabil sortering
Kjøretid alltid Θ(n+k).
Tallene våre har begrenset antall siffer
Sorter et siffer av gangen, for alle d siffer.
Begynn med de minst signifikante sifferne.
Krever at hvert siffer sorteres stabilt.
Til gjengjeld har hvert siffer k mulige verdier.
COUNTING-SORT fungerer altså utmerket!
Kjøretid Θ(d⋅(n+k))
Verdier uniformt fordelt
Fungerer bare når alle verdiene er uniformt fordelt i [0,1).
For n tall, del intervallet [0,1) inn i n bøtter.
Legg hvert tall i riktig bøtte.
Mange bøtter blir tomme, noen får flere tall.
Sorter hver bøtte for seg med INSERTION-SORT.
Veldig usannsynlig om en av bøttene har feks 10 elementer.
Hver bøtte-sortering blir derfor konstant tid O(1)
Gjennomsnittlig kjøretid Θ(n). Worst case Θ(n2)
Eksamen desember 2016
Tegnet av folk som aldri har vært i skogen
På toppen har vi en rot.
roten har kanter new til barn-nodene sine.
Alle noder som ikke er rot har en forelder.
Noder uten barn kalles løvnoder.
Avstanden fra roten kalles dybde.
I et posisjonstre har hvert barn en posisjon i forelderen.
Et binæretre har to posisjoner per node. Venstre og høyre
Pent og symmetrisk
Når alle løvnodene i et binærtre er på samme dybde h.
Antall løvnoder blir 2h.
Antall interne noder blir 2h−1
Antall noder totalt n=2h+1−1
Finn frem fort!
Høyre subtre har kun høyere verdier.
En INORDER-WALK gir tallene i stigende rekkefølge.
SEARCH(k) finner k på O(logn) tid.
INSERT(k) setter inn noden k på riktig sted. O(logn).
Størst først
Et binærtre der alle interne noder er større enn barna sine.
Høyden er garantert Θ(logn).
MAX-HEAPIFY(i) - swapper verdien på plass i nedover til den sitter.
BUILD-MAX-HEAP(i) - gjør en vilkårlig liste med tall om til en heap.
Jeppsi
Lurt å bruke en maks-haug
HEAP-EXTRACT-MAX() - henter ut det største tallet
HEAP-INCREASE-KEY(i, value) - øker verdien til node i
MAX-HEAP-INSERT(value) - setter inn en ny node med verdi
Kjekt å ha
Alltid plukk det største
Bruk BUILD-MAX_HEAP på listen med tall. Θ(n)
Bruk HEAP-EXTRACT-MAX og sett maks bakerst. n⋅O(logn)
Heapen blir mindre og mindre, til slutt er alt sortert.
Kjøretid: Θ(nlogn). In-place!!
Det er lov å kalle det DP!
Optimal delestruktur: Det finnes en optimal løsning bestående av delløsninger
Overlappende delproblemer: Vi er avhengig av samme delproblem flere ganger
Eksamen november 2020
Krabbemusikk har veldig rar rytme. Musikken er delt inn i n strofer, der hver strofe har lengde li slag (0≤i≤n).
Når en strofe spiller, kan krabben enten gå til høyre eller venstre, eller stå stille.
Men: krabben må gå samme retning hele strofen. Én rute per slag i strofen.
Dansescenen er k ruter bred. Krabben starter i rute 0.
Krabben har lyst til å bevege seg flest mulig av strofene. Krabben kan ikke bevege seg utenfor scenen. Hvordan blir dansen?