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

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