FAV-ZCU/KIV PRO/01. Programátorské strategie.md

123 lines
6.1 KiB
Markdown

# 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?)