300 likes | 457 Views
Algoritmy. Přednáška z předmětu Počítače I Dana Nejedlová Katedra informatiky EF TUL. Efektivita algoritmu. Programy s částmi typu vstup n hodnot, zpracování, výstup. Zajímá nás složitost části zvané zpracování . Složitost je počet instrukcí jako funkce n .
E N D
Algoritmy Přednáška z předmětu Počítače I Dana Nejedlová Katedra informatiky EF TUL
Efektivita algoritmu • Programy s částmi typu • vstup n hodnot, • zpracování, • výstup. • Zajímá nás složitost části zvané zpracování. • Složitost je počet instrukcí jako funkce n. • Potřebujeme metodu, která porovná různé algoritmy nezávisle na hardwaru. • Počet vykonaných instrukcí programu. • Nebude nás zajímat to, že různé instrukce mohou trvat různou dobu. • Porovnání výkonnosti hardwaru pro stejné programy se nazývá benchmarking. • Měří se v časových jednotkách. • Počet instrukcí vyjadřuje časovou složitost.Kromě ní je ještě možné analyzovat paměťovou složitost.
Hledání největší položky 1 #include <stdio.h> 2 #define MAX_POCET_POLOZEK 10 3 intmain() 4 { 5 intx[MAX_POCET_POLOZEK]; 6 intpocet_polozek, i, nejvetsi, index_nejvetsiho; 7 printf("Zadej pocetpolozekmensinez %d: ", MAX_POCET_POLOZEK + 1); 8 scanf("%d", &pocet_polozek); 9 for(i = 0; i < pocet_polozek; i++) { /* Čtení */ 10 printf("Zadej %d. polozku: ", i); 11 scanf("%d", &x[i]); 12 } 13 nejvetsi= x[0]; 14 index_nejvetsiho= 0; 15 i = 1; 16 while(i < pocet_polozek) { /* Hledání největšího */ 17 if(x[i] > nejvetsi) { 18 nejvetsi= x[i]; 19 index_nejvetsiho= i; 20 } 21 i++; 22 } 23 printf("Nejvetsipolozka je %d a ma index %d.", nejvetsi, index_nejvetsiho); 24 return 0; 25 }
Efektivita algoritmu pro hledání největší položky • Řádky č. 1 – 15, 23 – 25 se provedou jen jednou. • Budeme je považovat za 8 instrukcí. • Řádky 9 – 12 se sice provedou n-krát, ale • vstupní operace nás z hlediska efektivity nezajímá, • její rychlost je závislá na interakci uživatele a systému. • Budeme je celkově považovat za 1 instrukci. • Je to konstantní faktor v programu (nezávislý na n). • Řádek č. 16 se provede n-krát. • Řádky č. 17 a 21 se provedou n – 1 krát. • 2 instrukce * (n – 1) • Řádky č. 18 a 19 se provedou v počtu závislém na datech. • Přehození položek se provádí jen někdy.
Nejlepší, průměrný a nejhorší případ • Počet instrukcí je závislý na uspořádání dat. • Nejlepší případ • Položky jsou seřazené od největší do nejmenší. • 8 + n + 2 * (n – 1) instrukcí • Průměrný případ • Položky přehodíme v polovině případů. • 8 + n + 2 * (n – 1) + 2 * (n – 1) / 2 instrukcí • Nejhorší případ • Položky jsou seřazené od nejmenší do největší. • 8 + n + 2 * (n – 1) + 2 * (n – 1) instrukcí
Asymptotická analýza algoritmu • Asymptota funkce f(x) je přímka, jejíž vzdálenost od f(x) se blíží nule, když se x blíží nekonečnu. • Počet instrukcí jako funkce n, když se n blíží nekonečnu • Vychází z matematického pojmu limita. • Počet instrukcí je často ve formě polynomiální funkce. • Záleží jen na členech nejvyššího řádu. • se zredukuje na nebo častěji na . • Omikron notace (velkáO notace) a další varianty • Formální způsob zápisu složitosti, například O(n3) • Asymptota v tomto smyslu je funkce vynásobená konstantou, která se funkci vracející počet instrukcí blíží pro nekonečně velké n. • Složitost hledání největší položky je řádu n.
Vyhledávání • Sekvenční • Seznam se prohledává od začátku, dokud se nenalezne položka nebo se nedojde na konec. • Nejlepší případ = 1 porovnání • Průměrný případ = n / 2 porovnání • Nejhorší případ = n porovnání • Binární • Prohledávaný seznam musí být setříděn! • Porovnáme položku uprostřed seznamu. • Podle toho, jestli je větší nebo menší než hledaná položka, budeme stejně pokračovat v jedné z polovin seznamu. • Rekurze • Algoritmus volá sám sebe na jednodušší problém. • Nejlepší případ = 1 porovnání • Průměrný případ závisí na datech. Lze zjistit statisticky. • Nejhorší případ = log2n • Seznam můžeme dělit tolikrát, kolikrát je v něm alespoň 1 položka. • n / 2x = 1, n = 2x, x = log2n = počet dělení
Tříděníneboli řazení • Třídění uspořádává položky seznamu do určitého pořadí. • Třídění je jedním z nejvíce studovaných algoritmů, protože • je součástí mnoha jiných algoritmů, • připravuje vstupní data pro jiné algoritmy. • například pro binární vyhledávání • Třídění je dobrým tématem pro úvod do základních pojmů z oblasti algoritmů jako jsou: • analýza nejlepšího, nejhoršího a průměrného případu, • analýza složitosti, • Jejím příkladem je asymptotická analýza. • výměna spotřeby času za spotřebu paměti (time-spacetrade-off). • metoda rozděl a panuj (divide and conquer), • rekurzivní algoritmy • datové struktury, • například pole, struktura, dynamické datové struktury • randomizace dat. • využití náhodných hodnot pro výpočty
Výběr optimálního třídícího algoritmu • Počet položek • Datový typ položek • Dají se položky považovat za celá čísla reprezentovaná stejným počtem bitů? • Čísla se stejným znaménkem ve formátu IEEE 754 se dají třídit jako celá čísla. • Jsou data ve formě pole (array), haldy (heap) nebo lineárního spojového seznamu (linked list)? • Jak výpočetně náročné je porovnání dvou položek? • Uspořádání nebo statistické rozložení položek • Je seznam v náhodném pořadí nebo částečně setříděný? • Je v seznamu mnoho položek se stejnou hodnotu? • Výpočetní zdroje • Kolik máme procesorů? • Vejde se celý seznam do paměti? • Jaká je cena za přehození položek vzhledem k povaze paměťového média? • Paměti mají různou rychlost přístupu k položce a mohou mít omezený počet zápisů. • Požadavky na rychlost výstupu • Má se setříděný výstup tvořit postupně, aby měl uživatel rychle k dispozici alespoň začátek setříděného seznamu, nebo se má vše nejdřív setřídit a potom jít do výstupu najednou? • Dají se výše uvedené vlastnosti dat a další podmínky očekávat vždy nebo jen někdy?
Řazení přímým výběremSelection Sort • V cyklu s (n – 1) iteracemi: • Nalezneme největší položku seznamu a vyměníme ji s položkou na jeho konci. • Seznam zkrátíme o poslední položku. • Výhody • Počet zápisů do paměti (výměna položek) je řádu n. • Nevýhody • Počet porovnání dle asymptotické analýzy je řádu n2. • (n – 1) krát zkracujeme seznam a přitom v něm pokaždé hledáme největší položku, což má složitost řádu n. • Přesněji • Seznam je na začátku dlouhý n a na konci 1, tedy v průměru n / 2. • Takže počet porovnání je (n – 1) ∙ n / 2 = 0,5n2 – 0,5n.
Řazení vkládánímInsertion Sort • Seznam rozdělíme na seřazenou a neseřazenou část tak, že seřazená obsahuje první položku seznamu. • V cyklu s (n – 1) iteracemi: • Vezmeme první položku neseřazeného seznamu a zařadíme ji do seřazené části seznamu, která se tvoří na začátku seznamu. • Seřazenou část seznamu prohledáváme od konce. • Nesetříděný seznam zkrátíme o první položku. • Výhody • Počet porovnání je řádu n2 / 4. • Seřazená část seznamu je v průměru dlouhá n / 2. • Při zařazování položky do seřazené části seznamu v průměru potřebujeme dojít do jeho poloviny. • Řazení přímým výběrem má počet porovnání řádu n2 / 2. • Počet porovnání i přesouvání položek je nižší pro částečně setříděný seznam. • Proto je většinou v praxi řazení vkládáním preferováno před řazením přímým výběrem. • Algoritmus s touto vlastností se nazývá adaptivní. • Nevýhody • Počet zápisů do paměti (posouvání položek v seřazené části) dle asymptotické analýzy je řádu n2. • n krát zařazujeme položku a přitom posuneme n / 2 položek. • Řazení přímým výběrem má počet zápisů do paměti řádu n.
Bublinkové řazeníBubble Sort, Sinking Sort • V cyklu s (n – 1) iteracemi • je vnořen cyklus s (n – 1) iteracemi, ve kterém: • Porovnáme sousední položky na začátku seznamu a jsou-li ve špatném pořadí, tak je přehodíme. • Posuneme se o jednu položku. • Nesetříděný seznam zkrátíme o poslední položku. • Při každém průchodu seznamem se nejvyšší položka přesune (potopí se) na jeho konec. • Nejnižší položky probublávají na začátek seznamu pomalu. • o jedinou pozici. • Nevýhody • Počet zápisů do paměti (přehození položek) i porovnání dle asymptotické analýzy je řádu n2. • To znamená, že bublinkové řazení nemá žádnou výhodu před řazením přímým výběrem ani vkládáním.
V čem může být bublinkové řazení výhodné? • Snadná algoritmizace a analýza • Může pomoci při ladění porovnávací funkce. • Porovnáváme mezi sebou víc dvojic než při ostatních algoritmech. • Algoritmus může skončit, když při průchodu seznamem nedošlo k žádnému přehození. • adaptivnost • Může být efektivní pro velmi krátké seznamy (2, 3 položky) a pro seznamy, ve kterých je malá vzdálenost mezi položkami ve špatném pořadí. • Může být nezbytné pro hardware se sekvenčním přístupem do paměti. • Data jsou na magnetické pásce a do operační paměti se vejdou jen 2 položky. • Převíjení pásky trvá dlouho, takže po projití seznamem uděláme následující průchod z konce na začátek. • Tím se navíc řeší i pomalé probublávání nejnižších položek. • Tato varianta třídění se jmenuje Cocktail (shaker) sort. • Nedostupnost náhodného přístupu do paměti je i u dat dostupných přes síť. • Vykreslování pohybujících se objektů v grafických programech • Třídí se podle vzdálenosti objektů (bližší objekty musí překrývat vzdálenější). • Při kontinuálně měnící se scéně jsou objekty v nesprávném pořadí blízko sebe. • Přehrávání videa nesmí být trhané, takže by nemuselo být výhodné kompletně objekty setřídit a potom teprve zobrazit další frame videa.
Řazení rozdělovánímQuicksort • Vybereme ze seznamu jednu položku zvanou pivot neboli mezník. • Projdeme jednou seznam a všechny položky menší než pivot dáme na začátek seznamu a všechny položky větší než pivot dáme na konec seznamu. • Seznam procházíme současně od začátku i konce a při tom přehazujeme špatně umístěné položky. • Seznam rozdělíme na 2 poloviny. • 1. polovina obsahuje položky menší nebo rovné pivotu. • 2. polovina obsahuje položky vyšší než pivot. • Na každou z polovin seznamu opět uplatníme Quicksort. • Rekurze
Efektivita řazení rozdělováním • Seznam dělíme log2n krát. • Viz binární vyhledávání. • Při každém dělení seznamu porovnáme případně přehodíme n položek. • Přesněji počet položek v dané části seznamu – 1. • Celkem se tedy provede n ∙ log2nporovnání. • Při uvádění složitosti algoritmu obsahujícího logaritmus se často vynechává základ logaritmu, protože převod logaritmu na jiný základ se provádí násobením konstantou, tedy , protože . • Řazení přímým výběrem, vkládáním nebo bublinkovémají složitost řádu n2. • Řazení rozdělováním je tedy pro dlouhé seznamy výrazně efektivnější než kvadratické algoritmy.
Nejlepší, průměrný a nejhorší případ • Záleží na hloubce dělení seznamu. • Nejlepší případ • Seznam dělíme pokaždé na 2 stejně velké půlky. • Průměrný případ • Pro seznam s náhodnými a neseřazenými hodnotami a velkým n se příliš neliší od nejlepšího případu. • Nejhorší případ • Pivot je vybrán vždy tak, že je nejmenší položkou seznamu, protože jej třeba bereme vždy ze začátku seznamu. • To se může stát u již setříděného seznamu. • Řeší se vhodnou, například náhodnou, volbou pivotu. • Seznam se tak rozdělí na část s pivotem a část s počtem položek v dané části seznamu – 1. • Počet dělení seznamu je roven hloubce dělení, tedy (n – 1). • Složitost algoritmu je řádu n2.
Nevýhody řazení rozdělováním • Quicksort není efektivní u malých seznamů, protože má velkou režii. • volání podprogramů v rekurzi • pomocné proměnné • Při opakovaném dělení seznamu vznikají nakonec malé seznamy. • Quicksort by měl pro malé seznamy (asi pod 10 položek) přepnout na nějakou variantu třídění s kvadratickou složitostí, například insertion sort, protože tyto algoritmy mají menší konstantní faktor.
Co je třeba umět do testu • Znát algoritmus sekvenčního a binárního vyhledávání. • Data mohou vypadat třeba takto: 1, 2, 3, 4, 5, 6, 7. • V jakém pořadí je procházíme? • Kolik porovnání provedeme při hledání určité hodnoty? • Jaké podmínky musí splňovat seznam, ve kterém chceme vyhledat určitou položku binárním vyhledáváním? • Jaké třídící algoritmy jsou vhodné pro krátké seznamy? • Jaké třídící algoritmy jsou vhodné pro dlouhé seznamy? • Pro jaké úlohy může být vhodné bublinkové řazení? • Rozumět nejlepšímu, průměrnému a nejhoršímu případu probraných algoritmů. • Pro jaká data může nastat? • Jakou má výpočetní složitost? • Pokud se neuvádí konkrétní algoritmus, jde o složitost nejefektivnějšího známého algoritmu. • Čím se vyznačují rekurzívní algoritmy? Uveďte jejich příklady.
Další typické algoritmy: Iterace • Cyklus (iterace) má v programech klíčová slova například for nebo while. • Jakou složitost má algoritmus, ve kterém se v m-krát vnořeném cyklu vykoná noperací? 1 #include <stdio.h> 2 intmain() 3 { 4 inti1, i2, i3, i4, n = 3, pocet= 0; 5 for(i1 = 0; i1 < n; i1++) 6 for(i2 = 0; i2 < n; i2++) 7 for(i3 = 0; i3 < n; i3++) 8 for(i4 = 0; i4 < n; i4++) 9 pocet++; 10 printf("Pocet iteraci je %d.\n", pocet); 11 return 0; 12 } • Cyklus v tomto příkladu budeme považovat za 4 krát vnořený, i když je spíše 3 krát vnořený, tedy m = 4, n = 3. • Počet iterací je nm = 81.
Hledání podřetězce v řetězci • Počítáme počet porovnání jednotlivých znaků.
Hledání podřetězce v řetězci • Hledaný řetězec má m znaků. • Prohledávaný řetězec má nznaků. • Počet znaků, od kterých se začíná porovnávat v prohledávaném řetězci = 1 až n. • Hledaný řetězec posouváme 0 až (n – 1) krát. • Počet porovnávaných znaků pro každé posunutí hledaného řetězce = 1 až m. • Celkový počet porovnání znaků = 1 až n ∙ m. • Složitost algoritmu = n∙ m.
Algoritmy polynomiální a ty ostatní • Dosud probrané algoritmy mají složitost s funkcí n, n ∙ log n, n2, n ∙ m. • Tyto algoritmy se nazývají polynomiální. • V polynomech je konstantní faktor, n krát konstanta, n na konstantní exponent. • Funkce n ∙ log n roste pomaleji než n2, takže se také řadí mezi polynomiální algoritmy. • V praxi je však často třeba řešit i úlohy typu • vyber nejlepší permutaci n prvků, • vyber nejlepší výběr z množiny n prvků. • To jsou funkce n! a 2n, které s růstem n rostou podstatně rychleji než funkce nm. • Funkce nm pro velké m také roste rychle, ale v algoritmech je exponent m obvykle maximálně 4 (4 vnořené cykly). • Proto se algoritmy s těmito funkcemi odlišují od polynomiálních a nazývají se nepolynomiální, nebo úlohy s exponenciální složitostí. • Algoritmy s exponenciální složitostí jsou řešením pro NP úlohy. • Kromě časové náročnosti, na kterou se v přednáškách omezíme, existují i studie paměťové (prostorové) náročnosti.
Problém obchodního cestujícíhoTravelling Salesman Problem (TSP) • Máme najít nejkratší cestu, která projde každé město jen jednou a vrátí se do výchozího města. • Máme n měst. • Počet možných průchodů městy je n! (faktoriál). • D • B • E • A • C • G • F
Problém batohuKnapsack (Rucksack) Problem • Naplňte batoh nejhodnotnějšími věcmi, když nemůžete unést všechny z nich. • Máme n věcí a každá z nich má svoji cenu a hmotnost. • Počet možných výběrů • Každá věc je buďto vybrána nebo nevybrána. • To je informace o hodnotě 1 bit. • Příklad pro 3 věci vyžaduje 3 bity informace pro 1 výběr. • 000 – Nic není vybráno. • 001 – Vybrána 1 věc. • 010 – Vybrána jiná 1 věc. • 011 – Vybrány 2 věci. • 100 • 101 • 110 • 111 – Vybrány všechny věci. • Celkem to bylo 23 možností, obecně 2n.
Úrovně složitosti algoritmu • Problém obchodního cestujícího může mít různé formulace: • Vypočti délku určité trasy. • Trasa je určitá permutace n měst. • Najdi trasu kratší, než je limit k. • Rozhodni, zda existuje trasa kratší, než je limit k. • Najdi nejkratší trasu. • Chceme vědět, jak těžké jsou tyto typy úloh. • Úlohu řešíme ve dvou fázích: • Navrhneme řešení. • Ověříme řešení. • Předpokládá se hypotetický abstraktní stroj zvaný orákulum (oracle), který v polynomiálním čase navrhne správné řešení. • Koncept teoretické informatiky (teorie složitosti) • Tento stroj používá nedeterministický algoritmus. • Dělá paralelně větvení do všech možností. • Nebo uhodne hned napoprvé správné řešení (možnost).
Redukovatelnost úloh • Pokud bychom uměli řešit v polynomiálním čase jeden typ úloh, ovlivnilo by naši schopnost řešit jiný typ úloh. • Úloha A je „Najdi trasu kratší, než je limit k.“ • Úloha Bje „Rozhodni, zda existuje trasa kratší, než je limit k.“ • Řešením úlohy A je určitá trasa a ověřit se dá v polynomiálním čase. • Při ověřování se n-krát vypočte vzdálenost mezi 2 následujícími městy v navržené trase. • Kdyby řešení navrhlo orákulum, byla by úloha řešitelná v polynomiálním čase. • Odtud termín NP úloha – NP jako NondeterministicPolynomialtime. • Jak složitá je úloha B oproti úloze A? • Řešením úlohy B je odpověď „ano“ nebo „ne“. • Pokud by řešením byla odpověď „ne“, nešla by nalézt určitá trasa kratší než k. • Proto se řešení nedá vždy snadno (to jest v polynomiálním čase ověřit). • Kdybychom uměli úlohu B řešit v polynomiálním čase, uměli bychom snadno řešit i úlohu A. • Rozhodnutí musí být podloženo nalezením cesty kratší než k nebo ověřením všech možných cest. • Úloha Anení těžší než rozhodovací úloha B. • Úloha Ase redukuje na rozhodovací úlohu B. • Úloha Bje těžká (is hard) pro třídu úloh A. Ale B není NP-hard. • Když přitom úloha B patří do třídy A, tak Bje kompletní (iscomplete) pro A.
NP úlohy • Najdi trasu kratší, než je limit k. • Najdi množinu věcí lehčí než k a dražší než l. • Nalezení řešení není v praxi obvykle možné v polynomiálním čase. • Ověření správnosti řešení (verifying) v polynomiálním čase možné je. • Délka určité trasy • Hmotnost a cena určité podmnožiny věcí • Počet operací je přímo úměrný počtu měst/věcí n.
NP-úplné (NP-complete) úlohy • Rozhodovací varianty NP úloh. • Odpověď je „ano“ nebo „ne“. • Existuje trasa, kratší než je limit k? • Existuje množina věcí lehčí, než k a dražší než l? • Nalezení řešení není ve všech případech možné v polynomiálním čase. • Ověření správnosti řešení také v polynomiálním čase nemusí být možné. • Řešením není určitá permutace nebo podmnožina, ale odpověď „ano“ nebo „ne“. • Ta se dá potvrdit jen nalezením konkrétní permutace nebo podmnožiny, neboli svědka (certifikátu).
NP-těžké (NP-hard) úlohy • Optimalizační varianty NP úloh, které nemusí mít řešení „ano“/„ne“. • Jaká je nejkratší trasa? • Jaká nejdražší množina věcí je lehčí než k? • Nalezení ani ověření řešení nejsou možná v polynomiálním čase. • U úloh s dostatečně malým n jsou v řešení lidé obvykle lepší než počítače. • Nejjednodušší algoritmy z hlediska algoritmizace generují všechny permutace nebo kombinace, pro každou z nich vypočtou potřebnou funkci a vyberou z nich tu s maximální nebo minimální hodnotou. • To je algoritmus hrubé síly (brute-forcealgorithm). • V praxi se musí řešit mnoho úloh s vysokým n. • Pro ně se musí hledat heuristické algoritmy. • Jsou složité na algoritmizaci, ale nemají exponenciální složitost. • Zaručují pouze suboptimální řešení (blízké optimu) ve většině případů na určitých typech dat. • Exponenciální složitost NP úloh a jejich tříd může být i užitečná. • Prvočíselný rozklad(Integerfactorization) je využíván v počítačové kryptografii. • Je to stěžejní předpoklad fungování e-businessu, kdy jde o prokázání identity komunikující osoby a utajení přenášených dat.
Co je třeba umět do testu • Jakou složitost má • algoritmus s několikrát vnořeným cyklem? • hledání podřetězce v řetězci? • výčet všech permutací (všech možných seřazení)? • výčet všech podmnožin? • Určit k dané formulaci úlohy, zda se jedná o úlohu polynomiální, NP úlohu, NP-úplnou úlohu nebo NP-těžkou úlohu. • Aplikovat počet instrukcí ve formě funkce n na odhad doby výpočtu. • Viz kapitola „Využití údajů o složitosti algoritmu“ přednášek.