Robert Haken [MVP ASP.NET/IIS, MCT] software architect, HAVIT, Základní algoritmy v praxi

Podobné dokumenty
Robert Haken [MVP ASP.NET/IIS, MCT] software architect, HAVIT, Optimalizace výkonu webových aplikací

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

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

IB111 Úvod do programování skrze Python

Algoritmizace prostorových úloh

Datové struktury 2: Rozptylovací tabulky

2 Datové struktury. Pole Seznam Zásobník Fronty FIFO Haldy a prioritní fronty Stromy Hash tabulky Slovníky

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

Kolekce, cyklus foreach

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

Pole a kolekce. v C#, Javě a C++

Prioritní fronta, halda

ALG 09. Radix sort (přihrádkové řazení) Counting sort. Přehled asymptotických rychlostí jednotlivých řazení. Ilustrační experiment řazení

Algoritmy I, složitost

Michal Krátký. Úvod do programovacích jazyků (Java), 2006/2007

Lineární datové struktury

IB111 Úvod do programování skrze Python

Úvod Přetěžování Generika Kolekce Konec. Programování v C# Další jazykové konstrukce. Petr Vaněček 1 / 31

Fronta (Queue) Úvod do programování. Fronta implementace. Fronta implementace pomocí pole 1/4. Fronta implementace pomocí pole 3/4

Úvod do programovacích jazyků (Java)

5. Vyhledávání a řazení 1

Seznamy a iterátory. Kolekce obecně. Rozhraní kolekce. Procházení kolekcí

Da D to t v o é v ty t py IB111: Datové typy

Třetí skupina zadání projektů do předmětu Algoritmy II, letní semestr 2017/2018

Datové typy a struktury

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

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) {

Maturitní témata. IKT, školní rok 2017/18. 1 Struktura osobního počítače. 2 Operační systém. 3 Uživatelský software.

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

2) Napište algoritmus pro vložení položky na konec dvousměrného seznamu. 3) Napište algoritmus pro vyhledání položky v binárním stromu.

Algoritmizace řazení Bubble Sort

Spojová implementace lineárních datových struktur

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

TGH07 - Chytré stromové datové struktury

Časová a prostorová složitost algoritmů

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

Algoritmizace prostorových úloh

Dynamické datové struktury IV.

Časová složitost / Time complexity

TGH07 - Chytré stromové datové struktury

Stromy, haldy, prioritní fronty

Základní datové struktury

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

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

Základní pojmy. Úvod do programování. Základní pojmy. Zápis algoritmu. Výraz. Základní pojmy

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

Algoritmizace prostorových úloh

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

HASHING GENERAL Hashovací (=rozptylovací) funkce

Algoritmy a datové struktury

Dynamické datové struktury III.

Elegantní algoritmus pro konstrukci sufixových polí

Šablony, kontejnery a iterátory

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

Rozptylovací tabulky

Úvod Třídy Rozhraní Pole Konec. Programování v C# Hodnotové datové typy, řídící struktury. Petr Vaněček 1 / 39

6. Problém typové anonymity prvků v kolekci Sjednocení typově rozdílných prvků pomocí rozhraní Kolekce pro jeden typ prvků...

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

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

Generické programování

Reprezentace aritmetického výrazu - binární strom reprezentující aritmetický výraz

Základy algoritmizace. Hašování

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

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

bfs, dfs, fronta, zásobník, prioritní fronta, halda

Abstraktní datové typy

Základy algoritmizace a programování

PROGRAMOVÁNÍ. Cílem předmětu Programování je seznámit posluchače se způsoby, jak algoritmizovat základní programátorské techniky.

Dynamické datové struktury I.

Vyhledávání, zejména rozptylování

Výčtový typ strana 67

Implementace překladače imperativního jazyka IFJ05

Algoritmy II. Otázky k průběžnému testu znalostí

Rekurzivní algoritmy

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

Časová složitost algoritmů

ADT/ADS = abstraktní datové typy / struktury

Lineární datové struktury

boolean hasnext() Object next() void remove() Kolekce

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

IB015 Neimperativní programování. Časová složitost, Typové třídy, Moduly. Jiří Barnat Libor Škarvada

Programování v C++ 2, 4. cvičení

Šablony, kontejnery a iterátory

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

ˇ razen ı rychlejˇ s ı neˇ z kvadratick e Karel Hor ak, Petr Ryˇsav y 20. dubna 2016 Katedra poˇ c ıtaˇ c u, FEL, ˇ CVUT

Rekurze a rychlé třídění

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

Cílem kapitoly je seznámit studenta se seznamem a stromem. Jejich konstrukci, užití a základní vlastnosti.

VYSOKÁ ŠKOLA POLYTECHNICKÁ JIHLAVA Katedra elektrotechniky a informatiky Obor Počítačové systémy

1 Nejkratší cesta grafem

Jazyk C# (seminář 3)

ALGORITMY A DATOVÉ STRUKTURY

bfs, dfs, fronta, zásobník, prioritní fronta, halda

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

Návrh designu: Radek Mařík

Bubble sort. příklad. Shaker sort

Datové struktury. Obsah přednášky: Definice pojmů. Abstraktní datové typy a jejich implementace. Algoritmizace (Y36ALG), Šumperk - 12.

Datové typy v Javě. Tomáš Pitner, upravil Marek Šabo

Konstruktory a destruktory

vyhledávací stromové struktury

Transkript:

Robert Haken [MVP ASP.NET/IIS, MCT] software architect, HAVIT, s.r.o. haken@havit.cz, @RobertHaken Základní algoritmy v praxi

Agenda Intro Řazení Vyhledávání Datové struktury LINQ to Objects

Intro

Asymptotická složitost algoritmů O-notace SLOŽITOST N = 10 N = 100 N = 1 000 O(1) konstantní 1 1 1 O(log n) logaritmická 3 7 10 O(n) linární 10 100 1 000 O(n log n) lineárně logaritmická 33 664 9 965 O(n 2 ) kvadratická 100 10 000 1 000 000 O(c n ) exponenciální (např. c=2) 1 024 1,27 10 30 1,1 10 301 paměťová časová/operační

Pole jako základ všeho lineární souvislý paměťový blok homogenní prvky stejného typu (popř. reference/potomci) s přímým přístupem přímé adresování paměti indexem -O(1)

System.Arrayv.NET referenční datový typ deklarace nealokuje paměť int[] pole; instance se vytváří na heapu non-resizable pole = new int[20]; resize= nové pole + kopie dat -O(n) Array.Copy(pole, pole2, pole.length);

System.Array, Windows Debugger DEMO

List<T> interně ukládá prvky do pole System.Array automatické zvětšování pole výchozí kapacita 4 (není-li určena explicitně) při naplnění se zdvojnásobuje kopírování O(n) přidání prvku typicky O(1), nejhůře O(n) samo se nezmenšuje stálo by kopii O(n) do menšího list.capacity = list.count; list.trimexcess(); // Treshold 90% odebrání prvků = setřesení pole O(n)

Řazení

Řadící algoritmy stabilní / nestabilní s kvadratickou složitostí O(n 2 ) Bubble-Sort, Shaker-Sort, Select-Sort, Shell-Sort Insert-Sort jednotlivé průchody na sobě nezávislé s lineárně logaritmickou složitostí O(n log 2 n) výběrem z binárního stromu = > Heap-Sort Quick-Sort Merge-Sort

Insert Sort O(n 2 ) v každém průchodu zařadím jeden prvek na své místo do již seřazené části lze vylepšit pomocí BinnarySearch nad seřazenou částí

QuickSort O(n log n) vyberu prvek, tzv. pivot pole roztřídím na dvě části menší a větší než pivot opakuji pro každou takto vzniklou část (rekurze) dokud nemám část s jedním prvkem kritickým okamžikem je výběr pivota v nejhorším případě vede na O(n 2 )

HeapSort O(n log n) principiálně vychází z řazení výběrem z binárního stromu binární strom reprezentován v poli hromadou = Heap

HeapSort O(n log n)

Řazení v.net Framework Enumerable.OrderBy() stabilní verze QuickSort, pivotem prvek z prostředka partition Array.Sort(), List<T>.Sort() nestabilní prosté pole, primitivní číselné typy a default Comparer=> SZSort nativní implementace QuickSort, pivotem prvek z prostředka partition(jde o obejití CompareTo() ve prospěch rychlejších přímých číselných porovnání), jinak NET1.0 prostý QuickSort, pivotem prvek z prostředka partition NET2.0 pivotem medián (prostřední hodnota) z prvního, prostředního a posledního prvku partition NET4.5 významné optimalizace, O(n log n) i pro worst-case

Array.Sort() v.net 4.5 O(n log n) worst dle BinaryCompatibility.TargetsAtLeast_Desktop_V4_5 false=> Depth Limited Quick Sort hloubka rekurze omezena na 32, poté se partitionseřadí HeapSortem pivot se volí jako prostřední hodnota z prvního, posledního a prostředního prvku partition true => Introspective Sort (1997) QuickSort do hloubky 2 Floor(log n), pak HeapSort partition4-16 prvků se řadí Insert Sortem zarážka rekurze pro partition velkosti 1, 2 a 3 -nedělí se, ale porovná přímo (obě verze)

Vyhledávání

Vyhledávací algoritmy prvku v množině sekvenční průchod O(n) binární půlení seřazené množiny O(log n) + vyhledávací stromy hashovací tabulka (rozptylování) O(1) přímý přístup přes index O(1)

Hashovacítabulka pozice prvku v poli se spočítá index = f(hash_code) hashovací(rozptylovací) funkce, např. H(key) = key mod n kolizní strategie chaining spojový seznam další pole open addressing linearprobing-sekvenčně se hledá volné místo quadraticprobing-postupně se krok kvadraticky zvyšuje (1., 2., 4., 8., 16. pozice atd.) rehashing/double hashing-další hashovacífunkce spočte další pozici nebo posun

.NET Hashtable hashovací funkce H(HashCode) = [HashCode + 1 + (((HashCode >> 5) + 1) % (HashSize 1))] % HashSize kolizní strategie = rehashing (double hashing) H k (HashCode) = [HashCode + k * (1 + (((HashCode >> 5) + 1) % (HashSize 1)))] % HashSize zvětšování při zaplnění loadfactor= 72% (odpovídá 1.0 ctoru!) thread-safe multi-read, single-write

Dictionary<TKey, TValue> jiná collision strategy chaining spojový seznam v poli (pomocí ofsetů) + FreeListpro díry private struct Entry { } public TKey key; public TValue value; public int hashcode; public int next; není thread-safe! rychlejší pro value-types

virtualintobject.gethashcode() musí splňovat pro stejné objekty (Equals) musí vracet stejný kód pro různé nemusí vracet různý dokud se objnezmění, musí vracet stejný kód (v čase per app) dobrá distribuce kódu (i malá změna obj, velká změna kódu) rychlý výpočet nevyhazovat výjimky obvyklá implementace využít existující.net implementaci public override int GetHashCode() { return this.id.gethashcode(); }

Operace nad.net datovými strukturami Přidání na konec Odebrání z konce Vložení doprostřed Odebrání z prostředka Přístup podle indexu Sekvenční přístup Vyhledávání elementu Poznámky Array O(n) O(n) O(n) O(n) O(1) O(1) O(n) seřaz. O(log N) Nejefektivnější využití paměti; vhodné v případě neměnného počtu položek. List<T> většinou O(1); nejhůře O(n) O(1) O(n) O(n) O(1) O(1) O(n) seřaz. O(log N) Vnitřně implementováno pomocí pole, při zaplnění se 2x zvětší. Přidávání nebo odebírání z prostředka či začátku jsou pomalé. LinkedList<T> O(1) O(1) O(1)* O(1)* O(n) O(1) O(n) Obousměrný spojový seznam. Pomalé přístupy doprostřed, rychlé přidávání na začátek a na konec. *) pokud už mám referenci na příslušnou položku Stack<T> většinou O(1); nejhůře O(n) O(1) N/A N/A N/A N/A N/A Zásobník, vhodné pro implementaci různých algoritmů. Last in, first out. Queue<T> většinou O(1); nejhůře O(n) O(1) N/A N/A N/A N/A N/A Fronta, vhodná pro implementaci různých algoritmů. First in, first out. Dictionary<K,T> HashTable většinou O(1); nejhůře O(n) O(1) většinou O(1); nejhůře O(n) O(1) O(1)* O(1)* O(1) Vnitřně implementováno pomocí hashovací tabulky, vhodné pro rychlé vyhledávání podle klíče. *) postavení pole Keys a Values má složitost O(n), ale stačí ho postavit jen jednou

LINQ to Objectsoptimalizace nespoléhá jen na IEnumerable<T> -sekvenční přístup MoveNext() zkouší různá rozhraní, která by mohla pomoci indexedaccess ElementAt, Skip, Last, LastOrDefault testuje implementaci rozhraní IList<T>, převod z O(n) na O(1) Countzkouší ICollectionpro O(1) místo O(n) Distinct, GroupBy, Joinpoužívá hashingpro O(n) místo O(n 2 ) Containszkouší ICollection, což např. pro HashSetje O(1) OrderBypoužívá stabilní QuickSort

Asymptotická časová složitost algoritmů O-notace SLOŽITOST PŘÍKLADY O(1) konstantní Přímý přístup, HashTable, Dictionary, HashMatch (SQL) O(log n) logaritmická BinnarySearch (půlení intervalu), vyhledávání ve stromu, IndexSeek O(n) linární Sekvenční průchod množinou vyhledávání v neseřazeném poli, přesuny dat, atp. IndexScan O(n log n) lineárně logaritmická Quick-Sort, Heap-Sort, Merge-Sort, Intro-Sort O(n 2 ) O(n m) kvadratická (m druhý vstup) Bubble-Sort, Insert-Sort, Shell-Sort, Select-Sort nested-loops O(c n ) exponenciální Prohledávání grafu možných řešení, problém obchodního cestujícícho (nalezení nejkratší možné cesty procházející všemi zadanými body na mapě)