Tijd is geen goede maatstaf, want is afhankelijk van computer waarop algoritme wordt gedraaid.

Vergelijkbare documenten
Zesde college complexiteit. 19 maart Mergesort, Ondergrens sorteren Quicksort, Shellsort

Zevende college complexiteit. 17 maart Ondergrens sorteren, Quicksort

Zevende college algoritmiek. 24 maart Verdeel en Heers

Zevende college complexiteit. 7 maart Mergesort, Ondergrens sorteren (Quicksort)

Hoofdstuk 3. Week 5: Sorteren. 3.1 Inleiding

Zevende college Algoritmiek. 6 april Verdeel en Heers

Zevende college algoritmiek. 23/24 maart Verdeel en Heers

Programmeermethoden. Recursie. week 11: november kosterswa/pm/

Opgaven QuickSort 3 mei 2019, Werkgroep, Datastructuren.

Divide & Conquer: Verdeel en Heers vervolg. Algoritmiek

Voortgezet Prog. voor KI

Programmeermethoden. Recursie. Walter Kosters. week 11: november kosterswa/pm/

Elfde college algoritmiek. 18 mei Algoritme van Dijkstra, Heap, Heapify & Heapsort

Uitwerking tentamen Analyse van Algoritmen, 29 januari

Datastructuren. Analyse van algoritmen. José Lagerberg. FNWI, UvA. José Lagerberg (FNWI, UvA) Datastructuren 1 / 46

Datastructuren en algoritmen voor CKI

Recursion. Introductie 37. Leerkern 37. Terugkoppeling 40. Uitwerking van de opgaven 40

Vierde college complexiteit. 26 februari Beslissingsbomen en selectie Toernooimethode Adversary argument


Uitgebreide uitwerking Tentamen Complexiteit, mei 2007

REEKS I. Zaterdag 6 november 2010, 9u

Vierde college algoritmiek. 23/24 februari Complexiteit en Brute Force

Tiende college algoritmiek. 13/21 april Gretige Algoritmen Algoritme van Dijkstra

Achtste college algoritmiek. 12 april Verdeel en Heers. Dynamisch Programmeren

Programmeermethoden NA. Week 6: Lijsten

Vierde college complexiteit. 16 februari Beslissingsbomen en selectie

algoritmiek - antwoorden

Vijfde college complexiteit. 21 februari Selectie Toernooimethode Adversary argument

recursie Hoofdstuk 5 Studeeraanwijzingen De studielast van deze leereenheid bedraagt circa 6 uur. Terminologie

Voorbeeldtentamen Inleiding programmeren (IN1608WI), Oktober 2003, , Technische Universiteit Delft, Faculteit EWI, Afdeling 2.

Tiende college algoritmiek. 26 april Gretige algoritmen

Programmeermethoden NA

Opgaven Binair Zoeken en Invarianten Datastructuren, 4 mei 2016, Werkgroep.

2 Recurrente betrekkingen

Divide & Conquer: Verdeel en Heers. Algoritmiek

Tweede college algoritmiek. 12 februari Grafen en bomen

Modelleren en Programmeren

Tiende college algoritmiek. 14 april Gretige algoritmen

Tiende college algoritmiek. 2 mei Gretige algoritmen, Dijkstra

public boolean equaldates() post: returns true iff there if the list contains at least two BirthDay objects with the same daynumber

Divide & Conquer: Verdeel en Heers. Algoritmiek

Datastructuren en Algoritmen

Small Basic Programmeren Text Console 2

Derde college complexiteit. 7 februari Zoeken

Zesde college algoritmiek. 18 maart Backtracking. Verdeel en Heers

Progra-MEER - Algoritmiek Leuven 20 maart 2018

Uitgebreide uitwerking Tentamen Complexiteit, juni 2018

Vijfde college algoritmiek. 9 maart Brute Force. Exhaustive search

Vierde college complexiteit. 14 februari Beslissingsbomen

Recursie. public static int faculteit( int n ){ // Deze functie berekent n! // pre: n = N en n >= 0 // post: faculteit = N!

Twaalfde college algoritmiek. 13 mei Branch & Bound Heap, Heapsort & Heapify

4EE11 Project Programmeren voor W. College 3, , Blok D Tom Verhoeff, Software Engineering & Technology, TU/e

Achtste college algoritmiek. 8 april Dynamisch Programmeren

1 Complexiteit. of benadering en snel

Algoritmiek. 15 februari Grafen en bomen

Minimum Opspannende Bomen. Algoritmiek

Derde college algoritmiek. 23 februari Complexiteit Toestand-actie-ruimte

Uitwerking tentamen Algoritmiek 9 juni :00 17:00

Programmeren (1) Examen NAAM:

Modelleren en Programmeren

Zoek- en sorteeralgoritmen en hashing

Programmeren in Java les 3

Lineaire data structuren. Doorlopen van een lijst

Uitwerking tentamen Algoritmiek 9 juli :00 13:00

Elke groep van 3 leerlingen heeft een 9 setje speelkaarten nodig: 2 t/m 10, bijvoorbeeld alle schoppen, of alle harten kaarten.

Opgaven Heaps Datastructuren, 8 juni 2018, Werkgroep.

De doorsnede van twee verzamelingen vinden

Inleiding Programmeren 2

Twaalfde college algoritmiek. 23 mei Branch & Bound, Heapsort

Tentamen Programmeren in C (EE1400)

De symmetrische min-max heap

Tiende college algoritmiek. 14 april Dynamisch Programmeren, Gretige Algoritmen, Kortste Pad met BFS

De doorsnede van twee verzamelingen vinden

Eerste Toets Datastructuren 11 juli 2018, , Educ-α.

9. Strategieën en oplossingsmethoden

Inleiding Programmeren 2

HOOFDSTUK 3. Imperatief programmeren. 3.1 Stapsgewijs programmeren. 3.2 If Then Else. Module 4 Programmeren

Uitgebreide uitwerking tentamen Algoritmiek Dinsdag 5 juni 2007, uur

Ingebouwde klassen & methodes

Informatica: C# WPO 11

Derde college algoritmiek. 22 februari Complexiteit Toestand-actie-ruimte

Amorized Analysis en Union-Find Algoritmiek

Uitgebreide uitwerking Tentamen Complexiteit, juni 2017

Modelleren en Programmeren

NAAM: Programmeren 1 Examen 29/08/2012

Tiende college algoritmiek. 4 mei Gretige Algoritmen Algoritme van Dijkstra

Vierde college algoritmiek. 1 maart Toestand-actie-ruimte Brute Force

Modelleren en Programmeren

Algoritmes in ons dagelijks leven. Leve de Wiskunde! 7 April 2017 Jacobien Carstens

Opgaven Lineair Sorteren Datastructuren, 15 mei 2019, Werkgroep.

Uitwerking Aanvullend tentamen Imperatief programmeren Woensdag 24 december 2014, uur

Vijfde college algoritmiek. 2/3 maart Exhaustive search

Eerste Toets Datastructuren 22 mei 2019, , Educ-β en Megaron.

REEKS II. Zaterdag 6 november 2010, 11u

Dynamisch Programmeren. Het Rugzakprobleem

Ieder tweetal heeft nodig: Een kopie van de slagschipspelletjes: 1. 1A, 1B voor spel A, 2B voor spel A, 3B voor spel 3

Een eenvoudig algoritme om permutaties te genereren

Examen Datastructuren en Algoritmen II

Heuristieken en benaderingsalgoritmen. Algoritmiek

Transcriptie:

Complexiteit of efficiëntie van algoritmen Hoe meet je deze? Tijd is geen goede maatstaf, want is afhankelijk van computer waarop algoritme wordt gedraaid. Een betere maatstaf is het aantal berekeningsstappen dat moet worden gedaan. We zijn niet zozeer geïnteresseerd in het precieze aantal stappen maar in de toename van het aantal stappen als het probleem 2 of 10 of 100 keer zo groot wordt gemaakt. for (int k=0; k < n; k++) { sum = sum + k; Als ik n 10 keer groter maak, moeten er 10 keer zo veel stappen worden gemaakt, bij 100 keer groter 100 keer meer stappen Daarom zeggen dat de complexiteit van dit algoritme O(n): orde n. Het aantal stappen neemt lineair toe met de grootte van n. Data Structuren en Algoritmen - Sorteren augustus 2013 1

Complexiteit vervolg for (int k=0; k < n; k++) { for (int m = 0; m < n; m++) {. for (int k=0; k < n; k++) { for (int m = 0; m < k; m++) {. Wat is de complexiteit van deze geneste lussen? Maakt het wat uit dat de binnenste lus in de ene tot n en de andere tot k loop? Neem bv n = 10: in bovenste: 100 stappen In onderste: 1+ 2 +.. + 10 55 stappen Dat lijkt verschillend maar: Als n = 100, in bovenste 10000 stappen in onderste 1 + 2 + 3 +.. + 100 = 5050 stappen In beide gevallen neemt het aantal stappen met +/- een factor 100 toe. Daarom voor beide is de complexiteit: O(n^2) Data Structuren en Algoritmen - Sorteren augustus 2013 2

Complexiteit vervolg Bestuderen van complexiteit van algoritmen is een belangrijke activiteit binnen de informatica. Zie bv: http://en.wikipedia.org/wiki/computational_complexity_theory De complexiteit van een algoritme zegt iets over de mogelijkheid het algoritme binnen redelijke tijd uit te voeren. Voor veel, op het oog eenvoudige, problemen zijn bv alleen exponentiële algoritmen bekend, dus O(2^n) - handelsreizigersprobleem: vindt de kortste route langs n steden - zo efficiënt mogelijk plaatsen van n componenten op een microchip - vinden van priemfactoren in een getal van lengte n (aantal decimalen). Heel belangrijk in de cryptografie. Praktisch betekent dit dat deze problemen voor n vanaf orde 100 niet meer oplosbaar zijn. Voor de eerste 2 bestaan goede benaderende algoritmen, die voor de praktijk goed genoeg zijn. Voor het vinden van priemfactoren is (nog) geen nietexponentiële methode gevonden! PKI maakt hier dankbaar gebruik van (behandeld in IBV) Data Structuren en Algoritmen - Sorteren augustus 2013 3

Sorteren Sorteren speelt een belangrijke rol in diverse algoritmen. Daarom is er behoefte aan efficiënte sorteer algoritmen. Er bestaan veel verschillende sorteer algoritmen, ieder met zijn eigen voor en nadelen. We beschouwen hier een aantal verschillende algoritmen vanuit complexiteitsoogpunt. Zie ook: http://www.sorting-algorithms.com/ Data Structuren en Algoritmen - Sorteren augustus 2013 4

Sorteren: Selection sort Het selection sort algoritme is eenvoudig: static void selsort(int a[], int n) {// n is lengte int m,h; for (int i = 0; i < n; i++) { m = i; for (int j = i+1; j < n; j++) { if (a[j] < a[m]) m = j;, h = a[i]; a[i] = a[m]; a[m] = h; Het selecteert steeds het kleinste element uit de rest van het array en zet dit vooraan. Dit algoritme heeft complexiteit n^2 (vanwege geneste lus). Dus voor een array van lengte 1000, moeten er 1.000.000 stappen doorlopen worden! Dit loopt dus heel hard op als n groter wordt! Als n = 1.000.000 dus 1.000.000.000.000 stappen! Vraag Hoelang duurt het ongeveer om een array van lengte 10.000.000 te sorteren als je 10^9 stappen per sec kan doen. Data Structuren en Algoritmen - Sorteren augustus 2013 5

Sorteren (vervolg) Gelukkig is het mogelijk efficiënter te sorteren. Een bekend snel sorteer algoritme is het Quicksort algoritme. Bij quicksort verdeel je een array herhaaldelijk in tweeën, waarbij alle elementen in het eerste deel kleiner zijn dan die in het tweede (gebeurt in split). static void qsort(int[] a, int low, int up) { int m; if (low < up) { m = split(a, low, up); qsort(a, low, m - 1); qsort(a, m + 1, up); static int split(int[] a, int low, int up) { int h, m; // hulp var m = low; // initialisatie // invariant: a[low.. m-1]< a[m] <= a[m+1..i-1] for (int i = low + 1; i <= up; i++) { if (a[i] < a[m]) { h = a[i]; a[i] = a[m+1]; a[m+1] = a[m]; a[m] = h; m++; return m; Aanroep: qsort(a,0,n-1); Data Structuren en Algoritmen - Sorteren augustus 2013 6

Sorteren (vervolg) De functie split splitst een array tussen de grenzen low en up [low..up] in twee stukken: elementen kleiner dan het eerste element (pivot element) en elementen groter dan de pivot Tijdens de uitvoering van split geldt voor i en m steeds het volgende: a[low.. m-1]< a[m] <= a[m+1..i-1] Als nu a[i] >= a[m] dan kunnen we i een opschuiven. Als a[i] < a[m] dan: schuiven we a[m+1] naar a[i], a[m] naar a[m+1] en a[i] naar a[m] (rotatie). Ga na dat we nu weer in de situatie van het plaatje zitten met i 1 opgeschoven. Wat is nu de complexiteit van qsort? split kost in de orde van n stappen (1 for lus). Hoe vaak wordt split aangeroepen: als het segment door split steeds in twee gelijke delen wordt gesplitst, roepen we split net zo vaak aan als we een segment kunnen halveren voordat de lengte van het segment 1 wordt. Dit is 2 log n. Data Structuren en Algoritmen - Sorteren augustus 2013 7

Sorteren (vervolg) De totale complexiteit wordt dus: n * 2 log n Voor een array van lengte 1000 is dit dus ongeveer: 10.000 (dus 100 * zo snel als selsort!). De voorwaarde was echter dat split een segment in ongeveer twee gelijke delen splitste. Als dit niet gebeurt is de situatie slechter. In het slechtste geval (bv. als het array al gesorteerd is) is de complexiteit weer n 2. Probeer maar eens uit op een klein voorbeeld! Let op: dit hangt natuurlijk ook af van de keuze van het pivot element. Hier kiezen we het eerste element steeds als pivot. Je kan ook het middelste element kiezen. In dat geval gaat het sorteren van een (minof-meer) al gesorteerd array veel sneller! Vraag Hoelang duurt het sorteren van ons array nu ( 2 log 10.000.000 = 23)? Data Structuren en Algoritmen - Sorteren augustus 2013 8

Merge sort Mergesort is een ander voorbeeld van een sorteer algoritme met complexiteit n* 2 log n. De belangrijkste verschillen met quicksort zijn: - quicksort sorteert in het oorspronkelijke array, mergesort heeft een hulp-array nodig. - mergesort is gegarandeerd n* 2 log n, terwijl quicksort in het slechtste geval complexiteit n 2 heeft. Het merge-sort algoritme is eenvoudiger dan quicksort. Het idee is het array herhaald in tweeën te delen tot er stukken over blijven met lengte 1 of 0. Twee gesorteerde delen kunnen ge-merged (samengevoegd) tot een gesorteerd gedeelte. De functie merge voegt de twee gesorteerde deelarrays [low..m] en [m+1..up] samen tot een nieuw gesorteerd array (schuift ze in elkaar door steeds het volgende kleinste element te kiezen). Op het einde wordt het sorteerde array weer teruggekopieerd naar het oorspronkelijk array: [low..up-1] De functie mergesort deelt het array in twee delen, sorteert deze beide recursief en merged dan deze twee gesorteerde delen. Data Structuren en Algoritmen - Sorteren augustus 2013 9

Merge sort static void merge(int a[],int h[],int low,int m,int up) { int i1 = low, i2 = m + 1, r = low; while (i1 <= m && i2 <= up) { if (a[i1] <= a[i2]) { h[r++] = a[i1++]; else { h[r++] = a[i2++]; while (i1 <= m) { h[r++] = a[i1++]; while (i2 <= up) { h[r++] = a[i2++]; for (i1 = low; i1 <= up; i1++) { a[i1] = h[i1]; static void mergesort(int a[], int h[], int low, int up) { int m; if (low < up) { m = (low + up) / 2; mergesort(a, h, low, m); mergesort(a, h, m + 1, up); merge(a, h, low, m, up); public static void main(string[] args) { int a[] = new int[]{6, 5, 4, 3, 2, 1, 7, 10, 13, 18, 20, 12, 15, 14, 9, 16, 17, 8, 19, 11; int h[] = new int[20]; mergesort(a, h, 0, 19); for (int i = 0; i < 20; i++) { System.out.print("" + a[i] + " "); System.out.println(); Data Structuren en Algoritmen - Sorteren augustus 2013 10

Heap sort Als laatste sorteer algoritme bekijken we heap sort. Heap sort heeft gegarandeerde n * 2 log n complexiteit en heeft geen extra array nodig! Het nadeel van heap sort is dat het algoritme nogal complex is. Het heap sort algoritme bestaat uit twee slagen: - In de eerste slag wordt het array in de zgn. heap conditie gebracht. - In de tweede slag wordt het array in heap conditie gesorteerd. Beide slagen hebben een complexiteit n * 2 log n. Data Structuren en Algoritmen - Sorteren augustus 2013 11

Heap conditie Om te begrijpen wat een array in heap conditie is moeten we het array voorstellen als een boom. Het array a is in de heap conditie als geldt: a[vader] >= a[zoon] voor alle vaders en zonen. Als a[i] een vader is dan zijn: a[2*i + 1] en a[2*i + 2] zijn zonen. Als a[i] een zoon is dan is a[(i-1) / 2] zijn vader (geheeltalige deling dus 5 / 2 = 2 bv). (Dit geldt niet voor a[0] (want (0-1) / 2 == 0!). Bij a[0] moeten we dus oppassen!) Data Structuren en Algoritmen - Sorteren augustus 2013 12

Algoritme om array in heap conditie te brengen static void makeheap(int a[], int n) { int i, elem; for (i = 1; i < n; i++) { elem = a[i]; moveup(a, elem, i); static void moveup(int a[], int elem, int blad) { // pre: a[0..blad-1] in heap conditie // post: a[0..blad] in heap conditie int father, son; son = blad; father = (son - 1) / 2; while (father >= 0 && elem > a[father]) { a[son] = a[father]; son = father; if (son == 0) { father = - 1; // om te stoppen else { father = (son - 1) / 2; a[son] = elem; Het idee is om beginnend in blad langs de takken van de boom omhoog te lopen totdat je of aan de top bent gekomen (elem is het grootste element), of je de juiste plaats hebt gevonden waar elem moet worden ingevoegd. Bij het omhoog lopen wordt een vader steeds in positie van de zoon geplaatst. Data Structuren en Algoritmen - Sorteren augustus 2013 13

Complexiteit van makeheap makeheap bevat een lus van lengte n - 1. moveup bevat een while-lus die van een blad in de boom tot hooguit de top loopt. Aangezien de boom niet dieper is dan 2 log n, kan moveup niet meer dan 2 log n stappen hebben. De totale complexiteit van makeheap wordt dus: n * 2 log n Data Structuren en Algoritmen - Sorteren augustus 2013 14

Sorteren van een array in heap conditie In de top van een heap bevindt zich altijd het grootste element. Dit element plaatsen we op de laatse plaats in het array waarna we het element dat op de laatste plaats stond opnieuw van bovenaf in de heap (maar nu eentje korter) plaatsen. Dit proces herhalen we totdat alle elementen aan de beurt zijn geweest. static void movedown(int a[], int elem, int last) { // pre: a[1..last] is een heap (a[0] ontbreekt) // pre: a[0..last] is een heap en elem is ingevoegd int father, son; father = 0; son = maxson(a, father, last); while (son <= last && elem < a[son]) { a[father] = a[son]; father = son; son = maxson(a, father, last); a[father] = elem; static void sortheap(int a[], int n) { int i, h; for (i = n - 1; i > 0; i--) { h = a[i]; a[i] = a[0]; movedown(a, h, i - 1); movedown plaatst een element van bovenaf in een heap h is het element dat geplaatst moet worden en i - 1 is de index van het laatste element in de heap (de heap wordt steeds 1 korter). movedown werkt op vergelijkbare manier als moveup, alleen ga je nu langs de taken naar beneden, waarbij je steeds de tak neemt van de grootste zoon en deze zoon eentje naar boven schuift. Data Structuren en Algoritmen - Sorteren augustus 2013 15

Sorteren van een array in heap conditie static int maxson(int a[], int father, int last) { int son; son = 2 * father + 1; if (son >= last) { return son; else if (a[son] < a[son + 1]) { return son + 1; else { return son; Voor de complexiteit van sortheap geldt hetzelfde verhaal als voor makeheap, deze is dus ook: n* 2 log n static void heapsort(int a[], int n) { makeheap(a, n); sortheap(a, n); Data Structuren en Algoritmen - Sorteren augustus 2013 16

Samenvatting Verschillende manieren van sorteren. Er is niet een beste. Voor korte arrays is selection sort ok qsort is vooral goed als het array een bijna random verdeling heeft mergesort is onafhankelijk van de verdeling maar heeft hulp array nodig heapsort heeft een vrij hoge overhead en daarom minder geschikt voor kleine arrays Opgave Oefen op papier met de verschillende algoritmen Volgende les moet je kunnen laten zien dat je deze op een voorbeeld kan toepassen. Data Structuren en Algoritmen - Sorteren augustus 2013 17