diff --git a/Algoritmer/Grafer/bellman-ford.md b/Algoritmer/Grafer/bellman-ford.md index 00a63d3..5c9cfec 100644 --- a/Algoritmer/Grafer/bellman-ford.md +++ b/Algoritmer/Grafer/bellman-ford.md @@ -54,9 +54,14 @@ Bellman-Ford(G,w,s) ## Styrker og svakheter sammenlignet med andre +\+ Kan oppdage negative sykler + + ## Kjøretid og utregning +$\Theta(V*E)$ + Best case | Average case | Worst case | Minne ---------|----------|---------|--------- TODO | TODO | TODO | TODO diff --git a/Algoritmer/Grafer/depth_first_search.md b/Algoritmer/Grafer/depth_first_search.md index 7aad367..89d5979 100644 --- a/Algoritmer/Grafer/depth_first_search.md +++ b/Algoritmer/Grafer/depth_first_search.md @@ -22,9 +22,9 @@ Fargeforklaringer: -- Hvit - tre-kant: Sett, men ikke besøkt -- Grå - bakoverkant: Besøkt, men ikke ferdig -- Svart - foroverkanter eller krysskant: Ferdig +- Hvit: Sett, men ikke besøkt +- Grå: Besøkt, men ikke ferdig +- Svart: Ferdig Bokstav- og forkortelsesforklaringer: diff --git a/Algoritmer/Grafer/dijkstra.md b/Algoritmer/Grafer/dijkstra.md index 1bad924..525d843 100644 --- a/Algoritmer/Grafer/dijkstra.md +++ b/Algoritmer/Grafer/dijkstra.md @@ -39,9 +39,16 @@ Optimal substruktur. Gitt ingen negative kanter vil det umulig kunne være noen ## Kjøretid og utregning +$\space$ | Innsetting | Pop | Oppdater + -|----------|----------|--------- + Array | 1 | V | 1 + Binary Heap | $log(V)$ | $log(V)$ | log(V) + |V| Innsettinger og pop'inger |E| Relax +Dijkstra kjøretid basert på tabellen over: + Array: $O(V^2)$ Binary heap: $O((V+E)\log V)$ diff --git a/Algoritmer/Grafer/floyd-warshall.md b/Algoritmer/Grafer/floyd-warshall.md index 3e32fa7..79b1ec7 100644 --- a/Algoritmer/Grafer/floyd-warshall.md +++ b/Algoritmer/Grafer/floyd-warshall.md @@ -10,7 +10,7 @@ 6. Kjenne kjøretidene under ulike omstendigheter, og forstå utregningen --> -Floyd-Warshall brukes til å finne den korteste veien mellom alle noder i en vektet rettet graf ved bruk av dynamisk programmering og matriser. +Floyd-Warshall brukes til å finne den korteste veien mellom alle noder i en vektet rettet graf ved bruk av dynamisk programmering og vektmatriser. ## Den formelle definisjonen av det generelle problemet @@ -20,6 +20,8 @@ Output: En $n*n$ matrise $D=(d_{ij})$ med avstander, dvs. $d_{ij}=s(i,j)$ Returnerer en forgjengermatrise $\Pi=(\pi_{ij})$ +$\pi^{(k)}_{ij}$ er forelderen til noden $j$ på den korteste veien (stien) fra noden $i$. + ## Tilleggskrav for korrekthet @@ -43,11 +45,13 @@ In-place: Ja, alt skjer inne i matrisen. |-----------------------------------|----------------| | Complexity | $O(v^3)$ | | Recommended graph size | Small | -| Good for APSP | Yes | +| Good for APSP* | Yes | | Can detect negative cycles | Yes | | SP on graph with weighted edges | Bad in general | | SP on graph with unweighted edges | Bad in general | +*APSP = All Pairs Shortest Path + ## Kjøretid og utregning diff --git a/Algoritmer/Grafer/heap_sort.md b/Algoritmer/Grafer/heap_sort.md index 99d3ee1..350921a 100644 --- a/Algoritmer/Grafer/heap_sort.md +++ b/Algoritmer/Grafer/heap_sort.md @@ -29,12 +29,14 @@ Heap sort er en sammenligningsbasert algoritme, lik selection sort, hvor vi før ## Styrker og svakheter sammenlignet med andre -- Heap sort er in-place. -- Heap sort er typisk ustabil, men kan bli implementert som stabil. Den vil vanligvis endre den relative rekkefølgen ved duplikat-verdier. +- In-place: Ja +- Stabil: Nei, Heap sort er typisk ustabil, men kan bli implementert som stabil. Den vil vanligvis endre den relative rekkefølgen ved duplikat-verdier. ## Kjøretid og utregning - +Best case | Average case | Worst case | Minne +---------|----------|---------|-------- + $O(n \log n)$ | ??? | $O(n \log n)$ | $O(1)$ ## Python kodeeksempel diff --git a/Algoritmer/Sortering/bucket_sort.md b/Algoritmer/Sortering/bucket_sort.md index 30d742a..0b47a38 100644 --- a/Algoritmer/Sortering/bucket_sort.md +++ b/Algoritmer/Sortering/bucket_sort.md @@ -18,7 +18,7 @@ Bucket sort antar at input-listen er generert tilfeldig og er uniformt fordelt o ## Tilleggskrav for korrekthet -For at bucket sort skal fungere må vi unngå at alle tallene havner i samme bøtte. +Krever uniform sannsynlighetsfordeling: For at bucket sort skal fungere må vi unngå at alle tallene havner i samme bøtte. ## Trinn for trinn @@ -35,10 +35,16 @@ For at bucket sort skal fungere må vi unngå at alle tallene havner i samme bø - In-place: Nei, bucket sort oppretter mange underlister - Stabil: Ja dersom den underliggende algoritmen er det. +- Bucket sort med hver bøtte med størrelse 1 er en generell counting sort. +- Bucket sort med 2 bøtter er en generell quick sort som velger `mid` som pivot. ## Kjøretid og utregning +Kjøretid baserer seg i stor grad på subrutinen som blir brukt i algoritmen. Om man bruker insertion sort for å sortere hver bøtte som har gjennomsnittlig kjøretid på $\Theta(n^2)$, vil den totale gjennomsnittlige kjøretiden til bucket sort være i samme størrelsesorden. + +Om man velger et konstant antall bøtter vil ikke dette påvirke den asymptotiske kjøretiden, da denne konstanten ikke vil ha noe å si når $n$ blir stor nok. + Best case | Average case | Worst case | Minne ---------|----------|---------|--------- $\Theta(n)$ | $\Theta(n)$ | $\Theta(n^2)$ | $O(n)$ diff --git a/Algoritmer/Sortering/counting_sort.md b/Algoritmer/Sortering/counting_sort.md index 8b836fc..45352c8 100644 --- a/Algoritmer/Sortering/counting_sort.md +++ b/Algoritmer/Sortering/counting_sort.md @@ -43,7 +43,11 @@ Anta at du kan kun ha $k$ distinkte elementer. Tell hvor mange instanser det er Best case | Average case | Worst case | Minne ---------|----------|---------|--------- -$\Theta(n+k)$ | $\Theta(n+k)$ | $\Theta(n+k)$ | $O(n+k)$ +$\Omega(n+k)$ | $\Theta(n+k)$ | $O(n+k)$ | $O(n+k)$ + +Dersom $k \gg n$, domineres $n$ av $k$ og derfor er $\Theta(k)$ også gyldig. I den sammenhengen vil det også være mer nøyaktig enn kjøretiden over, da vi fjerner unødvendige ledd. + +Det samme gjelder motsatt vei dersom $n \gg k$, da vil kjøretiden bli $\Theta(n)$. ## Python kodeeksempel diff --git a/Algoritmer/Sortering/merge_sort.md b/Algoritmer/Sortering/merge_sort.md index 97cd288..deaa447 100644 --- a/Algoritmer/Sortering/merge_sort.md +++ b/Algoritmer/Sortering/merge_sort.md @@ -34,7 +34,7 @@ Hvis du slår sammen to sorterte lister med merge metoden, vil du til slutt få ## Styrker og svakheter sammenlignet med andre - Ikke in-place: Merge sort lager en kopi av hele sekvensen som skal sorteres, med en øvre og en nedre halvdel. Da den kopierer mer enn et konstant nummer av elementer på en gang, merge sort er **ikke in-place** -- Stabil: den relative rekkefølgen til elementene i listen opprettholdes under sorteringen +- Stabil: Ja, den relative rekkefølgen til elementene i listen opprettholdes under sorteringen ## Kjøretid og utregning @@ -51,12 +51,14 @@ I utgangspunktet vil merge sort fungere for både partalls- og oddetallslister, 4. Dermed har vi rekurrensen $T(n)=2T(n/2)+n$ 5. Ved å bruke masterteoremet finner vi kjøretiden $O(n \log n)$ -Best case | Average case | Worst case ----------|----------|--------- - $O(n \log n)$ | $O(n \log n)$ | $O(n \log n)$ +Best case | Average case | Worst case | Minne +---------|----------|---------|-------- + $O(n \log n)$ | $O(n \log n)$ | $O(n \log n)$ | $O(n)$ ## Python kodeeksempel +![GIF LOL](https://i.imgur.com/R0JN21t.gif) + ```python def merge_sort(li): if len(li) < 2: # Dersom vi har en liste med ett element, returner listen, da den er sortert diff --git a/Algoritmer/Sortering/quick_sort.md b/Algoritmer/Sortering/quick_sort.md index da254ac..acde2bb 100644 --- a/Algoritmer/Sortering/quick_sort.md +++ b/Algoritmer/Sortering/quick_sort.md @@ -38,7 +38,7 @@ Quick sort er en sammenligningsbasert splitt og hersk algoritme som velger et pi ## Kjøretid og utregning -Kjøretiden avhenger i stor grad av hvilket element som blir valgt som pivot. Den absolutt verste kjøretiden $n^2$ vil være en revers sortert liste hvor det første (høyeste) elementet blir valgt som pivot. Løsningen her er å velge tilfeldig pivot-element hver gang. +Kjøretiden avhenger i stor grad av hvilket element som blir valgt som pivot. Den absolutt verste kjøretiden $O(n^2)$ vil være en sortert liste i stigende eller synkende rekkefølge hvor det første (høyeste eller minste) elementet blir valgt som pivot. Løsningen her er å velge tilfeldig pivot-element hver gang. Best case | Average case | Worst case | Minne ---------|----------|---------|--------- diff --git a/Algoritmer/Sortering/selection_sort.md b/Algoritmer/Sortering/selection_sort.md index 89f73e4..ea24a59 100644 --- a/Algoritmer/Sortering/selection_sort.md +++ b/Algoritmer/Sortering/selection_sort.md @@ -43,9 +43,9 @@ Det å finne minimum i en liste krever at $n$ elementer sjekkes ($n-1$ sammenlig $$(n-1)+(n-2) \space ...+1 = \sum_{i=1}^{n-1} i = \frac{1}{2}(n^2-n)$$ Som gir kjøretiden $O(n^2)$ når vi dropper konstanter og lavere ordens ledd i svaret. -Best case | Average case | Worst case ----------|----------|--------- - $O(n^2)$ | $O(n^2)$ | $O(n^2)$ +Best case | Average case | Worst case | Minne +---------|----------|---------|------ + $O(n^2)$ | $O(n^2)$ | $O(n^2)$ | $O(1)$ -> **Enhver sammenlingingsbasert algoritme krever $\Omega(n\lg n)$ sammenligniger i worst-case.** +> **Enhver sammenligningsbasert algoritme krever $\Omega(n\lg n)$ sammenligninger i worst-case.** Vi må vise at høyden til valgtreet er $n\lg n$. Vi har et valgtre med høyde $h$ og antall blader $l$ som kan nås fra roten. Da det er $n!$ permutasjoner som skal representeres av blad og et binært tre av høyde $h$ kan ikke ha mer enn $2^h$ blad, vil $n! \leq l \leq 2^h$, slik at $n! \leq 2^h$. Ved å ta logaritmen finner vi: @@ -589,6 +589,22 @@ Når man snakker om trær er det vanlig å bruke terminologi som beskriver avsta En haug (heap) er en sortert tre-struktur. Elementer som legges til en heap blir først sammenlignet med sin forelder-node (parent). Avhengig av om haugen sorterer etter min eller max, blir verdiene byttet om i stien opp til roten helt til rekken er sortert. +#### Operasjoner på Heaps + +Insert = $O(log n), O(h)$ + +Delete = $O(log n), O(h)$ + +Build = $O(n)$ + +Max-heapify = $O(lg n)$ + +Build-max-heap = Linear time + +Heapsort = $O(n lg (n))$ + +Max-heap-insert, heap-extract-max, Heap-increase-key, Heap-maximum = $O(lg (n))$ + ![Illustrasjon heaps](https://i.imgur.com/0yYXmiC.png) En haug er **komplett** dersom alle interne noder har to barn og alle løvnoder er på samme nivå. Om antallet noder er $2^h-1$, for en eller annen høyde $h$, så er treet som haugen representerer komplett. @@ -754,21 +770,24 @@ Ved bruk av memoisering, altså dynamisk programmering, har LCS en kjøretid på Ryggsekkproblemet handler om å finne maks verdi man kan ha i en begrenset kapasitet. Det binære ryggsekkproblemet er en variasjon hvor man enten kan legge til en ting eller ikke (til forskjell for det kontinuerlige ryggsekkproblemet, som kan løses grådig). Problemet kan representeres som en binærstreng, hvor 0 er å ikke ta med en ting, og 1 er å ta med en ting. -Benyttes en brute-force metode på det binære ryggsekkproblemet, får løsningen en eksponensiell kjøretid $O(2^{n})$. Løses det med dynamisk programmering, får derimoten løsningen en kjøretid på O(n * w). n er her antall ting å velge blant og w er deres ryggsekkens vektskapasitet. +Benyttes en brute-force metode på det binære ryggsekkproblemet, får løsningen en eksponentiell kjøretid $O(2^n)$. Løses det med dynamisk programmering, får derimot løsningen en kjøretid på $O(n\cdot w)$, hvor $n$ er antall ting å velge blant og $w$ er ryggsekkens vektskapasitet. + +Et eksempel på oppgave: Med en ryggsekk som tar vekt $8$, hvilke av de fire tingene bør tas med for å få maks verdi? -Et eksempel på oppgave: Med en ryggsekk som tar vekt 8, hvilke av de fire tingene bør tas med for å få maks verdi? -P = price = {1, 2, 5, 6}. -W = Weight = {2, 3, 4, 5}. +> $P$ = price = $(1, 2, 5, 6)$. +> $W$ = weight = $(2, 3, 4, 5)$. Ryggsekkproblemet kan løses på lignende måte som LCS-problemet; ved bruk av en tabell. Kolonnene representerer vekt fra 0 til 8. Radene representerer ting. For hver rad tar man kun hensyn til radene over. -| | | | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | +Øverste rad er vektkapasiteten til ryggsekken. + +| | | | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | |:-: |:-: |:-: |:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:| -| **Pi**| **Wi**| **0** | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | -| **1** | **2** | **1** | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | -| **2** | **3** | **2** | 0 | 0 | 1 | 2 | 2 | 3 | 3 | 3 | 3 | -| **5** | **4** | **3** | 0 | 0 | 1 | 2 | 5 | 5 | 6 | 7 | 7 | -| **6** | **5** | **4** | 0 | 0 | 1 | 2 | 5 | 6 | 6 | 7 | 8 | +| **$P_i$**| **$W_i$**| # of **Item** | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| **1** | **2** | **1** | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | +| **2** | **3** | **2** | 0 | 1 | 2 | 2 | 3 | 3 | 3 | 3 | +| **5** | **4** | **3** | 0 | 1 | 2 | 5 | 5 | 6 | 7 | 7 | +| **6** | **5** | **4** | 0 | 1 | 2 | 5 | 6 | 6 | 7 | 8 | 0. Tabellen initieres med 0 verdier i kolonne 0 og rad 0, siden ingen ting er valgt ennå, og har dermed ingen verdi. 1. I rad 1 vurderes første ting, som har en vekt på 2. Først ved kolonne 2 legges inn tingen, som har en verdi på 1. Ingen flere ting kan velges for denne kolonnen, siden det for denne raden kun er en ting tilgjengelig. @@ -812,6 +831,9 @@ Huffmankoder er en måte å kode data som består av tegn på en slik måte at d Huffmans algoritme er en grådig algoritme som komprimerer data veldig effektivt, vanligvis mellom 20%-90%. Algoritmen bruker en tabell som teller antall hendelser av hvert tegn i en sekvens med tegn, og bygger et binærtre basert på **frekvensene**. +> Lage trær ut av Huffman frekvenser: "Stryk ut 2 og legg til en" +> [Eksamensforelesning H19](https://mediasite.ntnu.no/Mediasite/Catalog/catalogs/eksamenskurs_tdt4120_h19), video 5, 6 min inn + ## Traversering av grafer @@ -930,7 +952,7 @@ Et bredde-først-tre er et tre som blir lagd under bredde-først-søk. Søket ka #### Dybde-først-tre -Dybde-først-søk søker så langt ned i grafen som mulig. Den gjør dette ved å velge en vilkårig barne-node som den videre søker nedover i. +Dybde-først-søk søker så langt ned i grafen som mulig. Den gjør dette ved å velge en vilkårig barne-node som den videre søker nedover i. Når den treffer bunnen (en løvnode), går den stegvis tilbake til den finner nye barne-node å besøke. Denne prosessen repeteres til alle noder som kan nås fra kilden har blitt utforsket. @@ -1398,24 +1420,26 @@ De tre viktigste punktene for en god problemløsnings-strategi er: I følgende avsnitt blir disse punktene forklart. - ### Tolkning -> **Definer problemet eller problemene du står overfor. Klargjør hva din oppgave er: Hva skal du gjøre med problemene?** +**Definer problemet eller problemene du står overfor. Klargjør hva din oppgave er: Hva skal du gjøre med problemene?** ### Analyse -> **Plukk problemet fra hverandre og plasser det i en større kontekst. List opp alt du har av relevant kunnskap og relevante verktøy.** +**Plukk problemet fra hverandre og plasser det i en større kontekst. List opp alt du har av relevant kunnskap og relevante verktøy.** ### Syntese -> **Koble sammen bitene og fyll inn det som mangler av transformasjoner, mindre beregningstrinn og eventuelle korrekthetsbevis.** -> -> > #### Distribuert kognisjon -> > Benytt deg av såkalt distribuert kognisjon, og skriv ting ned. Tegn figurer og diagrammer. Lag lister med alle alternativer du kan komme på. Står du fast, bruk penn og papir, whiteboard eller din favoritt-editor for å prøve å komme videre. -> -> > #### Forbedre løsningen trinnvis -> > Prøv å komme på eksempler som gjør at du får galt svar. Prøv så å forbedreløsningen, så den håndterer disse eksemplene. -> -> > #### Tenk logisk -> > Er det noen ting på listene dine som umulig kan være relevante? Er det noe du vet må være sant, som begrenser løsningen? Gir ting mening fra et fugleperspektiv? +**Koble sammen bitene og fyll inn det som mangler av transformasjoner, mindre beregningstrinn og eventuelle korrekthetsbevis.** + +#### Distribuert kognisjon + +Benytt deg av såkalt distribuert kognisjon, og skriv ting ned. Tegn figurer og diagrammer. Lag lister med alle alternativer du kan komme på. Står du fast, bruk penn og papir, whiteboard eller din favoritt-editor for å prøve å komme videre. + +#### Forbedre løsningen trinnvis + +Prøv å komme på eksempler som gjør at du får galt svar. Prøv så å forbedreløsningen, så den håndterer disse eksemplene. + +#### Tenk logisk + +Er det noen ting på listene dine som umulig kan være relevante? Er det noe du vet må være sant, som begrenser løsningen? Gir ting mening fra et fugleperspektiv?