ALG Flashcards

(40 cards)

1
Q

Asymptoticky rust/odhad runkce

A
  1. Horni - velke O
    - f(n) je tridou O(g(n)), tedy funcike g shora odhaduje f az na konstantnu
    - (Ex c>0)(Ex n0)(ProVse n > n0) plati: f(n) <= c * g(n)
    - tedy od nejakeho pocatecniho indexu je funkce f mensi nebo rovna nasobku funkce g
    - funkce g muze byt klidne stejneho radu, nebo dokonce mensi na nejakem intervalu, (nebo dokonce na celem intervalu - treba 3x je shora ohranicene funkce x, protoze staci vzit c=4 a najednou 3x je shora ohranicenej 4x…) ale od urciteho indexu (limitne) je rychlejsi
  2. Dolni odhad - velka Omega
    - stejny princip, jina nerovnost pouze
  3. Optimalni odhad - velka Theta
    - funkce je optimalne odhadnuta druhou funkci, pokud je ji shora i zdolaomezena
    - a plati to i naopak
    - (Ex c1, c2>0)(Ex n0)(ProVse n > n0) plati: c1*g(n) <= f(n) <= c2 * g(n)

Rust funkce (polynomu) urcuje clen s nejvetsi mocninou

Limitni kriteria:
1. lim f/g = 0, pak f je shora ohranicene g
2. lim f/g = c, pak f je optimalni vuci g a naopak
3. lim f/g = nekonecno, pak je shora odhaduje g

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
2
Q

Prefixni suma

A

Pokud mam nejake pole A[] a chci rychle v case O(1) spocitat sumu pouze nejakeho poduseku. Abych to umel, zavedu pomocne prefixni pole P[], kde P[i] = Summa(a0, …, ai), tedy je to suma do tohoto useku.

Pokud pak chci spocitat hned sumu poduseku A, tak vezmu pocatecni undex a koncovy a spocitam to jako: P[konec] - P[pocatek]

Da se rozsirovat i pro 2D matice, kde mam obdelnik ktery mi uderzuje castecne soucty uvnitr podmatice…

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
3
Q

Co plati pro asympt. rust logaritmickych funkci o ruznych zakladech?

A

Rostou stejne podle jsite vety. Navic jakakoliv mocnina logaritmu je VZDY SHORA OHRANICENA LINEARNI FUNKCI

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
4
Q

Rozdel a panuj obecne, vyuziti, vzroec casove narocnosti

A

Kdyz chce velky problem rozdelit na mensi subproblemy ktery predam rekurzivne dal kde se zpracuji na elementarni/atomicke urovni (treba razeni - quicksort)

Tedy cas ulohy je = 1/2 casu + 1/2 casu + atomicka_uprava

T(n) = T(n/2) + T(n/2) + Theta(n), pro n elementarnich uprav v ramci atomickeho kroku

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
5
Q

Mistrovska veta

A

Pro ihned urceni casove narocnosti rekurzivnich algoritmu tvaru:
T(n) = aT(n/b) + f(n), tedy a-krat rozdelime ulohu na n/b poduloh a pricteme nejakou atomickou upravu

  1. Pokud f(n) je O(n^(logb(a))) potom
  • T(n) je Theta(n^(logb(a))), tedy funkce se chova podle prvniho clenu
  1. Pokud f(n) je Theta(n^(logb(a))) potom
  • T(n) je Theta(n^(logb(a)) * log(n)), tedy prvni a druhy clen jsou si rovny -> oba se podili na asymptotickem rustu funkce
  1. Pokud f(n) je Omega(n^(logb(a) + epsilon)) pro epsilon > 0 A POKUD af(n/b) <= cf(n) pro c < 1 a dostatecna velka n, potom
  • T(n) je Theta(f(n), tedy druhy clen prevalcoval ten prvni a jen on prispiva do as. slozitosti
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
6
Q

Hloubka rek. stromu a pocet listu

A

Hloubka - podle toho, jak delim data, na jaky kusy: n/2 => log2n, n/3 => log3n, n/7 => log7n…

Tedy hloubka je logaritmus n o zakladu deleni na kusy

Pocet listu je n^hloubka (asymptoticky, muze byt treba o 1 min a tak…)

Treba n^(log7(n)), kam za n dosazuju pocet volani rekurze.

Obecne:
T(n) = a*T(n/b) + f(n)
- hloubka = logb(n)
- pocet listu = n^hloubka = n^logb(a) => dosazdim tedy a

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
7
Q

Co je binarni, pravidelny binarni a vyvazeny binarni strom?

A

Binarni - ma max 2 potomky
Pravidelny binarni - ma bud 0 , nebo 2 potomky (ne 1)
Vyvazeny binarni strom - zaplnuje se zleva doprava pravidelne bez der, jeho hloubka pro n uzlu je log2(n+1) - 1

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
8
Q

Reprezentace uzlu v kodu a pruchody in/pre/post order

A

class Node {
int value;
Node left;
Node right;
}

Obecne zpracovani stormu rekurzivne:

void rec_tree(Node node){
(if node == null) return;
rec_tree(node.left);
rec_tree(node.right);
}

3 zpusoby v jaky moment zpracovat uzel node
1. Preorder - hned na zacatku, pred volanim dalsim rekurzi do potomku, vypis ukazuje presnou trajektorii pruchodu
2. Inorder - nejvic levej potomek, tedy nejdriv se zahlubim do nejvic vlevo potomka, pak ho vypisu a jdu do pravych potomku, vypisuje to binarni storm zleva doprava po uzlech jako projekce
3. Postorder - kdyz uz nemam potomky a vracim se tak vypisu uzel, tedy potomci jsou vypsani driv nez predek

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
9
Q

Pocitani uzlu a hloubky, nejdelsi cesta

A

spocit(vlevo) + spocti(vravo) + 1,
max(hloubka(vlevo), hloubka(vpravo)) + 1
cesta(vlevo) + cesta(vpravo) + 2

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
10
Q

Backtreking

A

Prohledavani stavoveho prostoru v navratem. Tedy prochazim strom do hloubky a vzdy na rozcesti zkusim jednu moznost, poznamenam si stav, abych ho pak mohl obnovit, zkusim to tam, pak se vratim, obnovim stav, zkusim jinou moznost atd… tedy postupne predavam stav a obnovuju ho, treba umisteni dam na sachovnici - zkusim se zanorovat z jednoho policka a koukam zda damu tam mohu umistit a jakmile uz ne, tak ze vracim zpet o krok vys ale musim si pamatovat i stav ze ktereho jsem vychazel

Mohu u toto urezavat stavovy prostor tak, ze se nevydam cestou ktera je pro me dopredu znama jako nevyhodna a hned se vracim

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
11
Q

Reprezentace grafu v pameti dva pristupy

A
  1. Matice incidence (slozite na pamet)
  2. Seznam sousedu kazdeho uzlu
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
12
Q

BFS

A

Breadth-First-Search, pruchod grafem do sirky. Prochazi graf po patrech potomku ferove, tedy nezanoruje se do nejake strany, ale rovnomerne bere hladiny stromu a prochazi je treba zleva doprava po patrech.

Pracuje s frontou (FIFO) datova struktura.
1. Pridej koren do fronty
2. Dokud fronta neni prazdna tak proved:
3. Pop()
4. Zpracuj to cos vyndal
5. Pridej jeho potomky

Slozitost je n, protoze proste musim projit vsechny uzly
DFS je taky lineaerni slozitost

Vyuziti - hledani komponent souvislosti (fronta je empty, ale nebyl jsem ve vsech uzlech), hledani kruznice (znovuobjeveni nejakeho uzlu kde jsem byl enbo je ve fronte), hledani nejkratsi cesty tak, ze koren ma counter 0 a pri pridani jeho sousedu do fronty (objeveni jeho sousedu) jim zvysim counter o 1 => pak tedy posledni uzel ma informaci o vzdalenosti od korene k nemu…

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
13
Q

DFS

A

Prochazeni do hloubky. Slozitost je V+E jako BFS (???). Obycejna rekurze pres vsechny neobjevene sousedy dosud.

DFS(Node node):
node.visited = true
foreach n in node.neighbours do
if !n,visited then: DFS(n)

Takze vem node a pro kazdeho jeho souseda zpust rekurzivne DFS pokud nebyl objeven

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
14
Q

Pouziti BFS, DFS

A
  1. Detekce komponent souvislosti
  2. Detekce cyklu - POUZE DFS (narazim na otevreny uzel, tedy jsem se do nej vratil cyklme), BFS najde kruznice
  3. Nalezeni kostry
  4. Nejkratsi cesta - POUZE BFS
  5. Topologicke usporadani - POUZE DFS (sestupne usporadam podle casu uzavreni)
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
15
Q

Vyhledavani v serazenem poli

A

Pomoci Binary Search, kdy pole pulime na interaly poloviny a kontrolujeme zda moje hodnota lezi v tomto intervalu.

Vyuziva BST - strom ktery reprezentuje serazene hodnoty. Logaritmicka narocnost

Exponencialni vyhledavani - navysuju hledany interval tak dlouho, dokud tam nespadne mnou hledana hodnota - tedy nejdruv exponencialne hledam interval a pak az v nem treba nasadim binary search

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
16
Q

BST

A

Datova struktura reprezentujici usporadane pole prvku pro vyhledavani. Inorder vypise serazene pole.

Leva cast - mensim prava - vetsi

Find:
jestli jsem tento uzel - vrat
jestli jsem mensi nez hledana hodnota - hledej vpravo
jestli jsem vetsi nez hledana hodnota - hledej vpravo

Insert:
1. find misto
2. vytvor novy uzel a napoj ho

Delete uzel (se dvema potomky)
1. Find ho
2. Najdi k nemu nejblizsi vetsi vpravo
3. Dej nejblizsi vyssi vpravo na misto smazaneho
4. Preusporadej potomky noveho uzlu

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
17
Q

Asymptoticka slozitost operaci BST

A

OBECNY BST MUZE BYT RETIZEK HODNOT!
- tedy Find, Insert, Delete obecne jsou Theta(n) kdy musime vzdy projit pole prvku velikosti n

Vyvazeny BST strom je stromovity takze je to log(n)

18
Q

AVL Strom

A

Binarni Vyhledavajici Strom splnujici podminku:

  • pro kazdy uzel je rozdil hloubek leveho a praveho podstrmomu roven -1, 0, nebo 1.

Jakmile dojde k poruseni podminky, tak se strom musi vybalancovat rotacemi.
Je to vyvazeny strom, udrzuje stromovitou strukturu porad, proto operace v nem jsou Theta(logn) oproti obecnemu BVS

Rotace - uzel ktery putuje nahori preda svoje potomky uzlu ktery se snizuje.

Nekdy jendoducha rotace nemusi stacit a musime provest dvojitou rotaci. Od pridaneho uzlu postupujeme smerem ke koreni a pokud narazime na rozvazeny uzel, tak se podivame na posledni dva kroky jak jsme tam dosli, (typicky pro root)
- prisli jsme dvakrat zprava/zleva - prava/leva rotace jednoducha
- prisli jsme zleva-zprava - provedeme nejdriv leva pak prava rotace
- prisli jsme zprava-zleva - provedeme nejdriv pravou pak levou rotaci

Po operaci insert staci VZDY POUZE JEDNA ROTACE
Po operace delete OBECNE AZ PO O(logn) rotacich

19
Q

B=Strom

A

Pri databayovzch szstemech, souborovych systemech

B-Strom radu k ma bunky velikosti 2k a uchovav minimalne k nebo 2k klicu (krome korene, muze mit jen jeden klic treba).
Tedy stormr radu k=2 ma bunky velikost 4.

Uchovava v blocich prvky mensi nez na dane pozici
- kazdy uzel ma 1 vice potomku nez klicu
- vsechny cesty od korene k listum jsou stejne dlouhe
- find - sestupuju na hladinu klice a v ramci bunky uz hledam lienarne nebo binarne

Insert - najdi potrebnou pozici
- pokud je volne misto tak vloz
- pokud neni misto, tak usporadej mimo prvky
- vyber jejich median (prostredni prvek, vzdycky je, protoze rad je 2k sudy)
- z medianu udelej novej uzel, napoj na nej zleva prvky mensi a zprava prvky vetsi
- napoj novy uzel k rodici pokud jde
- pokud nejde opakuje stepeni rodicu…

Delete -
- najdi prvek a pokud ma dost klicu tak vymaz
- pokud mazes ve vnitrnim uzlu a ma dost klicu, tak ho nahrad nejblizsim prvekm z listu pokud ma dost klicu
- pokud ale by mel uzel min nez k klicu tak:
- spoj sousedni uzly spolu s jejich JEDINYM rodicem mezi nimi (sleju dohromady)
- jejich median poslu na misto rodice a PRELEJU OD sousedu nejake prvky pokud to jde, tedy prerotuju sousedni uzel aby se mi podelil o nekolik prvku
- pokud ani soused nema dost prvku - tak dva uzly spoj dohromady (slej do jednoho i vcetne rodice), vsechno dej do jednoho uzlu (vymaz ten prazdny) a vymaz i rodice z horni hladiny

Slozitost B-stromu radu K:
vsechny tri operace: Theta(k*logk(n)), tedy log je stoupani stromovou sturkturou a v ramci bunky musim projit linearni k prvku

20
Q

Radici algoritmy obecne, n^2

A

Radici algoritmy sloui k serazeni pole (protoze v serazenem poli umime efektivne vyhledavat). Bud n^2, kde potrebujeme porjit cele pole a treba porovna kazde dva prvky v nem coz nam da dvojity for cyklus vuci n takze asymptoticky n^2 slozitost Theta.

  1. Selection sort
  2. Insert sort
  3. Bubble Sort
  4. Quick Sort pro predem serazena data casteccne
21
Q

Selection sort

A

Radici algoritmus slozitossti n^2. Prochazime cele pole a pro kazdy prvek:

  1. najdeme minimum ve zbyvajici casti pole
  2. Porovname ho s aktualnim prvek na kterem stojime
  3. Bud je prohodime nebo nechame byt.

Tedy dvojity for cyklus prochazi cele pole a kazdy prvek s kazdym kdo je mensi, pokud jsem nasel mens, tak je prohodim na VEKLOU VZDALENOST

  • nestabilni
  • celkvoa slozitost Theta(n^2) nejde vylepsit ani zhorsit
  • pocet porovnani - n(n-1)/2, tedy kazdy s kazdym
  • za jednu operac 3 presuny pres tmp promennou, tedy celkem az 3(n-1) presunu pokud mam pole sereazeno treba uz sestupne tak se kazdy prvek prohodi
  • vyhoda - malo zapisovnai do pameti a prohozeni
22
Q

Insert Sort

A

Radici algoritmus sloziosti n^2.

  • prochazime cele pole a vzdy nasledujici prvek zarazujeme do zleva jiz serazene podposloupnosti (insertujeme ho).
  1. Pro kazdy prvek v poli, pro usporadanou cast proved:
  2. Porovnej aktualni prvek ktery chceme insertovat s jiz serazenou casti vlevo
  3. Mensi prvky probublavaji treba az na uplny zacatek
  • v nejlepsim pripade udelam pouze 1 test (nasledujici prvek je vetsi nez cela jiz vlevo serazena cast), tedy celkem (n-1) testu
  • v nejhrosim pripade az k testu, kde k je veliksot srazene casti vlevo (pro pole treba sereazene sestupne), tedy celkem porovnam kazdeho s kazdym - n(n-1)/2
  • presunu 2 v nejlepsim pripade (proste swap), tedy 2(n-1) prohozeni
  • v nejhorsim pripade az k+1 prohozeni, tedy (n^2 + n - 2)/2 presunu
  • vyhoda - skoro linearni pro serazeny vstup, stabilni
  • slozitost SHORA OMEZENA O(n^2), muze byt i linearni
23
Q

Bubble sort

A

Radici algoritmus, ktery vytvori okenko a prohodi dva sousedni prvky pokud je to potreba. Udela to pro celou delku pole. Tedy okenko se posouva (NE PRVEK ZAFIXOVANY) jeden prubeh okenanka prohodi sousedy 1. faze, pak to same se udela jeste jednou a jeste jednou… tedy okenko projede na konec a pak od zacatku znovu

  • postupne se mi hromadi na kocni pole nejvetsi prvky
  • vyhoda - jednoduchy kod, stabilni - prohozuje pouze dva sousedy vedlejsi
  • pro kazdy prvek v pole
  • pro kazdou dvojici
  • porovnej a prohod
  • celkem testu - kazdy s kazdym - n(n-1)/2
  • celkem presunu - nejhorsi pripad n(n-n)/2 kvadraticka
  • slozitost je Theta(n^2) nejde zrychlit
24
Q

Quicksort

A

Algoritmus ktery radime do O(n^2) obecne, ale ocekavame nlogn slozitost.

  1. Zvolime pivota (bud nahode, nebo median prvku, nebo 1. prvke atd…)
  2. Rozdelime vstupni pole na male a velke prvky oproti pivotu (bud ostra nebo neostra neorvnost, pivota muzeme dat do jaekoliv poloviny)
  3. Zavedeme ukazatel zleva a zprava a zacneme u prvniho a posledniho prvku
  4. Vzdy kouknem na dva prvky podle uazatelu a porovnavame je
    - pokud se maji prohodoit - prohodime je a posouvam ukazatele k sobe
    - pokud se jen jeden ma prohodit, tak u nej ukazatel nechame a u druheho pokracujeme s posunem
  5. Kdyz jsme dosli k tomu, ze se ukazatele protli -> volej rekurzi od kroku 1 na dve vznikle poloviny…

Tedy kod mi rozpuli vstupni pole na mensi podproblemy, kde v kazdem z nich rekurzivne to rozpulim dal, kde kazde deleni mi prehodi male prvky a velke prvky. Tedy v poslednim kroku se pouze proovnaji dve hodnoty a prohodi se podle velikost.

Nejhorsi pripad je ze si spatne zvolime pivota (nebo pole je uz serazene) a budeme pole delat na 1 prvek a zbytek - coz nam povede na lienarni zpracaovani pole n-krat - tedy Theta(n^2).

Obecne ale ocekavana slozitost je Theta(nlogn), protoze mam stromovitou strukturu jejichz hloubka je logn a v kazdem kroku udelame n porovnani.

  • vyhody - muzeme ocekavat vetsi rychlost nez n^2, ve standardni knihovne vetsinou implementovan
  • nevyhoda - nestabilni
  • pocet rpesunu obecne- nlogn Theta
25
Merge sort
Radici algoritmus slozitosti Theta(nlogn) kde vstupni pole rozdelime na mensi podproblemy rozdel a panuj rekurzivne, v nejnizsi urovni porovname dvojice a vracime se nahoru. Behem vraceni se nahoru postupne slucujeme vysledky podproblemy dohroamdy tak, ze lienarne porovnavame prvky subproblemu a zapisujeme je slucovane bunky podle veliksoti - rozdeleni je ihned THeta(1) - slucovani je Theta(n), protoze v linearnim case projdu podproblemy a slucim je dohromady - musime provest logn slucovani (tolik mam pater pri rekurzi) - coz dava celkovou slozitosst nlogn - stabilni Merge metoda slucovani - v jednom cyklu zaved ukazatele pro pole A a ukazatel pro pole B. Vzdy porovnej prvky na indexech a pokud beres prvek z pole nejakeho, tak posun jeho ukazatel (druhej nech) a tak dokud ti nedojde jedno ze dvou poli. Jakmile pole doslo - zkopiruj hodnoty druheho pole ktere proste zbyly
26
Binarni halda
Stromova datova struktura ktera splnuje POUZE JEDNU PODMINKU: rodic je vzdy mensi nez potomci (vztah potomku je ale neurcity) - implementuje prioritni frontu, kde koren je nejprioritnejsi Insert - novy prvek vlozime jako dalsi list a pak ho musime probublat na takovou pozici, kdy bude vetsi nez svuj rodic ale mensi nez jeho potomci Delete - smazat muzeme POUZE KOREN (protoze ma prioritu) - koren nahradime poslednim listem - novy koren probublavame dolu (prohazujeme s mensim potomkem standardne) dokud nenarazime na takovou prvni pozici, kde ten uzel bude vetsi nez rodic ale mensi nez potomci - oprava ma logaritmickou slozitost, protoze musime sesoutap az do listu v biarnim stromu coz mi dava slozitost logn Reprezentujeme v poli jako: koren je vzdy na 1. pozici. - levy potomek uzlu na indexu k je 2k - pravy potomek uzlu na indexu k je 2k+1 Budodvani haldy - mejme nejake pole prvku - v nem postupuju o posledniho prvku k prvnimu - kouknu, zda aktualni prvek splnuje relaci haldy vuci svemu predkovi - pokud ji splnuje - necham - jdu dal - pokud nesplnuje - prohodim je mezi sebou - toto je slozitost Theta(n) protoze musim proste jednou projit pole a proovnat potmky s jejich rodici
27
Heap Sort
Razeni haldou 1. Postav ze zadaneho pole haldu 2. V cyklu pro kazdy prvek: - prohod 1. a posledni prvek (tedy nejmensi prvek haldy dej na konec - oprav haldu Algoritmus konci, kdyz uz mam nejvetsi prvek jako prvni - tedy tridi to sestupne - mohu to pak vypsaat v obracenem proadi Slozitost: - n-krat odstranim prvek - orpava trva log(n) - tedy celkem mohu provest az n-1 * logn operaci - celkove: Theta(nlogn) - nestabilni - prohazuje prvky na velkou vzdalenost
28
Radix sort
Prehradkove razeni - hlavne pro retezce - pro slova stejne delky, kde pocet znaku je d - d-krat musim projet vstupni pole retezcu n, tedy slozitost je Theta(dn) coz pro male d znamena Theta(n) linearni algoritmus. 1. Udelam si d prehradek podle poctu znaku (serazene prehradky abecedne!!!) 2. Projdu cele pole a poskladam retezce ZA SEBOU TAK JAK BYLY ODSHORA DOLU do prehradek podle posledniho znaku 3. Prohlasim to za nove vstupni pole 4. Znovu si udelam d serazenych abecedne prehradek 5. Nove pole rozhazu VE STEJNEM PORADI JAK JDOU ZA SEBOU do prehradek podle predposledniho znaku 6. Prohlasim to za nove vstupni pole ... opakuju tyto kroky dokud to neseradim podle 1. znaku Abecedne serazene prehradku a sekvencni projiti pole odshora dolu mi zajistuje, ze nikdy neprohodoim uz serazena slova podle predchozich pismen - nemaji se jak promichat kdyz to dodrzim. - stabilni algoritmus - linearni slozitost
29
Counting sort
Razeni pocitanim - vhodny pro velka pole s omezenim nabyvanim hodnot - tedy treba 1 milion mereni, ale nabyvane hodnoty pouze treba v intervvalu (0, 10) - pak je to vyhodny s linearni narocnosti 1. Nejdriv si vyrobim pole cetnosti - tedy projdu jednou cele pole a spocitam cetnosti jednotlivych elementu od min po max. Jako vysledek mam pole elementu od min po max, vcetne nevyskytovanych. A druhe pole primo cetnosti, kde na vynechanych pozicich mam 0. 2. K vynechanym elementum pridame cetnosti 0 (pokud v inputu treba chybi 5, tak v poli cetnosti bude mi 5 pocet 0) 3. Poscitam prefixni sumu v poli cetnosti - tedy prostre postupne jdu zleva doprava a pricitam cetnosti k sobe. 4. Jako vysledek mam v poli cetnosti prefixni sumu, kde posledni element ma index posledni pozice na ktere konci Pak zacinam cist PUVODNI VSTUPNI POLE POZPATKU a doplnovat do noveho cisteho pole o velikosti takvoe, jaky je index posledniho prvku v poli cetnosti: - ctu prvek - kouknu kde ma koncit - zapisu ho na tu pozici - dekrementuju jeho prvek o 1 - ctu dalsi prvek... - vyhody: stabilni, lienarni slozitosst
30
Hashovani
= kompromis mezi rychlosti a spotrebou pameti. Jak obecne nalezt data v datove strukture? - pokud mame nekonecno casu -> tak sekvencni vyhledavani a porovnavani hodnot -> pole - pokud mame nekonecne pameti -> pomoci primero pristupu indexovanim klicu -> slovnik - pokud mame malo casu i pameti => hashovaci tabulky - chceme v konstantnim case operace Find a Insert Klice zasifrujeme pomoci hashovaci funkce - ktera pocita adresu z hodnoty klice, ktera ale muze mit kolize. - synonima: dva ruzne klice, ktere ale maji stejnou hashovaci funkci hodnotu Od hashovaci funkce pozadujeme: - rychlost - nahodnots - rovnomerne rozpoztreni - minimu kolizi
31
Priklady hashovacich funkci pro ruzne typy
1. Realna cisla z intervalu <0,1>: - multiplikativni h(k, M) = round(k*M), kde M je velikost tabulky 2. Cela cisla - treba modualrni: - h(k, M) = k % M 3. Strings: - Hornerovo schema - prevod retezce na polynom, kde znaky nmahradimy jejich ciselnymi ASCII hodnotami
32
Reseni kolizi hashovacich
1. Zretezene rozptylovani - Pro stejne klice budujeme spojove seznamy, kdy vkladame vzdy na zacatek s O(1). Search a delete obecne O(n) 2. Otevrene rozptylovani - zname dpredu (cca) pocet prvku na ukladani - pri kolizi bud udelam liearni prohledavani, nebo dvojity rozptylovani 2.1. Liear probing - pri kolizi zvysuj inkrement a zkus hledat dalsi volne pozice: h(k) = (k+i) mod m, kde i zacnu na 0, v pripade kolzie inkrementuju (proste posun o i kroku dal) modulo velikost pole. Ke kroku i mohu pridat *konstantu treba 3, tedy se budu posouvat po trech krocich naraz... - bez konstanty hrozi velke kolizni bloky (hromadeni za sebou) - pridani konstanty prida trochu nahody kolizim 2.2. Double hashing - pri kolizi aplikuju druhou hashovaci funkci - treba h(k) = [h1(k) + i*h2(k)] mod m - tedy nejdriv udelam prvni hashovaci funkci, pokud nastala kolize (tak inkrementuju i z 0 na 1) pak spocitam druhou hashovaci funkci, sectu je a udelam modulo m treba... pokud nastane dalsi kolize tak inkrementuju i a pocitam znova pomoci tabulkjy
33
LISCH, EISCH, LICH, EICH, VICH, Extandable
1. LISCH - late insert standard coalesced hashing - zpusob reseni kolizi tak, ze vytvorim spojove seznamy primo v tabulce - ke klicum pridame nove policko, ktere ukazuje na pripadny dalsi prvek - v tabulce zavedem ukazatel posledni pozice, ktery budeme updatovat - pri kolizi prvky vkladame na prvni volne misto od konce - pridane prvky kolizni propojime s jejich predchudci do spoj. seznamu - kouknu na adresu -> kolize -> pridam na prvni volne misto od konce -> -> propojim pridany prvek do spojoveho seznamu s jeho predchudcem, tedy mistem, kde realne mel byt -> mohu to retezit i po x krocich... - zarazuju to tedy na konec seznamu 2. EISCH - eraly... - zarazuju na ZACATEK spojoveho seznamu, hned za kolizni pozici - pridam jako druhy prvek po kolizi (na prvni volne misto od konce) - ale nepridam na zacatek, ale prehodim ukazatel z puvodni pozice na nove pripadny rpvek a z nove pridaneho prvku napojim na zbytek spojoveho senzmau - tedy kolize -> pridam novy prvek na prvni volne misto od konce -> roztrhnu ukazatele s puvodni pozice a zbytkem senzmau -> vlozim tam ukazatel na novy prvek a napojim ho na zbytek seznamu - vlozim tedy jako druhy a prehodim ukazatele 3. LICH - LISCH algoritmus ale se sklepem - sklep je pridane misto na konci tabulky, ktere neni adresovatelne hashovaci funkci - ale ma stejnou strukturu a postupy - tedy ukazatel zacina na konci sklepa - pri kolizi plnime njedriv sklep algortmem LISCH - kdyz dojde sklep tak plnime zbytek tabulky klasicky - predejde to kolizim v ramci samotne tabulky, kdy odlozeny prvek zabira misto jinych prvku podle hashovaci funkce (tedy obsadil misto jine tride ekvivalence), protoze sklep je neadresovatelny, takze prvky z ruznych trid ekvivalence plni tabulku samotnou bez kolizi 3. EICH - EISCH se sklepem analogicky... 4. VICH - variable, tedy po naplneni sklepa menim algoritmus z LICH na EICH? 5. Extandable - tabulka pracujici s binarnimi klici, kde vytvorim jakysi tag spolecny pro klice, tedy zalozim mnoziny, ktere maji stejny tag a ukladam to do nich, mohu to stromovat dal... tedy pridam dalsi bity do tagu takze zalozim novou skupinu a tak...
34
Dynamicke programovani
Postupne vyplnujeme tabulku, ktera nam resi podproblemy od nejmensiho po nejvetsi - postupne aktualizujeme dalsi krok z jich vypocitanych predchozich kroku. Rekurze naopak provolava az do hloubky vsechna volani ZNOVU. DP - nemusi provolavat znovu, protoze si vsechny predchozi vypocty uchovava v pameti
35
Nejdelsi cesta (nejdrazsi) v DAG - directed acyclic graph
Pomoci dynamickeho programovani: - sestrojim topologicke usporadani - zacnu v koreni a postupuje zleva doprava - pro nasledujici uzel vzdy spocitam maximum ze vsech variant odkud do me vede hrana, - tedy priklad 1->2, 1->3, 2->3, ve trojce tedy spocitam maximum z (1->3, 2->3), kde v ceste 2->3 uz je automaticky zapocitana cesta z 1->2 jako predchozi krok. Tedy vzdy kouknu odkud muzu prijit a vezmu z toho maximum. K dalsimu kroku naprimo tedy pripocitam jeho puvodni hodnotu + cena kroku
36
Nejdelsi rostouci/klesajici/aritmeticka/geometricka... podposloupnost v zadane posloupnosti cisel/retezcu
Pomoci dynamickeho programovani: - prevedu ulohu na znamy tvar - hledani nejdelsi cesty v DAG - tedy zadanou posloupnost vnimam uz jako topologicke usporadanou, kde hrany mezi prvky existujou, pokud splnuji kriterium ze zadani (treba z mensich prvku do vetsich prvku - rostouci podposloupnost a naopak pro klesajici...) - v tomto topologicky usporadanym DAGu staci tedy najit nejdelsi cestu - projdu pak kazdy uzel a kouknu, jak jsem se do nich dostal a vyberu to nejdelsi a rekonstruju cestu zpatky - slozitost (n+m)
37
Optimalni nasobeni matic Optimalni BVS Rezani tyce
TODO - kubick slozitosst
38
Nejdelsi spolecna podposloupnost
Napis dve slova do matice jedno svisle jedno vodorovne - pridej radek a sloupec prvni samych nul - pokud je MATCH - vem prvek po diagonale vlevo + 1 - pokud je MISS - vem maximum s leveho a horniho prvku
39
Neomezena uloha batohu
Jde prevest jednoduse na DAG - uzly jsou postupne kapacity od 0 az maximalni kaapcita - hrany vychazi z kazdeho uzlu a je jich tolik kolik je predmetu - cena hrany je cena predmetu - hrana vede tam, do jake kapacity se naplni predmet (tedy pokud predmet ma vahu 4 a cenu 5, tak hrana pujde o 4 uzly dal a bude stat 5) - v tomto DAGu najdu nejdelsi cestu - hotovo
40
Omezena uloha batohu
Kazdy predmet si muzu vzit maximalne jednou: