1 Algoritmus. 1.1 Úvod

Podobné dokumenty
10. Složitost a výkon

Algoritmus. Přesné znění definice algoritmu zní: Algoritmus je procedura proveditelná Turingovým strojem.

Databáze, sítě a techniky programování X33DSP

Složitost 1.1 Opera ní a pam ová složitost 1.2 Opera ní složitost v pr rném, nejhorším a nejlepším p ípad 1.3 Asymptotická složitost

Základy algoritmizace

Složitost Filip Hlásek

Složitost. Teoretická informatika Tomáš Foltýnek

Seminář z IVT Algoritmizace. Slovanské gymnázium Olomouc Tomáš Kühr

Algoritmy a výpočetní složitost

Úvod do informatiky. Miroslav Kolařík

Definice 9.4. Nedeterministický algoritmus se v některých krocích může libovolně rozhodnout pro některé z několika možných různých pokračování.

Vztah teorie vyčíslitelnosti a teorie složitosti. IB102 Automaty, gramatiky a složitost, /31

Algoritmizace. Jiří Vyskočil, Marko Genyg-Berezovskyj 2010

Třídy složitosti P a NP, NP-úplnost

Algoritmy I, složitost

Pojem algoritmus. doc. Mgr. Jiří Dvorský, Ph.D. Katedra informatiky Fakulta elektrotechniky a informatiky VŠB TU Ostrava

Úvod do informatiky. Miroslav Kolařík

PŘÍJMENÍ a JMÉNO: Login studenta: DATUM:

Algoritmizace. 1. Úvod. Algoritmus

3. Třídy P a NP. Model výpočtu: Turingův stroj Rozhodovací problémy: třídy P a NP Optimalizační problémy: třídy PO a NPO MI-PAA

ALGORITMY A DATOVÉ STRUKTURY

Časová složitost / Time complexity

Třída PTIME a třída NPTIME. NP-úplnost.

Základy algoritmizace, návrh algoritmu

NP-úplnost problému SAT

Obecná informatika. Matematicko-fyzikální fakulta Univerzity Karlovy v Praze. Podzim 2012

Od Turingových strojů k P=NP

Třída PTIME a třída NPTIME. NP-úplnost.

Algoritmy a algoritmizace

Definice 7.2. Nejmenší přirozené číslo k, pro které je graf G k-obarvitelný, se nazývá chromatické číslo (barevnost) grafu G a značí se χ(g).

Týden 11. Přednáška. Teoretická informatika průběh výuky v semestru 1. Nejprve jsme dokončili témata zapsaná u minulé přednášky.

11 VYPOČITATELNOST A VÝPOČTOVÁ SLOŽITOST

Algoritmy. Z. Sawa (VŠB-TUO) Úvod do teoretické informatiky 15. dubna / 39

Michal Krátký. Úvod do programování. Cíl kurzu. Podmínky získání zápočtu III/III

3 Co je algoritmus? Trocha historie Definice algoritmu Vlastnosti algoritmu... 3

Dynamické programování

Vyhledávání. doc. Mgr. Jiří Dvorský, Ph.D. Katedra informatiky Fakulta elektrotechniky a informatiky VŠB TU Ostrava. Prezentace ke dni 21.

Složitost algoritmů. doc. Mgr. Jiří Dvorský, Ph.D. Katedra informatiky Fakulta elektrotechniky a informatiky VŠB TU Ostrava

Složitost algoritmů. Karel Richta a kol. Katedra počítačů Fakulta elektrotechnická České vysoké učení technické v Praze Karel Richta a kol.

Rozhodnutelné a nerozhodnutelné problémy. M. Kot, Z. Sawa (VŠB-TU Ostrava) Úvod do teoretické informatiky 24. dubna / 49

Časová a prostorová složitost algoritmů

V každém kroku se a + b zmenší o min(a, b), tedy vždy alespoň o 1. Jestliže jsme na začátku dostali 2

Výpočetní složitost algoritmů

NP-ÚPLNÉ PROBLÉMY. Doc. RNDr. Josef Kolář, CSc. Katedra teoretické informatiky, FIT České vysoké učení technické v Praze

Dijkstrův algoritmus

NMIN101 Programování 1 2/2 Z --- NMIN102 Programování /2 Z, Zk

Vlastnosti algoritmu. elementárnost. determinovanost. rezultativnost. konečnost. hromadnost. efektivnost

Digitální učební materiál

Vyhledávání. doc. Mgr. Jiří Dvorský, Ph.D. Katedra informatiky Fakulta elektrotechniky a informatiky VŠB TU Ostrava. Prezentace ke dni 12.

Výukový materiál zpracován v rámci projektu EU peníze školám

Algoritmy a výpočetní složitost

4. NP-úplné (NPC) a NP-těžké (NPH) problémy

Algoritmizace prostorových úloh

Různé algoritmy mají různou složitost

Algoritmizace. Obrázek 1: Přeložení programu překladačem

Úvod do informatiky. Miroslav Kolařík

Test prvočíselnosti. Úkol: otestovat dané číslo N, zda je prvočíslem

Algoritmizace- úvod. Ing. Tomáš Otáhal

Problém obchodního cestujícího(tsp) Vstup: Množina n měst a vzdálenosti mezi nimi. Výstup: Nejkratší okružní cesta procházející všemi městy.

Algoritmus pro hledání nejkratší cesty orientovaným grafem

Vzdálenost uzlů v neorientovaném grafu

Digitální učební materiál

Algoritmus. Cílem kapitoly je seznámit žáky se základy algoritmu, s jeho tvorbou a způsoby zápisu.

Výroková a predikátová logika - XIII

Binární soubory (datové, typované)

Algoritmizace Dynamické programování. Jiří Vyskočil, Marko Genyg-Berezovskyj 2010

TGH12 - Problém za milion dolarů

Operátory pro maticové operace (operace s celými maticemi) * násobení maticové Pro čísla platí: 2*2

Věta o dělení polynomů se zbytkem

Prohledávání do šířky = algoritmus vlny

Úvod do programování

doplněk, zřetězení, Kleeneho operaci a reverzi. Ukážeme ještě další operace s jazyky, na které je

Programování: základní konstrukce, příklady, aplikace. IB111 Programování a algoritmizace

NMIN101 Programování 1 2/2 Z --- NMIN102 Programování /2 Z, Zk

Z. Sawa (VŠB-TUO) Teoretická informatika 18. prosince / 67

Pojem algoritmus a jeho základní vlastnosti

Časová složitost algoritmů

Digitální učební materiál

Náplň. v Jednoduché příklady na práci s poli v C - Vlastnosti třídění - Způsoby (algoritmy) třídění

IB111 Úvod do programování skrze Python

TGH05 - Problém za milion dolarů.

Výroková a predikátová logika - II

Týden 14. Přednáška. Teoretická informatika průběh výuky v semestru 1. PSPACE, NPSPACE, PSPACE-úplnost

Numerická stabilita algoritmů

NPRG030 Programování I 3/2 Z --- NPRG031 Programování II --- 2/2 Z, Zk

Obsah přednášky. Analýza algoritmu Algoritmická složitost Návrhy algoritmů Urychlování algoritmů 1/41

Úvod do problematiky

Usuzování za neurčitosti

Výroková a predikátová logika - III

VYŠŠÍ ODBORNÁ ŠKOLA a STŘEDNÍ PRŮMYSLOVÁ ŠKOLA Mariánská 1100, Varnsdorf PROGRAMOVÁNÍ FUNKCE, REKURZE, CYKLY

Složitost problémů. Z. Sawa (VŠB-TUO) Úvod do teoretické informatiky 25. dubna / 23

Naproti tomu gramatika je vlastně soupis pravidel, jak

Složitost a moderní kryptografie

Tato tematika je zpracována v Záznamy přednášek: str

Intervalová data a výpočet některých statistik

YZTI - poznámky ke složitosti

5.6.3 Rekursivní indexace složitostních tříd Uniformní diagonalizace Konstrukce rekursivních indexací a aplikace uniformní diagonalizace

Polynomy. Mgr. Veronika Švandová a Mgr. Zdeněk Kříž, Ph. D. 1.1 Teorie Zavedení polynomů Operace s polynomy...

Programovací jazyk Pascal

Výroková a predikátová logika - XII

Transkript:

1 Algoritmus Cílem této kapitoly je seznámi studenty se základními pojmy informatiky jako jsou algoritmus, program, složitost. Student získá také přehled o složitostních třídách problémů (algoritmů). O algoritmech toho lze říci mnoho. Nejsou vidět, ale jsou důležitou součástí našeho života a běžně je při svých činnostech používáme. Je těžké si představit, jak složitý by byl náš každodenní život složitý, pokud by algoritmy neexistovaly. 1.1 Úvod V 9. století znamenal význam slova algoritmus provádění aritmetiky za pomoci arabských číslic. Dnes se s pojmem algoritmus setkáváme nejčastěji v matematice a v programování, kde označuje sestavení teoretických principů řešení. Využívá se k tomu i mnoho již známých algoritmů. Aniž bychom si to uvědomovali, s algoritmy v podobě návodů či instrukcí se setkáváme také v mnoha běžných každodenních činnostech. Ovšem ne každý návod je algoritmus. Takto lze označit jen postupy, které splňují určité vlastnosti. 1.2 Programování (tvorba algoritmů) V praxi se pod pojem programování schovávají následující činnosti: 1. Analýza (problému) zjistit, co uživatel přesně potřebuje, přesná specifikace úlohy 2. Algoritmizace vymyslet postup, jak danou úlohu řešit 3. Programování/Kódování donutit počítač, aby tento postup realizoval 4. Testování Analýza Často největší problém, je zde nutná spolupráce se zadavatelem. Zadavatel většinou neví, co chce (i když si myslí, že ví) a zjistí, že to chtěl jinak, až když je práce (program) hotová. Proto je vhodné před započetím práce sepsat dokument (specifikace zadání), kde bude přesně uvedeno, co zadavatel požaduje. Algoritmizace Algoritmus si můžeme představit jako kuchařku pro řešení dané úlohy. Algoritmus definujeme jako konečnou posloupnost elementárních příkazů, jejichž provádění umožňuje pro každá přípustná vstupní data mechanickým způsobem získat po konečném počtu kroků příslušná výstupní data. Programování/Kódování Programem budeme nazývat algoritmus, který je zapsaný ve tvaru vhodném pro jeden konkrétní typ procesoru (počítač). Procesory pracují ve strojovém kódu který pro lidi velmi nepřehledný. Proto vznikly programovací jazyky, které můžeme chápat jako kompromis. Pro lidi je relativně dobře čitelný a je snadno přeložitelný do strojového kódu pomocí překladače (kompilátoru). Výhoda je také ta, že jednou napsaný program (v programovacím jazyce) lze přeložit do strojového kódu různých počítaču. 1

Prekladač vs. Interpret Prekladač je nástroj, který vezme zdrojový tvar programu (napsaný v programovacím jazyce) a preloží (zkompiluje) ho do strojového kódu daného procesoru (binární tvar programu). Interperet (interpreter) je nástroj, který vezme zdrojový tvar programu a jeho jednotlivé instrukce postupně vykonává. Běh programu je tak pomalejší. Příklad: Uveďte programovací jazyky které znáte a rozhodněte, do které z těchto dvou kategorií patří. Testování Ověření funkčnosti vytvořeného programu. Alfa-testování provádí tvůrce programu, betatestování provádí vybraná skupinka uživatelů (beta-testeri). Na testování nezapomínat! V některých případech je to prakticky jediná možnost, jak zjistit jestli náš program funguje tak jak má. 1.3 Historie algoritmů S ohledem na obecnost algoritmu, jako popisu libovolné běžné každodenní činnosti, sahá počátek vzniku algoritmu až ke vzniku lidstva samotného. Vždyť i činnosti pravěkých lidí měly přesně daný postup, řád, konečnost a výsledek. Postupy, které dnes splňují podmínky algoritmu, se ve vědních oborech objevily již v období starého Řecka, ačkoli v této době pojem algoritmus ještě nebyl vůbec znám. Podstatu a použití algoritmu v období cca 300 let p.n.l. dokládá např. známý Euklidův algoritmus pro výpočet NSD, tj. největšího společného dělitele, nebo v 1 století n.l. Herón z Alexandrie který algoritmicky podal důkaz vzorce pro obsah trojůhelníku, či algoritmus pro hledání odmocniny z čísla. Samotný pojem algoritmus vzniknul zhruba o tisíc let později v 9. století našeho letopočtu, a je spojován se jménem perského matematika Abú Abd Alláh Muhammad ibn Músá al-chwárizmí, který vytvořil systém arabských číslic. Prvním významem slova algoritmus tak bylo provádění aritmetiky pomocí arabských čislic a používal se k vyjádření zejména matematických postupů. Pojem algoritmus ve smyslu dnešního významu se používá zhruba od 20. století. Využití známých algoritmů Algoritmy se dnes využívají ve všech vědních oborech. Nejčastěji se s nimi ale setkáme v matematice a v programování, kde jsou nástrojem k sestavení teoretickému principu řešení daného problému. Vytváření algoritmů je v dnešní době předmětem intenzivního zkoumání a stává se i samostatným vědním oborem, při kterém se v nemalé míře využívají a dále rozvíjejí již vytvořené algoritmy, kterých existuje velmi mnoho, např.: Eratosthenovo síto je algoritmus pro nalezení všech prvočísel menších než zadaná horní mez. Dijkstrův algoritmus slouží k nalezení nejkratší cesty v grafu. Ballman-Fordovův algoritmus nám umožní spočítat nejkratší cestu od uzlu k uzlu v ohodnoceném grafu. Algoritmus de Casteljau pro výpočet bodu na Beziérově křivce. Turingův stroj Díky objevu Alana Turinga (1912-1954), který navrhl abstraktní matematický model počítače - Turingův stroj (1936/37), můžeme algoritmus definovat jako proceduru implementovatelnou pomocí Turingova stroje. TS se skládá z procesorové jednotky, tvořené konečným automatem, programu ve tvaru pravidel přechodové funkce a potenciálně nekonečné pásky pro zápis mezivýsledků. Existuje více obecných definicí Turingových strojů (jednopáskové / vícepáskové deterministické TS, nedeterministické TS, univerzální). V jednom kroku výpočtu stroj v závislosti od aktuálního stavu a od symbolu (resp. k symbolů u k-páskových TS) snímaných hlavami: 1. změní svůj stav, 2

2. zapíše symbol na každé políčko snímané hlavou (čímž přepíše symbol, který tam byl zapsaný předtím ), 3. posune každou hlavu o jedno políčko doprava nebo doleva. Způsob, kterým se má změnit stav, přepsat políčka a posunout hlavy, předepisuje přechodová funkce δ. Výpočet končí když stroj přejde do jednoho ze speciálních stop stav, na některých vstupech může výpočet stroje být nekonečný. Další zdroje: http://alan.sourceforge.net - projekt emulátoru TS http://www.warthman.com/ex-turing.htm - projekt animace činnosti TS 1.4 Algoritmy Algoritmem budeme nazývat jakýkoliv postup (návod, soupis kroků), který bude splňovat následující kritéria: 1. Elementárnost algoritmus se skládá z jednoduchých, tzv. elementárních, kroků. 2. Hromadnost, obecnost, univerzálnost algoritmus slouží k řešení celé třídy (skupiny) navzájem si podobných úloh. Úlohy jsou si podobné, ale liší se vstupními daty. Tzn. neřeší jak spočítat 3x7, ale řeší, jak spočítat součin dvou celých čísel. 3. Konečnost pro každá přípustná data algoritmus po konečném počtu kroků (může být libovolně velký) skončí. 4. Determinovanost algoritmu každý krok uvedený v algoritmu musí být jednoznačně a přesně definován. V každé situaci musí být napřosto zřejmé, co a jak se má provést a jak má provádění algoritmu pokračovat. 5. Částečná (parciální) správnost jestliže algoritmus skončí, pak výsledek je správný (tj. nestane se, že pro nějaká přípustná vstupní data algoritmus skončí se špatným výsledkem). 6. Výstup, resultativnost algoritmus musí mít alespoň jeden výstup. Říkáme, že algoritmus vede od zpracování hodnot k výstupu. Můžeme algoritmus chápat také jako funkci, která nám ke vstupu přiřadí příslušný výstup. 7. Mechanické provádění algoritmus může provádět každý bez hlubší znalosti řešené úlohy, např. procesor (umí jen základní sadu příkazů) nebo ten kdo bude vykonávat algoritmus (nemusí to být nutně počítač). 3

Druhy algoritmů Algoritmů dnes existuje celá řada a proto existuje klasifikace (roztřídění) do skupin. Rozdělení ale neplatí direktivně, a je běžné, že jeden algoritmus může patři současně i do více skupin. Mezi důležité skupiny algoritmů patří: 1. Rekurzivní algoritmy, které v rámci cyklu volají samy sebe. 2. Pravděpodobnostní algoritmy provádějí některá rozhodnutí náhodně. 3. Paralelní algoritmy lze využít v případě, kdy můžeme algoritmus rozdělit na více samostatných úloh a zpracovávat je odděleně na více strojích. Výhodou je časová úspora. 4. Genetické algoritmy, které pracují na základě napodobování biologických evolučních procesů. Pro vědu jsou přirozené procesy probíhající v přírodě velkým vzorem, protože mohou být chápány a aplikovány i jako možná řešení daného problému. 5. Heuristické algoritmy, jejichž cílem není nalézt přesné řešení daného problému. Tyto algoritmy se používají v situacích, kdy dostupné zdroje nepostačují na využití exaktních algoritmů. Ověřování správnosti algoritmu K ověření správnosti algoritmu nestačí vyzkoušet reakci algoritmu na konečný počet vstupních dat, i když se to tak v praxi často dělá a takové ověření o správnosti algoritmu leccos vypoví. Není ovšem dokázáno, že se algoritmus při neočekávané kombinaci vstupních dat nezhroutí. Pro ověřování správnosti algoritmu neexistuje univerzální metoda, algoritmus by měl být matematicky dokázán sledem předem známých kroků (operací), které nevyvratitelně vedou pro všechna přípustná data k správnému výsledku úlohy. Je zřejmé, že takový algoritmus je pak korektním řešením úlohy. Algoritmus můžeme považovat za korektní, pokud není opomenuta žádná z možností zpracování dat při průchodu algoritmem. Algoritmus je částečně (parciálně) správný, právě když platí, že pokud skončí, vydá správný výsledek. K dokázání částečné správnosti výpočtu můžeme použít tzv. invariant - tvrzení, které platí po celou dobu výpočtu. Nutné je také ověřit konečnost algoritmu (pro všechna přípustná data algoritmus po konečném počtu kroků skončí). Dokazování konečnosti algoritmu Konečnost algoritmu je často intuitivně zřejmá tím, že se pro vstupní data nemůže algoritmus zacyklit. Matematicky lze dokázat konečnost algoritmu takto: Pokud najdeme způsob, který každý stav výpočtu ohodnotí přirozeným číslem, a ukážeme, že provedením jednoho kroku algoritmu se tato hodnota zmenší, je jasné, že algoritmus po konečném počtu kroků skončí, neboť interval počtu průchodů algoritmem je konečný. Kvantitativní ukazatele kvality algoritmů Mezi dva nejdůležitější kvantitativní ukazatele kvality algoritmů patří: operační složitost paměťová složitost Příklady: Zadání: Pole S obsahuje n vzestupně seřazených prvků. Je třeba nalézt funkci typu Boolean, která vrátí hodnotu true, pokud zadaný prvek v poli S existuje, a hodnotu false v opačném případě. Řešení: Řešení hrubou silou - sekvenční hledání function sekvencni_hledani(hodnota, pole) { var existuje = false; var i = 0; while(i<pole.lenght &&!existuje) { if(pole[i] === hodnota) { existuje = true; i++; 4

return existuje; Nejhorší případ: prvek v poli není, pak tělo cyklu proběhne (n-1) krát a bude provedeno n porovnání. Cvičení: Je-li pole uspořádáno, lze využít efektivnější binární půlení, napište tento algoritmus. function binarni_hledani(hodnota, pole) { var existuje = false; var i = l = 0; var r = pole.length; while(!ret && r >= 1) { i = Math.round((l+r)/2); if(hodnota === pole[i]) { existuje = true; else { if(hodnota > pole[i]) { l = i+1; else { r = i-1; return existuje; Opět časově nejnáročnější při neexistenci prvku v poli. Cyklus while však proběhne jen (log 2 n) krát. Algoritmus je však mírně paměťově náročnější. Důležitost analýzy složitosti algoritmů Ukážeme na dvou příkladech tisku Fibonacciho posloupnosti: Fibonacci (Leonardo z Pisa) řešil reprodukční problém - kolik párů králíků může vzniknout za rok z jednoho páru, jestliže budeme předpokládat, že každý pár každý měsíc plodí nový pár, který se začne množit od druhého měsíce? Měsíc: 1 2 3 4 5 6 7 8 9 10 11 12 Počet párů: 1 1 2 3 5 8 13 21 34 55 89 144 f 0 = 0; f 1 = 1 a f n = f n -1 + f n -2 pro n > 1. Varianta 1: Rekurzivní výpočet n-tého Fibonacciho čísla: function fib(n) { return (n == 0)? 0:((n == 1)? 1 : fib(n-1) + fib(n-2)); function printfib(n) { for(var i = 1; i <= n; i++) { console.log(i + " " + fib(i)); Varianta 2: Fibonaccioho posloupnost bez rekurze: function prinfib2(n) { var p0 = p1 = p = 1; for (var i = 1; i <= n; i++) { console.log(i + " " + p0); 5

p = p1; p1 = p0 + p1; p0 = p; Pod složitostí algoritmu rozumíme tedy dobu prováděného algoritmu - časovou složitost a rozsah použité operační paměti - paměťovou náročnost (složitost). 1.5 Složitost algoritmu Složitost závisí na velikosti vstupních dat, tj. můžeme popsat jako funkci T(n), kde číslo n udává velikost vstupních dat. Např. T(n) = an + b, kde a, b jsou nějaké konstanty, je zápis lineární časové složitosti (složitost roste lineárně s rostoucí velikostí vstupů). Obvykle je pro odhad složitosti důležitý pouze typ funkční závislosti a nikoliv přesné hodnoty konstant, ty se zanedbávají. Efektivními algoritmy nazveme takové postupy, jejichž složitost je maximálně polynomiální (např. n 127, nikoliv exponenciální např. 2 n ). Provádění exponenciálních algoritmů T(n) = 2 n či dokonce algoritmů o složitosti T(n) = n! může už jen při malém navýšení velikosti vstupních dat trvat i mnoho tisíců a miliónů let. Ani polynomiální algoritmy s velkým stupněm polynomu nebo s velkými vstupními daty nejsou příliš rychlé, viz následující tabulka: V zápisu T(n) = an + b je a multiplikativní konstanta, která v sobě zahrnuje počet operací, který je třeba provést na jednotku vstupních dat. Aditivní konstanta b udává pouze konstantní nárůst složitosti nezávislý na velikosti vstupních dat. Při značné velikosti vstupních dat můžeme konstanty a a b zanedbat, protože vzhledem k velikosti n jsou nepatrné, a výsledná složitost T(n) tak závisí především na velikosti n, tj. velikosti vstupních dat algoritmu. 6

Vybereme-li ze všech konstant a největší konstantu, kterou označíme c, platí T(n) cn pro všechna dostatečně velká n. Tuto skutečnost značíme T = O(n), čímž vyjadřujeme asymptotické chování funkce T. Horní odhad složitosti algoritmu T worst (n) udává složitost algoritmu v nejhorším případě. Složitost algoritmu f(n) je asymptoticky menší nebo rovna g(n), tj. f(n) = O(g(n)), právě když existuje taková kladná konstanta c tak, že pro každou velikost dat n od určité hodnoty n 0 platí: 0 f(n) cg(n). Např.: 2n 2 + 3n + 4 = O(n 2 ), neboť pro n 0 = 1 a c = 10 platí 2n 2 + 3n + 4 <= cn 2. Dolní odhad složitosti T best (n) určuje minimální složitost daného algoritmu (nejkratší čas provedení), která nastává jen pro určité případy vstupních dat. Pokud o algoritmu víme, že má dolní odhad složitosti n 2, je jasné, že výsledek nedostaneme rychleji než v kvadratickém čase: Složitost algoritmu f(n) je asymptoticky větší nebo rovna g(n), tj. f(n) = Ω(g(n)), právě když existuje taková kladná konstanta c tak, že pro každou velikost dat n od určité hodnoty n 0 platí: 0 cg(n) f(n). Např. zápis T best (n) = Ω(n 3 ) udává kubickou dolní složitost algoritmu. Složitost v průměrném případě (očekávaná složitost) T avrg (n) se počítá jako střední hodnota náhodné složitosti T(n) při nějakém rozložení vstupních dat. Někdy může být i řádově lepší než složitost v nejhorším případě. Řekneme, že složitost algoritmu f(n) je asymptoticky stejná jako g(n), tj. f(n) = Θ(g(n)), právě když existují takové kladné konstanty c 1,c 2 tak, že pro každou velikost dat n od určité hodnoty n 0 platí: 0 c 1 g(n) f(n) c 2 g(n). Algoritmus je pro danou úlohu optimální, jestliže neexistuje algoritmus, který by tuto úlohu řešil v nejhorším případě s menším počtem základních operací. Často se místo T worst (n) odhaduje pouze podle toho, kolikrát se provedou některé základní, časově nejnáročnější operace. Většinou existuje tzv. triviální dolní odhad, což je velikost instance, protože algoritmus musí vždy projít celý vstup alespoň jednou. 1.6 Složitost úloh P a NP úlohy Třída P je třída všech rozhodovacích úloh U, pro něž existuje polynomiální algoritmus, řešící úlohy U. Rozhodovací úloha je úloha, jejímž řešením je odpověď ano nebo ne. Každou optimalizační úlohu zle převést na rozhodovací úlohu. Příklad - problém obchodního cestujícího. Je zadána množina nějakých bodů a pro každé dva z nich je zadána jejich vzdálenost. Uvažujeme cesty, které vychází z některého z daných bodů, projdou všemi body a vrátí se do výchozího. Optimalizační verze: Najděte trasu nekratší délky. Převedeno na rozhodovací úlohu: Je dáno navíc číslo K. Rozhodněte, zda existuje trasa délky K. Obchodní cestující není zatím ve třídě P, ale je ve třídě NP úloh. NP úloha je taková úloha, kdy platí : pro každou ano instanci lze v polynomiálním čase ověřit správnost odpovědi ano. Pro ne instanci takový algoritmus neexistuje. Třída NP je třída všech rozhodovacích úloh U, pro něž existuje nedeterministický algoritmus, pracující v polynomiálním čase. Nedeterministický algoritmus má dvě fáze. Nedeterministická, kdy se náhodně vygeneruje řetězec symbolů s a deterministická, kdy na vstupu úlohy je jak instance úlohy, tak řetězec s. Po konečném počtu kroků je výstupem ano nebo ne. Řetězec s je vlastně navržené řešení úlohy, které se v deterministické části otestuje, zda platí. Pro obchodního cestujícího je to číslo K. Redukce a polynomiální redukce Obtížnost rozhodovacích úloh se dá srovnávat. Pojem U se redukuje na V vlastně znamená, že rozhodovací úloha U není těžší než rozhodovací úloha V. U se redukuje na V, jestliže existuje algoritmus A, který pro každou instanci I úlohy U zkonstruuje instanci A(I) úlohy V tak, že I je ano instance U právě když A(I) je ano instance V. Je-li algoritmus A polynomiální, pak jde o polynomiální redukci. NP úplné úlohy Rozhodovací úloha U je NP úplná, jestliže je NP úloha a každá NP úloha se na U polynomiálně redukuje. Třídu NP úplných úloh označujeme jako NPC. (NP úplné úlohy jsou nejtěžší mezi NP úlohami). Není známo, zda třídy P a NP jsou opravdu různé. Jinak řečeno, o žádné úloze v NP se nepodařilo dokázat, že není v P. 7

Podařilo se však nalézt úlohy, které jsou úplné ve třídě NP. Příklady Otázka (obtížné problémy): Existuje pro každý problém efektivní (polynomiální) algoritmus, který ho řeší? Odpověď: Ne, existují problémy, pro které se dá dokázat, že neexistuje žádný efektivní algoritmus, který by daný problém řešil. Dokonce existují problémy, pro které se dá dokázat, že neexistuje žádný (ani neefektivní) algoritmus, který by daný problém řešil. Námitka (neexistence algoritmů): Jak dokázat, že něco neexistuje? Odpověď: Sporem. Předpokládáme, že to existuje a ukážeme, že z toho vyplývá nějaký závěr, který je ve zjevném rozporu se skutečností (typicky ukážeme, že něco musí být současně pravda i nepravda). Příklad obtížného problému Vstup: Uzavřená aritmetická formule vytvořená ze symbolů +, =,,,,,, (, ), proměnných a celočíselných konstant. Otázka: Je tato formule pravdivá v oboru přirozených čísel? Příklad vstupu: x y z((x + y = z) (y + 5 = x)) Pro tento problém je znám algoritmus se složitostí 2 2^2^O(n). Současně bylo dokázáno, že jakýkoliv algoritmus rešící tento problém má složitost minimálně 2 2^cn. Příklad algoritmicky neřešitelného problému Vstup: Uzavřená aritmetická formule vytvořená ze symbolů +,, =,,,,,, (, ), proměnných a celočíselných konstant. Otázka: Je tato formule pravdivá v oboru přirozených čísel? Příklad vstupu: x y z((x y = z) (y + 5 = x)) Tento problém je algoritmicky neřešitelný (u rozhodovacích problémů se používá též pojem algoritmicky nerozhodnutelný). Úzce souvisí s Gödelovou větou o neúplnosti. Další příklad nerozhodnutelného problému Vstup: Počítačový program a nějaká jeho vstupní data. Otázka: Zastaví se někdy tento program, když dostane na vstup tato data? Idea důkazu nerozhodnutelnosti: Předpokládejme existenci programu H, který řeší tento problém. Můžeme ho snadno upravit na podprogram H (p,v), který vrací Ano" nebo Ne" jako návratovou hodnotu. Vytvoříme nový program D: Vezme svůj vstup x a zavolá H jako H (x,x). Pokud H vrátí Ano", D skočí do nekonečné smyčky. Pokud H vrátí Ne", D se zastaví. Zastaví se program D nebo ne, když mu předložíme jako vstup jeho vlastní kód? 1.7 Třídy problémů Některé problémy jsou těžší než jiné. Při posuzování obtížnosti problémů se ukázalo jako užitečné rozdělit problémy do tříd složitosti, které značíme: PTIME - problémy řešitelné v polynomiálním čase PSPACE - problémy řešitelné s polynomiálním množstvím paměti EXPTIME - problémy řešitelné v exponenciálním čase EXPSPACE - problémy řešitelné s exponenciálním množstvím paměti 8

Třída NPTIME Jednou z nejdůležitějších tříd je třída NPTIME. Do třídy NPTIME patří rozhodovací problémy, pro které existuje polynomiální algoritmus, který ověří správnost nalezeného řešení. Přesněji řečeno, pokud je odpověď Ano", existuje svědek, který dosvědčuje, že odpověď je Ano", kterého je možné v polynomiálním čase otestovat, že tomu tak skutečně je. Pokud je odpověď Ne", žádný takový svědek neexistuje. Příklad problému z NPTIME Vstup: Popis mapy (seznam států a informace který stát sousedí s kterým) a číslo k. Otázka: Je možné státy obarvit k barvami tak, aby žádné dva sousední státy neměly stejnou barvu? P vs. NP Jeden z největších otevřených problémů teoretické informatiky: Otevřený problém: Je P = NP? Pozn.: Třídy PTIME a NPTIME bývají také označovány stručněji P a NP. NP-úplné problémy Důležitou podtřídou třídy NPTIME jsou tzv. NP-úplné problémy. Definice Problém P je NP-těžký, jestliže platí, že libovolný problém ze třídy NPTIME je možné v polynomiálním čase redukovat na problém P. Definice Problém P je NP-úplný, jestliže je NP-těžký a současně sám patří do třídy NPTIME. NP-úplné problémy jsou důležité, protože: Kdyby alespoň jeden z nich byl řešitelný v polynomiálním čase, všechny problémy z NPTIME by byly řešitelné v polynomiálním čase. Pokud v NPTIME existuje alespoň jeden problém, který není řešitelný v polynomiálním čase, pak žádný z NP-úplných problémů není řešitelný v polynomiálním čase. Velké množství problémů, které se objevují v praxi v různých oblastech informatiky, je NP-úplných nebo NP-těžkých. To, že NP-úplné problémy nelze řešit v polynomiálním čase je podmínkou nutnou (nikoli však postačující) pro to, aby existovaly šifrovací algoritmy, které by nebyly snadno prolomitelné. Někdy dva problémy mohou vypadat podobně, a přitom jeden z nich je řešitelný v polynomiálním čase, zatímco druhý je NP-úplný. Problém 1 Vstup: Popis měst a silnic. Výstup: Existuje okružní cesta, na které projedeme každou silnici právě jednou? Problém 2 Vstup: Popis měst a silnic. Výstup: Existuje okružní cesta, na které projedeme každé město právě jednou? 9

Problém 1 je v PTIME. Problém 2 je NP-úplný. Jak řešit těžké problémy? Pokud pro daný problém neexistuje efektivní algoritmus, máme následující možnosti: 1. Exponenciální algoritmy použitelné jen na malé instance. 2. Aproximační řešení použitelné jen pro optimalizační problémy. Najde řešení, které je o něco horší než optimum. 3. Pravděpodobnostní (randomizované) algoritmy najde rychle řešení, ale řešení je s určitou pravděpodobností špatně. 4. Speciální případy soutředit se jen na některé speciální případy instancí, neřešit problém v plné obecnosti. 5. Heuristiky postup, který najde řešení rychle ve většině rozumných" případů, není však zaručeno že vždy. Příklad: Randomizovaný algoritmus Zadání: Vstup: Přirozené číslo p. Otázka: Je p prvočíslo? Teprve od roku 2003 je znám polynomiální algoritmus (O(n 12+ε ), později o něco zlepšen). V praxi je používán randomizovaný algoritmus se složitostí O(n 3 ): Pokud p je prvočíslo, vrátí vždy odpověď Ano". Pokud p není prvočíslo, je pravděpodobnost odpovědi Ne" minimálně 50%, ale existuje až 50% šance, že program vrátí chybnou odpověď Ano". Program můžeme volat opakovaně (k krát). Pokud program vrátí alespoň jednou odpověď Ne", víme na 100%, že p není prvočíslo. Pokud program vrátí pokaždé Ano", je pravděpodobnost toho, že p není prvočíslo, menší než 2 k. Když k = 100, je pravděpodobnost chyby zanedbatelně malá. Poznámka: Lze například odvodit, že pravděpodobnost toho, že počítač bude zasažen během dané mikrosekundy meteoritem, je nejméně 2 100 za předpokladu, že každých 1000 let je meteoritem zničeno alespoň 100 m 2 zemského povrchu. 10