1 / 38

Teorie složitosti

Teorie složitosti. I když je problém rozhodnutelný (řešitelný algoritmicky), může mít příliš velké nároky na čas výpočtu nebo paměť, a může se tedy stát, že bude prakticky nerealizovatelný

Download Presentation

Teorie složitosti

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Teorie složitosti • I když je problém rozhodnutelný (řešitelný algoritmicky), může mít příliš velké nároky na čas výpočtu nebo paměť, a může se tedy stát, že bude prakticky nerealizovatelný • Přestože často mluvíme o tom, že určitý algoritmus je „rychlý“ a jiný naopak „pomalý“, bylo by vhodné mít k dispozici určitou charakteristiku, která nám umožní různé algoritmy porovnávat • Touto charakteristikou je časová (paměťová) složitost • Samozřejmě lze příslušné algoritmy naprogramovat, testovat jejich chování na různých instancích problému, měřit čas výpočtu (či využití paměti) a potom usuzovat na příslušné charakteristiky, ale to není příliš efektivní ani „praktické“

  2. Časová složitost • Odhlédneme-li od konkrétního hardwaru i softwarového prostředí, v němž je příslušný algoritmus implementován, můžeme časovou složitost charakterizovat počtem operací stroje, které je nutné během výpočtu provést • Nejde nám o přesný počet operací, ale o obecné vyjádření trendu růstu počtu operací stroje v závislosti na velikosti vstupních dat • Nechceme počítat přesný čas výpočtu pro data určité délky, ale spíše znát odpověď na otázku, kolikrát déle bude trvat výpočet jestliže vstupní data budou například desetkát větší než obvykle (eventuálně při testování programu).

  3. Časová složitost • Délka výpočtu samozřejmě závisí i na některých dalších parametrech a konkrétním charakteru úlohy Pro třídící algoritmus může být velký rozdíl, zda je posloupnost již téměř setříděná, nebo naopak setříděná zcela opačně; u grafu může být u některých úloh důležitý například maximální stupeň vrcholu; matice o stejném rozměru může být řídká nebo naopak hustá atd. • Stejný algoritmus může proto „běžet“ mnohem déle na nejnepříjemnějších datech a naopak být poměrně rychlý na datech jiných (a přesto budou vždy délky n)

  4. Časová složitost • Většinou mluvíme o složitosti v nejhorším případě (pesimistická složitost), kdy dosažený výsledek platí univerzálně, ale někdy se užívá i průměrná složitost, kdy se na základě pravděpodobnosti výskytu určitých dat zjišťuje střední hodnota složitosti výpočtu (bývá těžší odhadnout) • DEF: Nechť T je deterministický Turingův stroj, který se zastavuje na všechny vstupy. Časová složitost T je funkce f:NN, kde f(n) je maximální počet kroků, které stroj T udělá na libovolný vstup délky n.

  5. Časová složitost • Příklad: Časová složitost algoritmu pro přijímání jazyka L={0k1k| k0} • Řešení: Délka vstupních dat: k+k=2k=n 1. Příslušný TS nejprve zkontroluje, zda jde o posloupnost 0i1j k čemuž potřebuje n kroků, potom n kroků zpět na začátek pásky … 2n kroků 2. Dokud jsou na pásce nuly i jedničky: postupně vždy smaže první 0, udělá i kroků, smaže 1 a udělá i kroků zpět …1+i+1+i=2i+2 kroků pro i nul => celkem(2i+2)*n/2<(2n+2)*n/2 3. Pokud už není na pásce žádná nula, zkontroluje se, že už tam není ani žádná jednička a skončí … j+1n kroků

  6. Časová složitost Celkem: 2n + (2n+2)*n/2 + n = 3n +n2+n = n2+4n Už v předchozím počítání kroků jsme se dopouštěli jistých odhadů a zjednodušení (např. (2i+2)*n/2<(2n+2)*n/2 ) Zajímá nás asymptotická složitost, tj. uvažujeme velký rozsah vstupních dat (tedy velká n) a potom je zřejmé, že druhou část výrazu n2+4n můžeme zanedbat. n2+4nn2 Vzhledem ke kvadratické závislosti z tohoto výsledku usuzujeme, že například pro 10x rozsáhlejší vstupní data bude výpočet trvat 100x déle atd.

  7. Časová složitost • Hovoříme o takzvané asymptotické složitosti. • Přesný výpočet počtu kroků TS je zbytečně komplikovaný už i u celkem jednoduchých algoritmů. U větších programů by to bylo nemožné a my ani nepotřebujeme znát přesné číslo. • Můžeme tedy zanedbávat „drobné“ členy, které se významněji projevují při malých hodnotách n (n2+4nn2), i konstanty, kterými je funkce f násobena a které ovlivňují konkrétní číselnou hodnotu výsledku, ale nikoliv rychlost růstu (kn2n2– pořád jde o kvadratický růst a od určitého dostatečně velkého n můžeme konstantu k zanedbat) • Funkce f(n)=0.001n3roste mnohem rychleji nežg(n)=1000n2 (Pro všechna n > 1 000 000 platínežf(n) > g(n) )

  8. Časová složitost • Čas pro vykonání jednotlivých instrukcí na konkrétním hardwaru není stejný, ale jelikož jde vždy o několik taktů, můžeme i tuto skutečnost zanedbat. Stačí, pokud platí předpoklad, že existuje konstanta k, která omezuje maximální počet taktů pro vykonání jedné instrukce. • Někdy zase můžeme výpočet složitosti zjednodušit tím, že zcela zanedbáváme některé instrukce. U třídících algoritmů například počítáme obvykle jen instrukce porovnávání klíčů a nikoliv už instrukce případné výměny prvků, jelikož je jich nejvýše stejně jako instrukcí porovnání (n+n=2n n) • Obecně lze říci, že pokud existuje konstanta k, která omezuje počet „pomocných“ instrukcí vzhledem k počtu instrukcí, které bereme v úvahu, můžeme ty „pomocné“ zanedbat.

  9. Značení O, ,  • Díky soustředění se na „rozhodující“ člen výrazu a zanedbávání podrobností můžeme zavést a využívat následující pojmy. • DEF: Pro libovolné dvě funkce f, g: NN řekneme, že fO(g) (čteme „f je ve velkém O g“ či zjednodušeně „f je velké O g“), právě když kN n0N n>n0 : f(n)  kg(n) • Pokud fO(g), říkáme také, že funkce froste řádově nejvýše jako funkce g (funkce g je horní odhad funkce f)

  10. Značení O, ,  • Příklad 1: Funkce f(n)=6n+7. Jistě platí f(n)O(n) • (stačí k=7 a n0 =7, protože f(7)=g1(7)=49 a potom už f(n)<g1(n))

  11. Značení O, ,  • DEF: Pro libovolné dvě funkce f, g: NN řekneme, že f(g) (čteme „f je ve velkém  g“ či zjednodušeně „f je velké  g“), právě když kN n0N n>n0 : f(n)  kg(n) • Pokud f(g), říkáme také, že funkce froste řádově nejméně jako funkce g (funkce g je dolní odhad funkce f) • DEF: Pro libovolné dvě funkce f, g: NN řekneme, že f(g) (čteme „f je ve velkém  g“ či zjednodušeně „f je velké  g“), právě když fO(g) a současně f(g). • Pokud f(g), říkáme také, že funkce froste asymptoticky řádově stejně rychle jako funkce g.

  12. Značení O, ,  • Příklad 1: Funkce f(n)=6n+7. Jistě platí f(n) (n) • (stačí k=6 a n0 =1, protože a potom f(n)>g2(n))

  13. Značení O, ,  • Příklad 1: Funkce f(n)=6n+7. Jistě platí f(n) (n) • (pro všechna n >n0 =7 platí g1(n)>f(n)>g2(n))

  14. Různá složitost • DEF: Funkci f říkáme lineární, pokud platí f (n), kvadratická, pokud platí f (n2), logaritmická, pokud platí f (log n), polynomiální, pokud platí f (nc) pro nějaké c>0, exponenciální, pokud platí f (cn) pro nějaké c>1. • Příklad 2:Funkce f(n)=999999n2 se ve srovnání s funkcí g(n)=2n zdá být dosti velká, ale stačí zvolit například n=30 a g(30)>f(30) f(29)=840999159g(29)=229=536870912 f(30)=899999100g(30)=230=1073741824f(1000)=999999000000g(1000)=21000 10300

  15. Značení O, ,  Příklad 2: Funkce f(n)=999999n2 ve srovnání s funkcí g(n)=2n

  16. Značení O, ,  • Příklad 3: Funkce h(n)=3n2+15n+9. Platí f(n) (n2) • (pro všechna n >n0 =16 platí g2(n)>f(n)>g1(n))

  17. Složitost algoritmu • Příklad 4: Jakou složitost má algoritmus pro výpočet aritmetického průměru n čísel? Řešení: prumer(X,n) pom:=0 fori:=1 ton do pom:=pom+X[i] return pom/n Máme n čísel v poli X a cyklus for se vykoná n-krát, takže n-krát se bude přičítat číslo, n-krát se bude inkrementovat i a kdybychom chtěli být opravdu korektní, n+1-krát se bude porovnávat i<n; potom ještě závěrečné dělení je 1 instrukce. Celkem tedy f(n)= 3n+2 a platí f (n) => lineární složitost

  18. Složitost algoritmu • Příklad 5: Jakou složitost má algoritmus: prg2(n) fori:=1 ton*n doforj:=1 toi doprint „ahoj“ Řešení: Vnější cyklus for vykoná n2-krát, počet iterací vnitřního cyklu závisí na proměnné i vnějšího cyklu. Vnitřních iterací (a tisků) proběhne tedy 1+2+3+….+n2= n2(n2+1)/2 Celkem tedy f(n)= (n4+ n2)/2 Platí f (n4) => polynomiální složitost

  19. Složitost algoritmu • Příklad 6: Jakou složitost má algoritmus přímého zatřiďování n čísel? Řešení: Nalezení největšího prvku v poli proběhne v jednom průchodu polem … n kroků (uvažuji jen porovnávání,ostatní instrukce zanedbávám). Pro druhý největší prvek už to bude jen n-1 kroků, … Celkově tedy n+ n-1 +….+3+2+1= n(n+1)/2 kroků Potom f(n)= (n2+ n)/2 Platí f (n2) => kvadratická složitost

  20. Složitost algoritmu • Příklad 7: Jakou složitost má algoritmus bublinkového třídění n čísel? Řešení: Pokud je posloupnost setříděná, projde se pole jednou, není co „probublávat“ a třídění končí … O(n) V případě, že posloupnost je setříděná opačně (největší prvek je první) při prvním průchodu se dostane (propadne) první prvek na své (poslední) místo … n kroků Při k-tém průchodu se „usadí“ k-tý prvek … n kroků Při n-tém průchodu se již jen ověří, že je „uspořádáno“… n Celkově tedy n+ n +….+n+n= nnkroků Potom f(n)= n2, platí f (n2) => kvadratická složitost

  21. Složitost algoritmu • Příklad 8: Jakou složitost má algoritmus quicksort? • Řešení: Pokud je pivot volen ideálně tak, že v každém kroku se posloupnost dělí vždy na dvě poloviny, bude existovat log2núrovní a na každé procházím celkem nejvýše n prvků: Celkově tedy nlog2nkroků a f (nlog2n)

  22. Složitost algoritmu • Pokud je však pivot volen vždy tak, že je nejmenším (nebo největším) prvkem v příslušné posloupnosti (tj. nejhorším možným způsobem), vypadá situace následovně: Potom je počet kroků celkově n+ n-1 +….+3+2+1= n(n+1)/2 a tedy f (n2). Takový případ je ale naštěstí málo pravděpodobný, průměrná složitost algoritmu quicksort je f(nlog2n) a patří k nejrychlejším třídícím algoritmům.

  23. Složitost algoritmu • Praktický rozdíl mezi použitím quicksortu a bublesortu - setřídění náhodně vygenerovaného seznamu o velikosti N: • ?- test. ?- test. • Zadej N: 100. Zadej N: 500. • Quicksort... Quicksort... • 8 : 58 : 52 : 11 8 : 59 : 00 : 39 • 8 : 58 : 52 : 11 (---) 8 : 59 : 00 : 42 (3ss) • Bublesort... Bublesort... • 8 : 58 : 52 : 11 8 : 59 : 00 : 42 • 8 : 58 : 52 : 78 (67ss) 9 : 00 : 07 : 49 (1min7s7ss)

  24. Složitost algoritmu Vhodnost použití datových struktur: • Vyhledání prvku v seznamu (poli): • Podle hodnoty klíče to může být sice hned první prvek pole, ale může to být i prvek poslední (n kroků). Zajímá nás pesimistický odhad, a proto f O(n).

  25. Složitost algoritmu • Vyhledání prvku v binárním vyhledávacím stromu: Podle hodnoty klíče může být hledaným prvkem sice hned kořen stromu, ale v nejhorším případě projdeme cestu délky log2(n+1). Proto fO(log2n).

  26. Složitost algoritmu • Příklad 9: Jakou složitost má algoritmus pro zjištění, že graf G=(V,E) s n vrcholy a m hranami je souvislý? • Algoritmus: 1. Vezmi libovolný vrchol vi a nechť S={vi} a Pom=Ø 2. Najdi všechny vj, pro které existuje hrana (vi,vj) a přidej každé vjS a vjPom do Pom 3. Jestliže Pom=Ø konec a jestliže |S|=n „graf je souvislý“, jinak „nesouvislý graf“ 4. Vyjmi libovolné viPom, přidej jej do množiny S a pokračuj krokem číslo 2. • Složitost: fO(nm)

  27. Složitost algoritmu • Úloha: Je dáno n čísel. Je možné z nich vybrat podmnožinu takovou, že součet těchto čísel je S? • Př.: {1,3,5,15,19} S=27 (ano 3+5+19=27), S=26 (ne) • Algoritmus: Je nutné vyzkoušet všechny možnosti: 0c1+0c2+…+ 0cn-1+0cn =? [0,0,…,0,0] 0c1+0c2+…+ 0cn-1+1cn =?[0,0,…,0, 1] 1c1 + 1c2+ … +1cn-1+1cn =?[1, 1,…, 1, 1] V nejhorším případě je nutné vyzkoušet 2n možností. • Složitost je tedy: f O(2n )

  28. Doba výpočtu pro různé složitosti • Čas výpočtupři rychlosti 1 milion operací za vteřinu.

  29. Růst rozměru úlohy při daném zrychlení procesoru • Předpokládejme, že v daném okamžiku jsme v čase T schopni řešit úlohu o rozměru n=100. Tabulka udává rozměr úlohy řešitelné ve stejném čase T na počítači s x-krát rychlejším procesorem.

  30. Praktický pohled na složitost • Úlohy řešitelné v polynomiálně omezeném čase považujeme za prakticky řešitelné, zatímco úlohy s exponenciální složitostí jsou již pro relativně malé hodnoty n prakticky nezvládnutelné. • Pro programátora je samozřejmě důležité, zda algoritmus, který programuje, má složitost O(n), O(n2) nebo O(n4), ale z teoretického hlediska je zásadní rozdíl mezi složitostí polynomiální („rychlé“ algoritmy) a složitostí exponenciální. • Algoritmus se složitostí O(n1000) samozřejmě nelze považovat za rychlý, ale pro většinu praktických problémů řešitelných v polynomiálně omezeném čase známe algoritmy s relativně nízkým stupněm polynomu.

  31. Praktický pohled na složitost • Většinou se ukazuje, že jestliže pro určitý problém existuje algoritmus řešící daný problém v polynomiálně omezeném čase, na základě důkladné analýzy a pochopení podstaty problému se podaří navrhnout prakticky použitelný algoritmus s rozumným stupněm polynomu. • Pro libovolnou třídu složitosti O(nk), kde k>0lze samozřejmě zkonstruovat problém, který není řešitelný v čase O(nk), ale dá se řešit v čase O(nk+1). Naštěstí jde o uměle konstruované problémy bez praktického využití.

  32. Teoretický pohled na složitost • Z teoretického hlediska není nutné se zabývat rozdílem mezi algoritmy se složitostí O(n) a O(n3), neboť je považujeme za dostatečně rychlé a zvládnutelné. • Proto můžeme přistoupit k zjednodušujícímu pohledu na celou problematiku, kdy zanedbáme rozdíly mezi různými stupni polynomiální složitosti a budeme nadále uvažovat pouze dvě třídy problémů – třídu se složitostí polynomiální a třídu s exponenciální složitostí. • Algoritmy s exponenciální složitostí jsou typicky spjaté s tzv. metodou „hrubé síly“ (brute-force search), kdy se pokoušíme řešit problém úplným prohledáním celého stavového prostoru (tj. vyzkoušením všech možností).

  33. Třída P (PTIME) • DEF: Nechť t:NR+ je funkce. Časová třída složitosti TIME(t(n)) obsahuje všechny jazyky, které jsou rozhodnutelné Turingovým strojem v čase O(t(n)). • Příklad: Třída TIME(n2) obsahuje všechny jazyky,které jsou rozhodnutelné Turingovým strojem v čase O(n2). • Platí: TIME(log2n) TIME(n) TIME(n log2n) TIME(n2) TIME(n3) …

  34. Třída P (PTIME) • DEF:P je třída všech jazyků, které jsou rozhodnutelné deterministickým Turingovým strojem v polynomiálním čase. Neboli: • Třída P je velmi významná v teorii složitosti, protože: 1. Je nezávislá na zvoleném výpočetním modelu (za podmínky, že model je polynomiálně ekvivalentní deterministickému Turingovu stroji) 2. V podstatě odpovídá třídě úloh, které jsou realisticky řešitelné na počítači. Tedy: PTIME je robustní (ad 1) a má značný praktický význam (ad 2).

  35. Třída P Příklady problémů z třídy P: • Přímé zatřiďování, bublesort, heapsort,quicksort, … • Aritmetický průměr, medián, největší prvek v poli, … • Násobení matic, řešení soustavy lineárních rovnic, … • Cesta mezi dvěma vrcholy grafu, spojitost grafu, nejkratší cesta mezi dvěma vrcholy v ohodnoceném grafu, minimální kostra grafu, … • Hledání maximálního toku v síti, … • Úloha lineárního programování (ale pozor – simplexový algoritmus má v nejhorším případě exponenciální složitost)

  36. Cvičení • Úloha 1: Rozhodněte zda posloupnost znaků v poli délky n tvoří palindrom (slovo, které je stejné při čtení zprava i zleva). • Př.: [a,l,e,l,a][a,n,n,a] [k,r,k] [i,d,o,l,z,l,o,d,i] • Navrhněte vhodný algoritmus pro tuto úlohu • Určete složitost navrženého algoritmu • Navrhněte případně algoritmus rychlejší

  37. Cvičení • Úloha 2: V zadané posloupnosti reálných čísel délky N nalezněte úsek s maximálním součtem. • Př.: 1,3,5,-8,4,-7,15,3,-12,-8,7,-1,9,4,-6,-14,3,5,4,-17,11 • Navrhněte vhodný algoritmus pro tuto úlohu • Určete složitost navrženého algoritmu • Navrhněte případně algoritmus rychlejší

  38. Cvičení • Úloha 3: V zadané posloupnosti reálných čísel P1 délky N1 nalezněte nejdelší úsek, který neobsahuje žádný prvek z druhé zadané posloupnosti P2 o délce N2. • Př.: P1: 1,3,5,-8,4,-7,15,3,-12,-8,7,-1,9,4,-6,-14,3,5,4 P2: 3,11,4,25,-12,-1,5,41,17,-22,13 • Navrhněte vhodný algoritmus pro tuto úlohu • Určete složitost navrženého algoritmu • Navrhněte případně algoritmus rychlejší

More Related