TGH01 - Algoritmizace Jan Březina Technical University of Liberec 28. února 2017
Co je to algoritmus? Porovnávání algoritmů
Porovnávání algoritmů Co je to algoritmus? Který algoritmus je lepší? Záleží na kritériu:
Porovnávání algoritmů Co je to algoritmus? Který algoritmus je lepší? Záleží na kritériu: Rychlost výpočtu (časová složitost)
Porovnávání algoritmů Co je to algoritmus? Který algoritmus je lepší? Záleží na kritériu: Rychlost výpočtu (časová složitost) Pamět ová náročnost (pamět ová složitost)
Porovnávání algoritmů Co je to algoritmus? Který algoritmus je lepší? Záleží na kritériu: Rychlost výpočtu (časová složitost) Pamět ová náročnost (pamět ová složitost) Složitost implementace (rychlost implementace)
Porovnávání algoritmů Co je to algoritmus? Který algoritmus je lepší? Záleží na kritériu: Rychlost výpočtu (časová složitost) Pamět ová náročnost (pamět ová složitost) Složitost implementace (rychlost implementace) Robusnost (odolnost vůči chybám vstupu)
Složitost algoritmu jako funkce vstupu Maximální zjednodušení: vstup má velikost n ( např. bytů) výpočet trvá T (n) elementárních kroků (např. instrukcí) a potřebuje M(n) jednotek paměti ( např. bytů)
Porovnání různých složitostí Pro seriový počítač s frekvencí 1GHz (10 9 operací za sekundu) T (n) n = 10 100 1000 1000000 za 1 hodinu log n 3.3ns 6.7ns 10ns 20ns n 3.2ns 10ns 32ns 1µs 10 25 (1000x world) n 10ns 100ns 1µs 1ms 10 12 (TB) n log n 33ns 664ns 10µs 20ms 10 11 n 2 100ns 10µs 1 ms 17min 10 6 (MB) n 3 1µs 1ms 1s 31let 15000 2 n 1µs 41 n! 3ms 15 Závěr: Na konstantě nezáleží.
O(n) notace Necht g a f jsou dvě reálné funkce reálné proměnné. g(n) = O(f(n)) pokud existuje konstanta C, že pro dost velká n je g(n) < Cf(n) g(n) = Ω(f(n)) pokud existuje konstanta c, že pro dost velká n je g(n) > cf(n) g(n) = Θ(f(n)) pokud platí g(n) = O(f(n)) i g(n) = Ω(f(n)) Přesnější notace: g O(f), g patří do funkcí asymptotocky menších než f, g f, g je asymptoticky menší než f
Počítání, pro f i O(g i (n)): Vlastnosti Příklady: analogie T f, př: analogie T f, př: f 1 f 2 = O(g 1 g 2 ) f 1 + f 2 = O(g 1 + g 2 ) = O(max(g 1, g 2 )) f(h(n)) = O(g(H(n))) H(f(n)) = O(H(g(n))) f(n) f(n) = O(g(n)) lim n g(n) < n 2 + log(n) = O(n 2 ), = O(n 3 ), O(n log(n)) n 2 + log(n) = Θ(n 2 ), Ω(n 3 ), = Ω(n log(n))
Asymptotická složitost Algoritmus má asymptotickou časovou složitost O(f(n)) pokud pro dobu běhu jakožto funkce velikosti vstupních dat T (n), platí Vlastnosti: T (n) O(f(n)). Nezávisí na rychlosti počítače (ukrytá v konstantě). Nezávisí na kvalitě překladače, zručnosti programátora. Charakterizuje chování v nejhorším případě. Pomíjí členy nižšího řádu. Platí pouze pro dost veliká data.
Příklad binární vs. Finonačiho halda Složitost operací používaných v Dijkstrově algoritmu Binární halda Fibonacci halda Odeber Min. O(lg n) O(lg n) Zmenšení Kĺıče O(lg n) O(1) Praxe, Boost C++ library: Generating graph...10 000 vertices, 20 000 000 edges. Running Dijkstra s with binary heap...1.46 seconds. Running Dijkstra s with Fibonacci heap...1.31 seconds. Speedup = 1.1145.
Určení složitosti algoritmu function InsertSort (A[1:n]) for i = 2... len(a) do key = A[i] j = i-1 while j > 0 and A[j] > key do A[j+1] = A[j] j = j - 1 A[j+1] = key
Dolní odhad složitosti třídění (složitost třídění) Rozhodovací strom: Počet uspořádání - listů je n! Výška stromu: log n! = log n + log(n 1) +... log 2 + log 1 n/2 log(n/2) cn log(n)
Jiné druhy složitosti Průměrná složitost složitost průměrovaná přes možné vstupy quicksort asymptotocká složitost O(n 2 ) průměrná složitost O(n log n) Amortizovaná složitost složitost pro vleké množství opakovaných operací příklad, dynamické pole (std::vector)
Složitost rekurzivních algoritmů function Rekurze (A[1:n]) Θ(n); Rekurze (A[1:n/2]); Rekurze (A[n/2:n]) T (n) = 2T (n/2) + Θ(n), T (1) = 1 Theorem (Master theorem) Pokud T (n) = at (n/b) + f(n), a 1, b > 1 1. f(n) = O(n log b a ε ), pak T (n) = Θ(n log b a ) 2. f(n) = Θ(n log b a), pak T (n) = Θ(n log b a lg(n)) 3. f(n) = Ω(n log b +ε ), pak T (n) = Θ(f(n)) Složitost Rekurze je tedy případ 2, Θ(nlgn).
Pseudokód Bloky FOR, IF, WHILE vyznačeny odsazením a vertikální čarou. Hodnota čítače ve FOR má první neplatnou hodnotu po konci cyklu. // Komentář Přiřazení - porovnání -= Přístup k prvkům pole: A[i] Sekvence: 1..4, A[1..4] Atributy objektů: A.size, Child.parent Předávání parametrů funkcí hodnotou. Zkrácené vyhodnocování AND a OR.
Insert sort function InsertSort (A[1:n]) for i = 2... len(a) do key = A[i] j = i-1 while j > 0 and A[j] > key do A[j+1] = A[j] j = j - 1 A[j+1] = key
Důkaz správnosti algoritmu Invariant: Vlastnost dat, která: platí na počátku (po inicializaci) zachovává se její platnost na konci implikuje splnění úkolu
Správnost insert sortu Invariant: Na začátku for cyklu obsahuje A[1... i 1] prvních i 1 prvků původního pole, setříděných. Inicialiazace: První prvek původního pole tvoří setříděnou posloupnost délky 1. Zachování: Do cyklu vstupuje setříděná posloupnost prvků A[1... i 1]. Z cyklu vystupuje setříděná posloupnost prvků A[1... i]. Ukončení: For cyklus skončí pro i = n + 1, pole A[1... n] obsahuje setříděnou poslouponst prvků celého původního pole.