Přidání poznámek z PRO

This commit is contained in:
Filip Znachor 2024-01-24 22:17:22 +01:00
parent bf2c303a5c
commit 8a9d04fc64
5 changed files with 490 additions and 0 deletions

View file

@ -0,0 +1,123 @@
# Programátorské strategie
## Algoritmizace
**Proč se jí zabývat?**
- rozvíjí abstraktní a logické myšlení potřebné nejen pro techniky
- existují hotová řešení na různé problémy, ale vždy narazíme na trochu jiné problémy
+ je potřeba znát
+ základní problémy a jejich řešení
+ principy a techniky k řešení velké oblasti neznámých problémů
**Algoritmus**
- postup k vyřešení určitého úkolu
- musí řešit obecný, dobře specifikovaný problém
- procedura, která libovolná možná vstupní data transformuje na požadovaný výstup
- **algoritmus** - vždy vede k cíli, **heuristika** - nemusí vést vždy k cíli
### Správnost a účinnost algoritmu
**Cíl snažení**
- algoritmy správné, efektivní a snadno implementovatelné
- ne vždy je možné vše najednou
**Zlepšení výkonu**
- lepší algoritmus > lepší počítač
- kdy nehledat účinnější řešení:
- poběží jen několikrát
- výpočet přes noc je OK
- optimalizovat *bottleneck* (kritické místo - 90 % času v 10 % kódu)
### Robustnost algoritmu
**Cíl snažení**
- algoritmy odolné vůči numerickým aj. chybám
- singulární případy: při první úvaze ignorovat, poté zahrnout
**Robustnost**
- malá chyba nesmí vést k selhání
- algoritmy často odvozeny např. pro nekonečnou přesnost reálných čísel
### Analýza algoritmů
**Cíl snažení**
- hodnocení a porovnávání algoritmů nezávislé na typu počítače a na jazyku
- typické chování pro očekávaná vstupní data
**Nástroj**
- asymptotická analýza složitosti
- experimentální otestování na reprezentativních vstupních datech
#### Složitost
- paměťová x časová x předzpracování
- nejčastěji nás zajímá nejhorší případ a očekávaný případ
- => složitost v nejhorším případě, očekávaná složitost
**Symbolika**
- $O(f(n))$ - horní mez
- $\Omega(f(n))$ - dolní mez
- $\Theta(f(n))$ - omezeno shora i zdola (optimální algoritmus)
**Časová složitost algoritmu**
- nejdelší doba výpočtu potřebná pro vstup velikosti $n$
**Časová složitost problému**
- časová složitost nejrychlejšího algoritu řešící tento problém
- $O(n^2)$ - najít algoritmus, který vyřeší tento problém nejvýše v čase $cn^2$
- $\Omega(n^2)$ - dokázat, že žádný algoritmus nedokáže problém vyřešit rychleji
#### Experimentální ověření složitosti
- spotřeba času a paměti jako funkce velikosti vstupu
- pro zmenšení chyby měřit více opakování, bez I/O, pro více datových množin, pro více typů dat
- spočítat $t/f(n)$, zkoumat průměrné a nejhorší chování
**Očekávaná složitost (Expected complexity)**
- odhad pozorovaného chování algoritmu, často odhad podle implementace, závisí též na očekávaném typu vstupních dat
#### Standardní třídy složitosti problému
- **P** - problém v této třídě řešitelný výpočty v polynomiálním čase
- **NP** - řešitelný v polynomiálním čase nedeterministicky
- nevíme, jak řešit polynomiálně, ale umíme ověřit v polynomiálním čase řešení
- dnes kolem 3000 problémů
- **NP-úplné** - není známo žádné polynomiální řešení
- nebylo dokázáno, že neexistuje
### Hledání řešení neznámého problému
Pomáhá klást si správné otázky (v uvedeném pořadí):
1. Opravdu problému rozumím?
- Co je vstupem?
- Jaký přesně má být výstup?
- Umím sestavit malý příklad a vyřešit ručně? Co se stane, když to zkusím?
- Jak moc je pro mou aplikaci důležité najít vždy přesné, optimální řešení? Nestačí něco, co obvykle funguje docela dobře?
- Jak velká je typická instance mého problému? 10? 1000? 1 mil.?
- Jak důležitá je pro moji aplikaci rychlost?
- Musí být problém vyřešen za 1s? 1 min? 1 h? 1 den?
- Kolik času a úsilí mohu dát do implementace?
- Budu řešit numerický problém? Grafový? Geometrický? Se znakovým řetězcem? Více možných formulací? Která se zdá nejlehčí?
2. Umím najít jednoduchý algoritmus nebo heuristiku řešící daný problém?
- Umím najít algoritmus správně řešící můj problém prohledáním všech podmnožin a výběrem nejlepší? (Pokud ano, jsem si jist správností odpovědi? Umím změřit kvalitu nalezeného řešení? Stačí časově? Pokud ne, mám problém dostatečně definovaný, aby se dal vyřešit?)
- Umím problém vyřešit opakovaným výběrem nejlepšího? Opakovaným náhodným výběrem? (Pokud ano, pro jaký vstup to funguje dobře, špatně? Je to rychlé?)
3. Není můj problém v katalogu algoritmických problémů?
- Pokud ano, co je o problému známo? Není k mání implementace řešení?
- Pokud ne, je to správné místo? Umím hledat v knihách?
- Co Web?
4. Existující speciální případy, které umím řešit přesně?
- Umím to, pokud ignoruji některé parametry?
- Co se stane, když některé parametry nastavím na triviální hodnoty, jako je 0, 1?
- Umím problém zjednodušit na případ, který je možné řešit přesně? Je teď triviální nebo stále zajímavý?
- Pokud už umím řešit spec. případ, proč nejde řešení použít pro obecnější problém?
- Je můj problém spec. případ některého obecného problému?
5. Které ze standardních paradigmat návrhu algoritmů je nejvhodnější pro můj problém?
- Je možné položky setřídit? Ulehčí to řešení? (SORT)
- Je možné problém rozdělit na 2 nebo více podproblémů? Malý a velký? Levý a pravý? 2 stejně velké? (D&C)
- Má vstup nebo řešení přirozené pořadí zpředu dozadu, zleva doprava (řetězce, permutace, listy stromu)? (DP)
- Opakuje se stejná operace nad stejnými daty (hledání), kterou by urychlila pomocná dat. struktura? (slovník, hašovací tabulka, hromada, prioritní fronta…)
- Lze použít náhodné vzorkování pro výběr dalšího objektu? Výběr nejlepší z náhodně vybraných konfigurací? (řízená náhodnost, např. SA)?
- Problém pro lineární programování? Celočíselné programování?
6. Jsem stále ztracen(a)?
- Nenajmu si na to experta?
- Nezkusím otázky projít znova? (Změnily se moje odpovědi?)

View file

@ -0,0 +1,126 @@
# Algoritmické strategie
## Brutální síla
- problém řešen prohledáním všech podmnožin, uspořádání nebo potencionálních řešení a výběrem nejlepšího
+ pro malé problémy postačující
+ často superpolynomiální složitost
+ obvykle snadná garance správnosti algoritmu
## Greedy strategie
- očekávané řešení je množina $n$ prvků
- začneme s prázdnou množinou
- vždy zafixujeme 1 položku řešení, kterou už neměníme
- takto pokračujeme dál, dokud jsou všechny zafixované
- pořadí podle slibnosti položek (od slibnějších k méně)
- "greedy" - nikdy se nevrací, nikdy nemění dřívě udělané rozhodnutí
Příklady
- greedy algoritmus pro minimální kostru
- greedy heuristika pro minimálního cestujícího
## Inkrementální strategie
- obvykle nevede k optimálním algoritmům
- obvykle implementačně jednoduché, zejména vkládání
- dovoluje různé modifikace
### Inkrementální vkládání
- budujeme řešení (strukturu) o $n$ položkách
- napřed řešení o $n-1$ položkách, pak nezbytné změny a vložení $n$-té položky
- v paměti někdy dílčí řešení, někdy jen současný stav
- zvlášť užitečné pro geometrické algoritmy
- **on-line metoda** - vstup nemusí být celý dostupný na začátku
- užitečné pro reálná data, ale část práce se dělá zbytečně
Příklady
- insertion sort
- obarvení vrcholů
- hvězdicová polygonizace
### Inkrementální konstrukce
- budujeme řešení (strukturu) inkrementálně, v každém okamžiku kousek
- vstup zpracováván v pořadí, jaké algoritmus chce, nikoliv v pořadí, jak vstupní data přicházejí
- **off-line metoda** - vstup musí být celý k dispozici
- vhodné pořadí vstupních dat někdy určeno předem (např. presort), někdy až v průběhu výpočtu
- časté pro geometrické problémy
Příklady
- selection sort
### Jiné inkrementální strategie
**Inkrementální změna**
Příklad: Generování permutací
- generujte všechny/náhodnou/další permutaci délky $n$
- permutace v poli, inkrementální změna = jeden swap v poli
- inkrementální změna generuje další permutaci z předchozí
- extrémně rychlé - až $O(0)$ v průměru pro 1 permutaci, nezávisí na $n$
## Rozděl a panuj (D&C)
- složitý problém je rozdělen na jednodušší podproblémy
- řešení podproblémů se poté spojí na celkové řešení
- pro dekomponovatelné problémy
- dělení a spojování nesmí být dražší než původní problém
- dekompozice a zejména spojování často obtížné
+ obvykle využita rekurze
+ původně vojenská strategie
Příklady
- mnoho významných, ale obvykle obtížných algoritmů
- např.: mergesort, FFT, Strassenovo maticové násobení
- quicksort
- dláždění šachovnice
- binary search, bisection (půlení intervalu)
- rychlá mocnina
- odmocnina
## Prohledávání s návratem (Backtracking)
- systematický průchod všemi možnými konfiguracemi prostoru
- obvykle prohledávání stromu do hloubky (DFS)
- menší spotřeba paměti než u prohledávání do šířky (BFS)
- pokud nelze postupovat dál směrem k listu, návrat k poslednímu rozhodovacímu místu
- odtud jiný postup (strategie pokusu a omylu)
+ vhodné také pro paralelní implementaci (spousta práce, málo komunikace)
+ množina všech možných řešení se rozdělí na podmnožiny a ty se paralelně prohledávají
+ pokud některý procesor hotov a jiný ne, přerozdělí se dosud nehotová část množiny řešení mezi hotové procesory
+ kromě přerozdělování je komunikace nutná jen pro nalezení nejlepšího řešení z nejlepších řešení jednotlivých procesorů
**Typické úlohy**
- nejčastěji permutační, herní nebo grafové
- všechny možné permutace nebo podmnožiny objektů
- průchod všech koster grafu nebo cest mezi 2 vrcholy
**Typické aplikace**
1. Optimalizační problémy, zejména komerční
- obchodní cestující, vhodné linky pro autobusy
- plánování (schůzky - sdružit seznam kandidátů se seznamem protikandidátů)
- turnajové schéma (kandidáti i protikandidáti ze stejného seznamu)
- výzkum trhu (testování výrobků)
- sladění nabídky a poptávky
- prohledávání adresáře s podadresáři
2. Hry
- šach, dáma, piškvorky, reversi, Go
3. Hádanky
- křížovky
- hádání na stěhování a přesuny
- Rubikova kostka, pokrývání šachovnice, stěhování piána
- solitéry (a: v co nejmenších tazích)
- vytváření bludiště a jeho řešení
- sudoku
- magické čtverce
Příklady
- pokrytí šachovnice
- vyvažování vah
- odporné odpory pana Odporného
- magický zapletenec

View file

@ -0,0 +1,121 @@
# Randomizované algoritmy
## Motivace
Mějme pole prvků, které je tvořeno stejným počtem prvků **a** a **b** v nejznámém pořadí. Cílem je najít znak **a**.
Deterministicky:
- $n/2$ kroků v nejhorším případě (pokud napřed budou všechna **b**)
Randomizovaně:
- kontrola v náhodném pořadí
- s velkou pravděpodobností najdeme **a** brzy bez ohledu na vstup
- tzv. Las Vegas algoritmus
+ randomizovaný algoritmus může být jednodušší neý deteministický při stejném nejhorším případě jako deterministický (např. quicksort)
+ jednoduchou deterministickou heuristikou s dobrými výsledky může být možné převést na algoritmus s dobrým nejhorším případem dodání náhodnosti (např. medián)
+ někdy náhodnost může řešit problémy, které deterministicky není možné řešit (problémy řešené orákulem) nebo se zdají nemožné
Randomizace
- vhodný nástroj pro vylepšování algoritmů, které mají špatný nejhorší případ a dobrý průměrný případ
- nejhorší případ zůstává, ale závisí na štěstí, ne na pořadí vstupních dat
- využití v kryptografii, kvantových výpočtech, hrách, simulacích, ...
## Randomizované algoritmy
- dělá nedeterministická, náhodná rozhodnutí
- např. uvažuje vstupní data v náhodném pořadí, vybírá alternativu podle prahování na základě náhodného čísla
- v určitém momentu dělá náhodný výběr
- inkrementální - náhodné pořadí vkládání
- D&C - náhodný výběr vzorku
- obvykle jednodušší implementace, v praxi často rychlejší
Převod na nerandomizovaný alg.
- není jasné, jestli je to vždy možné bez zhoršení výkonu
- není znám žádný randomizovaný polynomiální algoritmus pro NP-úplné problémy
- existují problémy, kde je znám účinný randomizovaný algoritmus, ale není znám účinný deterministický algoritmus
- a není známo, zda jde o P nebo NP problém (např. test prvočísel)
**Dělení**
- randomizované inkrementální algoritmy
- lineární programování
- rozděl a panuj
### Vzorkování
- nezjišťujeme hodnotu pro každou osobu nebo množinu jednotek, ale jen pro některé náhodné nebo nenáhodné
- důvody: čas a peníze
- ze vzorků odhady pro celou populaci
- vzorek musí být dostatečně velký
**Náhodné vzorkování**
- u všech položek stejná pravděpodobnost výběru
- není zkleslení vlivem výběru jednotek do vzorku
- používáno u D&C - pro dělení použita náhodně vybraná podmnožina
- využíváno pro vyhledávácí datové stuktury a přibližná řešení
- typy
- jednoduché
- každá položka má stejnou šanci na zařazení do výběru
- jednoduché, pro malé aplikace snadné, pro velké problematické
- systematické (intervalové)
- mezi výběry interval, 1. index vybrán náhodně
- často v průmyslu nebo obchodu
- výhody: dobré rozložení v populaci
- nevýhody: úchylky ve struktuře => zkreslení výsledků
- stratifikované
- rozdělení populace do různých skupin (strat - věk, pohlaví, stát, ...)
- vhodné, pokud jsou skupiny jednoduché a dobře porovnatelné, přičemž uvnitř skupiny jsou podobné názory
- shlukované
- rozdělit populaci na náhodný počet shluků, do vzorku zahrnout všechny jednotky vybraných shluků
- z nevybraných shluků se nic nevybírá
- výhody: redukce ceny, vzorek lokalizován v několika shlucích
- nevýhody: méně přesné výsledky, větší vzorkovací chyba
- víceúrovňové
- jako shlukové, ale zahrnuje výběr vzorku z každého vybraného shluku (ten se nepoužije celý)
- výběr vzorků na nejméně dvou úrovních
- v 1. zvoleny velké skupiny
- ve 2. jednotky
- výhody: pohodlné, ekonomické, účinné
- nevýhody: malá přesnost kvůli vyšší vzorkovací chybě
### Jiné dělení randomizovaných
**Monte Carlo**
- vždy dostaneme odpověď, ne vždy ale správnou
- náhodnost použita pro vedení algoritmu k řešení rychlejším způsobem s rizikem chyby
- nelze určit, zda odpověď algoritmu je správná
- můžeme algoritmus spouštět opakovaně a srovnat výsledky
- výstup chápán jako náhodná proměnná
- příklad: ověření prvočísla
- využijeme hledání dělitele - $a$ z intervalu $2\dots n/2$ takové, že $n$ je dělitelné $a$
- randomizovaný algoritmus
- vzorkuje se 10 čísel z intervalu, podle toho odpoví
- typy
- s jednostrannou chybou
- pouze pro rozhodovací problémy
- neřekne ano, pokud nemá požadovanou vlastnost
- někdy řekne ne, i když má tuto vlastnost
- velmi praktické, drastická redukce složitosti
- s oboustrannou chybou
- nechat algoritmus běžet $t$-krát a vzít převažující výsledek
- s neohraničenou chybou
- obecný randomizovaný algoritmus
- může potřebovat exponenciální počet běhů pro podstatný nárůst pravděpodobnosti úspěchu
**Las Vegas**
- vždy správná odpověď, ale náhodná doba běhu
- náhodnost využita k nalezení kratší cesty ke správné odpovědi
- někdy selže - vybraná cesta nevede k řešení
- složitost lze chápat jako náhodnou proměnnou
- lze jej změnit na Monte Carlo tím, že se po stanoveném čase ukončí a vydá libovolnou odpověď
- příklady
- randomizovaný quicksort
## Náhodná čísla
- na deterministickém zařízení nelze dosáhnout úplné náhodnosti, můžeme doufat jen v pseudonáhodná čísla
- **špatný generátor** - vážné důsledky (obzvláště v kryptografii)
- nejčastěji lineární kongruentní generátor
- $R_{n} = (aR_{n-1} + c) \mod n$
- pro 32 bitů: $R_{0} = 0, a = 1366, c = 150889$
- hodnoty bez znalosti teorie neměnit

View file

@ -0,0 +1,38 @@
# Dynamické programování
- trochu jako D&C, ale jde zdola nahoru, každý podproblém řeší jen 1x
- v tabulce uložena nejlepší dílčí řešení, kombinují se pro získání větších řešení
- **dynamika** - pro problémy, kde je čas výpočtu a pořadí operací důležité
- tak trochu kombinace brutální síly a žravé strategie (greedy)
- minimalizace úsilí důsledným využíváním dílčích výsledků
Příklad: $n$-té Fibbonaciho číslo
- DP spočte
- $F(0), F(1), F(2) = F(1) + F(0), \dots F(n) = F(n-1) + F(n-2)$
- $\implies O(n)$
- D&C spočte
- $F(n), F(n-1), F(n-2), F(n-2), \dots$
- $\implies O(2^n)$
- některé dílčí výsledky se počítají zbytečně víckrát
Příklady
- nejdelší rostoucí posloupnost
- problém dělení
**Použitelnost DP**
- problém výhodný pro DP:
- princip optimality - podstatný je stav, ne způsob, jakým se do něj došlo
- důležitá je cena operací, ne samotné operace
- většina kombinatorických problémů
- největší omezení
- počet dílčích řešení, která je nutno sledovat
- potřebujeme zastavovací místa, implicitní pořadí prvků
- pokud není splněno, máme exponenciální počet možných dílčích řešení a nedostatek paměti
**Typický problém pro DP**
- dekomponovatelný do posloupnosti rozhodnutí, přijatých v různých etapách
- každá etapa má určitý počet možných stavů
- rozhodnutí nás převádí ze stavu v jedné etapě do stavu v druhé etapě
- nejlepší posloupnost rozhodnutí v určité etapě je nezávislá na rozhodnutích v dřívějších etapách
- cena přechodu mezi stavy v různých etapách je jasně definována
- existuje rekurentní vztah pro výběr nejlepšího rozhodnutí

View file

@ -0,0 +1,82 @@
# Data stream algoritmy
- **streaming algorithm** - vstupem proud dat přicházející postupně po jedné položce
- zaměženy na minulost - spočítat nějakou funkci dat
+ oproti tomu **online algoritmy** - jak naše rozhodnutí ovlivní budoucnost
+ vypadá snadné, ale nemáme místo na všechna data, jen $O(\log n)$ nebo dokonce $O(1)$ paměti
- **data stream** - data přicházejí rychle, takže
- obtížné předat je programu všechna
- obtížné spočítat složitější funkce na velkých částech vstupu
- obtížné je dočasně nebo trvale ukládat
- neformálně: streaming zahrnuje
- malý počet průchodů daty (obvykle jeden)
- sublineární paměť
- sublineární čas na výpočet (někdy)
+ podobné dynamickým, online, aproximačním nebo randomizovaným algoritmům, ale s více omezeními
+ nesměšovat s algoritmy pro vnější paměť
- tam data v souborech, pomalé, ale přes všechny potíže se k nim lze dostat opakovaně, ukládat atd.
Jak zvládat taková data?
- **paralelizace**
- často vysoce paralelizovatelné úlohy, kromě ukládání
- **řízení datové rychlosti vzorkováním**
- experimenty s částicemi s vysokou energií v CERNu (TB/s dat redukováno HW v reálném čase na GB/s)
- **zaokrouhlení datových struktur na bloky**
- např. hledání podvodů v telefonní síti - užití grafu až do velikosti 1 dne a srovnávání s přechozím dnem
- **hierarchická detailní analýza**
- **kladení si imaginativních otázek**
- může přinést nová řešení
Aplikace
- sítě
- např. routery - sledují pakety, cca milión za sekundu, moc velké na uložení, ale chceme spočítat např. kam jdou, kde odmítány služby atd.
- databáze
- sledování updatů a dotazů, chceme statistiku, např. které položky nejčastěji požadovány atd.
Typická úloha
- stream permutovaných čísel z $\{1\dots n\}$, jedno vyřazeno, uhodnutí které
## Data stream modely
Vstupní data $a_{1}, a_{2}, \dots$ přicházejí sekvenčně, prvek po prvku, a popisují signál $A, 1D$ funkci $A:[1\dots N] \to R$.
Modely se liší způsobem popisu $A$.
**Time Series Model**
- $a_{i} = A[i]$, objevují se v rostoucím pořadí $i$
- vhodný model pro časové pospoupnosti, kde např. sledujeme provoz na IP adrese každých 5 minut, objem burzovních obchodů každou minutu apod.
**Cash Register Model**
- $a_{i}$ jsou inkrementy k $A[j], a_{i} = (j, I_{i}), I_{i} \geq 0$
- tj. $A_{i}[j] = A_{i-1}[j] + I_{i}$, kde $A_{i}$ je stav signálu po shlédnuté $i$-té položky ve streamu
- více $a_{i}$ může postupně inkrementovat jeden $A[j]$
+ patrně nejpopulárnější model pro aplikace typu monitorování IP adres, které přistupují k webserveru - mohou přistupovat vícekrát
**Turnstile Model**
- $a_{i}$ jsou updaty $A[j], a_{i} = (j, U_{i})$
- tj. $A_{i}[j] = A_{i-1}[j] + U_{i}$, kde $U_{i}$ může být kladné i záporné
- nejobecnější model pro apliakce typu sledování cestujících v podzemce - turniket sleduje přicházející i odcházející
- vhodné pro plně dynamické úlohy
- těžké získat nějaké řešení v tomto modelu
+ někdy $A_{i}[j] \geq 0$ - **strict Turnstile model**
+ tj. lidé odcházejí jen tím turniketem, kterým přišli
+ naopak **non-strict Turnstile model**
+ $A_{i}[j] < 0$ pro nějaké $i$: např. signál nad rozdílem dvou cash registerových streamů
## Příklady
- náhodné vzorkování s rezervoárem
- iceberg queries
- počet vzájemně různých položek
- konstrukce shluků (clusterů) bodů
Data stream řešení
- sticky sampling
- lossy counting
Zlepšení
- sample and count
- lossy counting