Základy algoritmizace a programování

Podobné dokumenty
Algoritmizace prostorových úloh

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

Algoritmy I, složitost

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

NPRG030 Programování I, 2018/19 1 / :03:07

Časová složitost algoritmů

DobSort. Úvod do programování. DobSort Implementace 1/3. DobSort Implementace 2/3. DobSort - Příklad. DobSort Implementace 3/3

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

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

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

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

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

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

Časová složitost / Time complexity

IAJCE Přednáška č. 9. int[] pole = new int[pocet] int max = pole[0]; int id; for(int i =1; i< pole.length; i++) { // nikoli 0 if (Pole[i] > max) {

každého programátora, a tak není divu, že třídicí algoritmy jsou jedny z nejstudovanějších.

A4B33ALG 2010/05 ALG 07. Selection sort (Select sort) Insertion sort (Insert sort) Bubble sort deprecated. Quicksort.

Časová složitost algoritmů, řazení a vyhledávání

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

Maturitní téma: Programovací jazyk JAVA

Datové struktury 2: Rozptylovací tabulky

vyhledávací stromové struktury

Stromy, haldy, prioritní fronty

přirozený algoritmus seřadí prvky 1,3,2,8,9,7 a prvky 4,5,6 nechává Metody řazení se dělí:

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

ALGORITMY A DATOVÉ STRUKTURY

Digitální učební materiál

Složitost UPR 2008/09 1

Časová a prostorová složitost algoritmů

Digitální učební materiál

Hledání k-tého nejmenšího prvku

Základní datové struktury III: Stromy, haldy

Základní informace o předmětu Otázka:

Algoritmy vyhledávání a řazení. Zatím nad lineární datovou strukturou (polem)

Třídění a vyhledávání Searching and sorting

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

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

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

Adresní vyhledávání (přímý přístup, zřetězené a otevřené rozptylování, rozptylovací funkce)

Anotace. Informace o praktiku z programování!!! Direktivy překladače Soubory (textové) Quicksort Metoda rozděl a panuj

Rekurze a rychlé třídění

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

Algoritmy I. Třídění ALGI 2010/2011

10. Složitost a výkon

IB111 Úvod do programování skrze Python

Složitosti základních operací B + stromu

Prioritní fronta, halda

Rozděl a panuj. Často se setkáme s úlohami, které lze snadno rozdělit na nějaké menší úlohy a z jejich

Dynamické programování

Digitální učební materiál

Sada 1 - Základy programování

Algoritmizace a programování

Intervalové stromy. Představme si, že máme posloupnost celých čísel p 0, p 1,... p N 1, se kterou budeme. 1. Změna jednoho čísla v posloupnosti.

Algoritmizace řazení Bubble Sort

Rozhledy matematicko-fyzikální

Řešení: PŘENESVĚŽ (N, A, B, C) = přenes N disků z A na B pomocí C

Binární vyhledávací stromy pokročilé partie

Digitální učební materiál

Algoritmy a datové struktury

13. Třídící algoritmy a násobení matic

Amortizovaná složitost. Prioritní fronty, haldy (binární, d- regulární, binomiální, Fibonacciho), operace nad nimi a jejich složitost

Návrh Designu: Radek Mařík

Mimo samotné správnosti výsledku vypočteného zapsaným algoritmem je ještě jedno

Zdůvodněte, proč funkce n lg(n) roste alespoň stejně rychle nebo rychleji než než funkce lg(n!). Symbolem lg značíme logaritmus o základu 2.

Třídící algoritmy. Insert Sort. Bubble Sort. Select Sort. Shell Sort. Quick Sort. Merge Sort. Heap Sort.

Anotace. pointery (pars prima). Martin Pergel,

3 Vyhledávání, třídící algoritmy

Aplikace. vliv na to, jakou mají strukturu i na to, jak pracné je je vyvinout. Bylo vypozorováno, že aplikace je možné rozdělit do skupin

Stromy. Jan Hnilica Počítačové modelování 14

Úvod do programování

Základy algoritmizace. Hašování

Základy řazení. Karel Richta a kol.

IB108 Sada 1, Příklad 1 Vypracovali: Tomáš Krajča (255676), Martin Milata (256615)

V případě jazyka Java bychom abstraktní datový typ Time reprezentující čas mohli definovat pomocí třídy takto:

Zadání k 2. programovacímu testu

Doba běhu daného algoritmu/programu. 1. Který fragment programu z následujících dvou proběhne rychleji?

Rekurzivní algoritmy

bin arn ı vyhled av an ı a bst Karel Hor ak, Petr Ryˇsav y 23. bˇrezna 2016 Katedra poˇ c ıtaˇ c u, FEL, ˇ CVUT

Dynamické datové struktury III.

3 Algoritmy řazení. prvku a 1 je rovněž seřazená.

ÚVODNÍ ZNALOSTI. datové struktury. správnost programů. analýza algoritmů

Informatika navazující magisterské studium Přijímací zkouška z informatiky 2018 varianta A

Základy algoritmizace a programování

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

Programování 3. hodina. RNDr. Jan Lánský, Ph.D. Katedra informatiky a matematiky Fakulta ekonomických studií Vysoká škola finanční a správní 2015

Programátorské kuchařky

5 Rekurze a zásobník. Rekurzivní volání metody

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

B3B33ALP - Algoritmy a programování - Zkouška z předmětu B3B33ALP. Marek Boháč bohacm11

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

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

TGH07 - Chytré stromové datové struktury

Rekurentní rovnice, strukturální indukce

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

PŘEDNÁŠKA 2 POSLOUPNOSTI

B3B33ALP - Algoritmy a programování - Zkouška z předmětu B3B33ALP. Marek Boháč bohacm11

Hranová konzistence. Arc consistency AC. Nejprve se zabýváme binárními CSP. podmínka odpovídá hraně v grafu podmínek

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

Digitální učební materiál

Transkript:

Základy algoritmizace a programování Složitost algoritmů. Třídění Přednáška 8 16. listopadu 2009

Který algoritmus je "lepší"? Různé algoritmy, které řeší stejnou úlohu zbytek = p % i; zbytek = p - p/i*i; Časové a pamět ové nároky algoritmu (programu) časová a pamět ová složitost. Volba vhodného algoritmu : Vyhledání telefonního čísla v telefonním seznamu. Nejjednodušší algoritmus: prohledávat od začátku postupně jméno po jméně, dokud nenajdeme hledané. (sekvenční vyhledávání). ALE my postupujeme jinak: Využíváme toho, že v seznamu jsou jména utříděna podle abecedy. Postup, který obvykle používáme je založen na myšlence půlení intervalu.

Složitost algoritmů Časová složitost závislost časových nároků na velikosti vstupních dat. Měříme počtem elementárních operací (kroků algoritmu), které budou provedeny v programu s danými vstupními daty. Elementární operace instrukce typické pro daný problém počet porovnání, přesunů v paměti, aritmetické operace apod. N (velikost konkrétního řešeného problému) počet operací vykonaných při výpočtu podle daného algoritmu. (rostoucí funkce ) Pamět ová složitost závislost pamět ových nároků na velikosti vstupních dat. Měříme počtem pamět ových míst, které budou při výpočtu podle algoritmu zapotřebí.

Složitost algoritmů Složitost v nejhorším případě jak nejdéle bude trvat výpočet s libovolnými daty délky N (zaručená horní mez)... hrubé odhady... Složitost v průměném případě při odhadu nutné uvažovat pravděpodobnostní rozložení dat. Zpravidla horní odhad Příklad: Je číslo prvočíslo? sudá čísla výpočet hned skončí číslo je prvočíslo testování všech možných dělitelů N. Hrubý odhad časové složitosti : N. Který ze dvou algoritmů je lepší? f (n) = 10n, g(n) = n 2 pro n < 10 platí : f (n) > g(n), pro n > 10 platí f (n) < g(n) Pokud nevíme, pro jak velká data bude algoritmus používán, je podstatné, který algoritmus je rychlejší pro velké hodnoty N

Asymptotická složitost Asymptotická složitost rychlost růstu funkce složitosti Například: počet operací je charakterizován 2N 2 + 3N + 1 časové nároky jsou úměrné N 2 funkce časové složitosti je kvadratická O(N 2 ). V praxi používané algoritmu mívají většinou některou následujících složitostí: O(log N), O(N), O(N log N), O(N 2 ), O(N 2 log N), O(N 3 ),... O(2 N ) uspořádáno podle rychlosti růstu polynomiální... exponenciální Zrychlení procesoru 10 násobné lineární algoritmus zpracuje 10 krát větší objem dat, kvadratický trojnásobně, exponenciální jen o 3.

Příklady Úloha utřídění N čísel podle velikosti. Jednodušší algoritmy mají časovou složitost O(N 2 ), lepší pracují v čase O(N log N). Předpokládejme, že operace porovnání dvou čísel trvá 0,1 ms. Utřídění 100 čísel "nepatrný" rozdíl (1 sekunda nebo 0,07 s) i pomalý algoritmus vyhovuje. Třídění 100 000 čísel rozdíl 11 dní nebo necelé 3 minuty.

Příklady Hledání v telefonním seznamu (cca 500 000 jmen) Prohledávání nejprimitivnějším způsobem... lineární složitost Binární vyhledávání v uspořádané posloupnosti otevřeme seznam uprostřed porovnáme s hledaným zjistíme, ve které polovině máme dál hledat v každém kroku zmenšíme sledovanou část na polovinu Při N jménech musíme udělat přibližně O(log 2 N) kroků, aby se zkoumaný úsek zúžil na jediné jméno. Člověk porovná dvě jména za cca 1 sekundu rozdíl dny nebo sekundy.

Matematická definice symbolu O Mějme dvě funkce f a g, definované v oboru přirozených čísel (v matematice matematické analýze se totéž zavádí v oboru reálných čísel). Řekneme, že funkce f je třídy O(g), jestliže existuje taková reálná konstanta C, že pro všechna přirozená čísla od jistého n 0 počínaje platí f (n) Cg(n). To znamená, že funkce g shora omezuje funkci f až na multiplikativní konstantu.

Algoritmy třídění Úloha Přerovnat data do správného pořadí, protože se seřazenými údaji se mnohem lépe pracuje, například pokud v nich pak potřebujeme vyhledávat. Budeme třídit pole celých čísel. Metody třídění můžeme rozdělit do dvou hlavních skupin: vnitřní třídění, kdy si můžeme dovolit všechna data načíst do (rychlé) paměti počítače, vnější třídění, kdy již třídění musíme realizovat opakovaným čtením a vytvářením diskových souborů. Omezíme se pouze na algoritmy vnitřního třídění.

Nejjednodušší algoritmy Nejjednodušší třídící algoritmy patří do skupiny přímých metod. Tyto algoritmy mají většinou časovou složitost O(N 2 ). Jsou použitelné tehdy, když tříděných dat není příliš mnoho. Stručně si přiblížíme tři nejznámější přímé algoritmy. přímým výběrem přímým vkládáním bublinkové třídění

Třídění přímým výběrem (SelectSort) Třídění přímým výběrem je založeno na opakovaném vybírání nejmenšího čísla z dosud nesetříděných čísel. Vybereme nejmenší číslo v celém poli Nalezené číslo prohodíme s prvkem na začátku pole Vybereme nejmenší číslo z čísel 2,...,N, Prohodíme s druhým prvkem v poli. Vybereme nejmenší číslo z čísel s indexy 3,...,N, atd.... Je snadné si uvědomit, že když takto postupně vybíráme minimum z menších a menších intervalů, setřídíme celé pole (v i-tém kroku nalezneme i-tý nejmenší prvek a zařadíme ho v poli na pozici s indexem i).

Realizace void SelectSort(int * A, int N) { int i,j,k,x; for (i=0; i<n-1; i++) { k=i; //k : index prvního z prohledávaných for (j = i+1; j< N; j++) if (A[j]<A[k]) k = j;//k : index nejmenšího x = A[k]; A[k] = A[i]; A[i] = x;//prohodíme } return; } Časová složitost algoritmu V i-tém kroku musíme nalézt minimum z N-i+1 čísel O(N i + 1). Ve všech krocích dohromady O(N + (N 1) + + 3 + 2 + 1) = O(N 2 ).

Třídění přímým vkládáním (InsertSort) Třídění přímým vkládáním (InsertSort) funguje na podobném principu jako třídění přímým výběrem. Na začátku pole vytváříme správně utříděnou posloupnost, kterou postupně rozšiřujeme. Na začátku i-tého kroku má tato utříděná posloupnost délku i-1. V i-tém kroku určíme pozici i-tého čísla v dosud utříděné posloupnosti a zařadíme ho do utříděné posloupnosti (zbytek utříděné posloupnosti se posune o jednu pozici doprava). Každý krok lze provést v čase O(N). Protože počet kroků algoritmu je N, celková časová složitost právě popsaného algoritmu je opět O(N 2 ).

Realizace void InsertSort(int * A, int N) { int i,j,x; for (i = 1; i< N; i++) { x = A[i]; j =i-1; while (j>0 && x <A[j]) { A[j+1] = A[j]; j = j-1; } A[j+1] = x; } return; }

Bublinkové třídění (BubbleSort) Bublinkové třídění (BubbleSort) pracuje jinak než dva dříve popsané algoritmy. Algoritmu se říká "bublinkový", protože podobně jako bublinky v limonádě "stoupají" vysoká čísla v poli vzhůru. Postupně se porovnávají dvojice sousedních prvků, řekněme zleva doprava, a pokud v porovnávané dvojici následuje menší číslo po větším, tak se tato dvě čísla prohodí. Celý postup opakujeme, dokud probíhají nějaké výměny. Protože algoritmus skončí, když nedojde k žádné výměně, je pole na konci algoritmu setříděné.

Realizace void BubbleSort(int * A, int N) { int i,x; int zmena; do { zmena = 0; for (i = 0; i< N-1; i++) { x = A[i]; A[i] = A[i+1]; A[i+1] = x; zmena = 1; } } while (zmena = = 1); return; }

Bublinkové třídění Po i průchodech while cyklem bude posledních i prvků obsahovat největších i prvků setříděných od nejmenšího po největší. Popsaný algoritmus se tedy zastaví po nejvýše N průchodech jeho celková časová složitost v nejhorším případě je O(N 2 ), nebot na každý průchod spotřebuje čas O(N). Výhodou tohoto algoritmu oproti předchozím dvěma je, že je tím rychlejší, čím blíže bylo zadané pole k setříděnému stavu pokud bylo úplně setříděné, tehdy algoritmus spotřebuje jen lineární čas, O(N).

Algoritmus jménem QuickSort Pracuje v čase O(N log N) Tento algoritmus je založen na metodě "Rozděl a panuj". Nejprve si zvolíme nějaké číslo, kterému budeme říkat pivot. Poté pole přeuspořádáme a rozdělíme je na dvě části tak, že žádný prvek v první části nebude větší než pivot a žádný prvek v druhé části naopak menší. Prvky v obou částech pak setřídíme rekurzivním zavoláním téhož algoritmu. Musíme ale dát pozor, aby byly v každém kroku obě části neprázdné (a rekurze tedy byla konečná). Po skončení algoritmu bude pole setříděné.

Výběr pivota Malá zrada spočívá ve volbě pivota. Hodilo by se, aby po přeházení prvků levá i pravá část pole byly přibližně stejně velké. Nejlepší volbou pivota by byl prvek takový, jenž by byl v setříděném poli přesně uprostřed. Přeuspořádání zvládneme v lineárním čase a pokud by pivoty na všech úrovních byly mediány, pak by počet úrovní rekurze byl O(log N) a celková časová složitost O(N log N) (na každé úrovni rekurze je součet délek tříděných posloupnosti nejvýše N). Většinou se pivot volí náhodně z dosud nesetříděného úseku Dá se ukázat, že takovýto algoritmus s velmi vysokou pravděpodobností poběží v čase O(N log N). V naší implementaci QuickSortu pro názornost nebudeme pivot volit náhodně, ale vždy jako pivot vybereme prostřední prvek tříděného úseku.

Realizace void QuickSort(int * A, int left, int right) {int i,j,pivot,x; i = left; j = right; pivot =A[(i+j) / 2]; do { while (A[i]<pivot) i = i+1; while (A[j]>pivot j = j-1; if (i<=j) { x=a[i]; A[i]=A[j]; A[j]=x; i=i+1; j=j-1; } } while (i< j); if (j>left) QuickSort(A, left, j); if (i<right) QuickSort(A, i, right); return; }

Vyhledávání Jak v uspořádaných datech něco efektivně najít a jak si data udržovat stále uspořádaná. K tomu se nám bude hodit zejména binární vyhledávání a různé druhy vyhledávacích stromů.

Binární vyhledávání. Najít nějaký konkrétní záznam z mezi utříděnými. Nalistujeme prostřední záznam (označíme si ho xm) a porovnáme s ním naše z. Při z<xm víme, že se z nemůže vyskytovat "napravo" od xm, protože tam jsou všechny záznamy větší než xm Analogicky, pokud z>xm, nemůže se z vyskytovat v první polovině pole. V obou případech nám zbude jedna polovina a v ní budeme pokračovat stejným způsobem. Tak budeme postupně zmenšovat interval, ve kterém se z může nacházet, až bud to z najdeme zjistíme, že v seznamu není. Tomuto principu se obvykle říká binární vyhledávání nebo také hledání půlením intervalu a snadno ho naprogramujeme pomocí cyklu, v němž si budeme udržovat interval < l, r >, ve kterém se hledaný prvek může nacházet.

Binární vyhledávání int BinSearch(int * x, int N, int z ) {int l,r,m ; l = 0; //interval, ve kterém hledáme r = N-1; while (l<= r) //ještě není prázdný { m = (l+r) / 2; // střed intervalu if (z < x[m]) r = m-1; // je vlevo else if (z > x[m]) l = m+1 ; // je vpravo else return m; // Bingo! } return -1; // nebyl nikde }

Složitost binárního vyhledávání Průchodů cyklem while může být nejvýše (log 2 N), protože interval < l, r > na počátku obsahuje N prvků a v každém průchodu jej zmenšíme na polovinu (ve skutečnosti ještě o jedničku. Proto po k průchodech bude interval obsahovat nejvýše N/2k prvků a jelikož pro N/2k<1 se algoritmus zastaví, může být k nejvýše log 2 N. Proto je časová složitost binárního vyhledávání O(log N). [Základ logaritmu nemusíme psát, protože logaritmy o různých základech se liší jen konstantou, která se "schová do O čka."] Hledání půlením intervalu je tedy velmi rychlé, pokud máme možnost si data předem setřídit.