6.1 KiB
6.1 KiB
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 časecn^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í):
- 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čí?
- 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é?)
- 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?
- 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?
- 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í?
- Jsem stále ztracen(a)?
- Nenajmu si na to experta?
- Nezkusím otázky projít znova? (Změnily se moje odpovědi?)