De doorsnede van twee verzamelingen vinden

Maat: px
Weergave met pagina beginnen:

Download "De doorsnede van twee verzamelingen vinden"

Transcriptie

1 De doorsnede van twee verzamelingen vinden Inleiding Daniel von Asmuth 12 februari 2015 Dit artikel vergelijkt enkele algoritmen om de doorsnede van twee verzamelingen of rijen van getallen te vinden. In een rij kunnen elementen meerdere keren voorkomen; we spreken in plaats van sets over bags of multisets de Nederlandse term is mij niet bekend die zonder extra moeite verwerkt kunnen worden. Het maakt een uitstap naar het probleem van getallen sorteren. I. Zoeken met geneste lussen Zet beide verzamelingen in twee rijen (arrays of lists). Loop elk element van verzameling B af om te zien of het eerste element van A daarin voorkomt, doe hetzelfde met het tweede element van A, etc. De meeste besproken algoritmen werken ook voor rijen getallen waarin elementen meer dan eens kunnen voorkomen. Het probleem wordt opgelost in O(N 2 ) stappen. Vanwege de eenvoud gebruiken we deze methode soms voor kleine verzamelingen. II. Vectoren van bits In de programmeertaal Pascal is het berekenen van de doorsnede of vereniging van twee verzamelingen een ingebouwde bewerking. Deelverzamelingen van een domein worden gerepresenteerd door vectoren van bits: als het i e bit hoog is dan bevat de verzameling dat element. Sorteren is hiermee niet nodig. Voor deelverzamelingen van grote domeinen kost deze methode veel tijd en geheugen, namelijk O(#D), waarin #D de grootte van het domein is. Als we overstappen op vectoren van gehele van gehele getallen dan kunnen we daarmee een eenvoudig sorteeralgoritme vormen. Initialiseer een array A ter grootte van #D met nullen en lees de getallen in: als je een waarde i vindt, dan hoog je A i op. Daarna loop je het array af en als A i = c dan druk je c keer het getal i af. De rekentijd is in de orde van O(#D + N) stappen; het benodigde geheugen kan onpraktisch zijn als D bijvoorbeeld uit de 32 bits gehele getallen bestaat. III. Sorteren van arrays Het originele quicksort algoritme van C.A.R. Hoare sorteert een rij getallen in situ. Het belangrijkste onderdeel is de functie partition(). Die kiest eerst een getal uit de rij, de pivot en laat de index variabelen i en j vanaf het begin en eind naar elkaar toe lopen en zoekt naar paren getallen A i > pivot en A j < pivot en verwisselt die telkens van plaats. Als i >= j, dan wordt de positie van de pivot geretourneerd en de quicksort() functie wordt recursief aangeroepen op het deelinterval met de getallen <= pivot en het deel met getallen >= pivot. Getallen die gelijk zijn aan de pivot kunnen dus aan beide zijden voorkomen, wat de implementatie vereenvoudigt.

2 <= pivot? >= pivot s i j m Figuur 1. Het deelarray s..m wordt gepartitioneerd Iets moeilijker wordt het als we een array in drie delen willen partitioneren, met links de waarden groter dan, rechts die kleiner dan in het midden die gelijk zijn aan de pivot. Een eenvoudige keuze voor de pivot is midden in het array. E.W. Dijkstra noemde dit het Dutch National Flag Problem. Het is soms nodig om het middensegment op te schuiven, wat deze oplossing iets langzamer maakt. Dat kan worden voorkomen door de mediaan te gebruiken als pivot, wat in theorie O(N) stappen kost. < pivot = pivot > pivot s i f g j m Figuur 2. Partitioneren in drie delen IV. De doorsnede van twee ongesorteerde rijen De quicksort() functie moet daarna de linker en rechter deelrijen sorteren en kan het midden laten staan, een besparing die niet opweegt tegen het extra werk voor de driedeling. Dit algoritme kan zodanig worden aangepast, dat de doorsnede wordt bepaald, terwijl we de twee arrays sorteren. De intersect() functie van listing I roept zichzelf recursief aan om de linker en rechter deelrijen te sorteren, en vergelijkt het verschil tussen f en g om te bepalen hoe vaak de pivot waarde voorkomt. De pivot is hier het gemiddelde van de hoogste en laagste waarde; omdat die niet in A en B hoeft voor te komen bewaren we de de waarden van A f en B g in A s en B s. Dit lost het probleem op in O(N.log(N)) stappen: een goede keus als de invoergegevens ongesorteerd zijn. Een nadeel van de aanpassing is dat de rijen na afloop niet volledig gesorteerd zijn, maar daarvoor besparen we iets tijd door af en toe getallen over te slaan. V. Drie algoritmen om lijsten sorteren We beginnen met een variant op het quicksort algoritme, waarin de te sorteren getallen in een linked list worden opgeslagen. Terwijl de sleutels aan de lijst worden toegevoegd zien we kans om het grootste en kleinste getal in de lijst te bepalen. We kiezen het gemiddelde van die twee als pivot. Een functie genaamd partition() haalt telkens een element uit de lijst en als de waarde kleiner of gelijk aan de pivot is, wordt het aan de linker lijst toegevoegd, en als het groter is aan de rechter. Merk op dat het splitsen van een lijst vrij gemakkelijk is. De quicksort() functie bepaalt de pivot en roept partition() aan om de lijst op te splitsen. Daarna roept ze zichzelf recursief aan om de beide deellijsten te sorteren en voegt ze samen tot één gesorteerde lijst. De oude pivot is daarbij maximum of minimum van de deellijst; dat zal net zo goed zijn als een willekeurige waarde uit de lijst. Een probleem ontstaat als alle te sorteren getallen dezelfde waarde hebben: alle getallen belanden in de linker deelrij en het algoritme stopt nooit; dat kan worden opgelost met een derde lijst

3 voor getallen die precies gelijk zijn aan de pivot. Een andere mogelijkheid is om de pivots beurtelings in de linker en rechter lijst te stoppen. Een lijst van N = 2 n getallen wordt gesplitst in twee lijsten van 2 n 1 getallen, vier lijsten van 2 n 2, enzovoorts, tot er na n = log(n) doorgangen nog N 1 overblijven, waardoor de rekentijd op O(N log(n)) uitkomt. Dit algoritme kan worden versneld door een lijst niet op te splitsen in twee helften, maar door de getalswaarden te verdelen over een array van N lijsten; in plaats van te vergelijken met een pivot delen we het interval tussen de grootste en kleinste waarde op in gelijke delen. Een lijst van N = 2 n getallen wordt gesplitst in delen van elk 2 n/2 getallen, gevolgd door 2 n/4, enzovoorts, tot er na n = log(log(n)) doorgangen nog N 2 0 overblijven, waardoor de rekentijd op O(N log(log(n))) uitkomt, ten koste van extra geheugengebruik. Nog meer snelheid wordt gewonnen met een array van N gelinkte lijsten, waardoor elke lijst gemiddeld 1 element krijgt. Merk op dat we de mediaan van een array in O(N) kunnen vinden met Hoares quickselect algoritme, dat de rij eerst partitioneert en dan1 partitie verder te doorzoeken. VI.Analyse Het laatste algoritme kost meer dan O(N) rekenstappen als we aannemen dat een bucket met 0 elementen toch 1 stap kost om te inspecteren, met 1 element ook 1 stap en 2 elementen in 2 stappen, en we voor grotere aantallen de partitionering recursief uitvoeren. We beginnen met een uniforme kansverdeling; als model kun je denken aan N worpen met een 'dobbelsteen' met N zijden. De verzameling van N N verschillende uitkomsten gaan we onderverdelen in partities, die aangeven hoe vaak getal voorkomt. Voor N = 4 bestaan er 5 partities: [ ] [1 1 2] [2 2] [1 3] [4] De partitie [ ] bevat alle permutaties van 1,2,3,4, terwijl de partitie [4] bestaat uit (1,1,1,1), (2,2,2,2), (3,3,3,3), (4,4,4,4) en [1 1 2] bestaat uit alle permutaties waarin één cijfer dubbel voorkomt. Een partitie is ook te beschouwen als een multiset van positieve gehele getallen waarvan de som N bedraagt. Op de zelfde manier waarop we hierboven bij een permutatie een partitie vonden, kunnen we aan een een partitie een klasse toevoegen. [ ] [4] [1 1 2] [1 2] [2 2] [2] [1 3] [1 1] [4] [1] Verder duiden we het aantal cijfers in een partitie aan met P. Het aantal permutaties van een partitie p is nu gelijk aan het aantal deelverzamelingen van 1..N met P elementen, vermenigvuldigd met het aantal permutaties van p, vermenigvuldigd met het aantal permutaties van de klasse k. Hierin is het aantal deelverzamelingen gelijk aan N P = N! N P! P! Het aantal permutaties van een partitie of klasse [x y z] kunnen we berekenen als

4 π N = N! x! y! z! Zo horen bij de partitie [1 1 2] de 4 deelverzamelingen 1, 2, 3, 1,2,4, 1,3,4 en 2,3,4. De klasse [1 2] heeft 3 permutaties, zodat bij deelverzameling 1,2,3 de reeksen (1,1,2,3), (1,2,2,3) en (1,2,3,3) horen, die elk weer op 12 manieren gepermuteerd kunnen worden, bijvoorbeeld (1,1,2,3), (1,1,3,2), (1,2,1,3), (1,2,3,1), (1,3,1,2), (1,3,2,1), (2,1,1,3), (2,1,3,1), (2,3,1,1), (3,1,1,2), (3,1,2,1), (3,2,1,1). We kunnen hiermee berekenen hoe groot de kans is dat een bucket gevuld is met M getallen. Iedere permutatie van een partitie [x y z] levert 1 uitkomst bij aan de buckets met x getallen, 1 uitkomst aan de buckets met y getallen, 1 maal aan de buckets met z getallen en N 3 maal aan de lege buckets. Zoals te verwachten blijken buckets met 1 getal erin het meest voor te komen. We ontdekken een regelmaat die uitgedrukt kan worden als P N = N 1 N Verder zien we dat de kans P(2) = P(1) / 2, plus wat meer buckets met 0 getallen dan met 2 erin. De kans op meer dan 2 getallen in een bucket loopt snel terug. Op deze manier hebben we van de uniforme kansverdeling van de sleutels een kansverdeling afgeleid voor het aantal getallen in een bucket, die een scherpe piek vertoont. Voor niet uniforme verdelingen, zoals de normale kansverdeling, laat zich aanzien dat het aantal buckets met meer dan 2 elementen groter is. Als we van deze kansverdeling het gemiddelde over alle niet lege buckets nemen, dan krijgen we een functie die heel langzaam groeit met N. De gemiddelde rekentijd t(n) kan uit de kansverdeling worden berekend door aan te nemen dat een bucket met M elementen vanwege de recursie 1 + t(m) kost voor M in 2..N en 1 stap voor M = 0 of 1. We krijgen dan een recurrente betrekking die we iteratief kunnen berekenen. t N = N M=0 N 1 π M 1 t M N π M M=0 De functie zal met N langzamer stijgen dan t(n) = log(log(n)), zie de grafiek hieronder Het sorteeralgoritme is te vergelijken met radix sort, dat een array van gehele getallen sorteert in O(N) stappen. VII.Hashing Hashing kan sneller zijn dan sorteren. Daarvoor kiezen het aantal hash buckets bijvoorbeeld op de wortel van #B (als #A > #B) en verdelen de rij A daarover en verdelen de rij B over een even grote hash tabel. Daarna moet je de doorsneden bepalen tussen de inhoud van corresponderende paren buckets, bijvoorbeeld met algoritme III. Als tenminste één van de buckets leeg is, kun je die overslaan. Dit algoritme zal Ω(N) rekenstappen vergen, maar de output is ongesorteerd. Ook het bovengenoemde algoritme om gelinkte lijsten te sorteren kan worden aangepast zodat verzamelingen A en B elk over een rij van gelinkte lijsten worden verdeeld, die dan paarsgewijs verder worden gesorteerd en geteld. Hiermee kan de doorsnede worden bepaald in bijna lineaire rekentijd.

5 Figuur 3. Rekentijd voor sorteren rij van gelinkte lijsten VIII.Twee gesorteerde rijen sequentieel vergelijken Als de rijen A en B al gesorteerd zijn, dan kan de doorsnede eenvoudig worden gevonden door telkens de kleinste elementen van beide rijen te vergelijken: als ze gelijk zijn rapporteer je het getal en verwijdert beide elementen, anders verwijder je het kleinste en vergelijkt weer de twee kleinste, enzovoorts. Dit lost het probleem eenvoudig op in O(N) stappen. Voor multisets kan het algoritme worden versneld met een array waarin per positie de waarde van het element wordt opgeslagen plus het aantal malen dat ze voorkomt. IX. Binaire zoekbomen De representatie met vectoren van bits verspilt geheugen wanneer het domein groot is en de verzamelingen kleiner; in zo'n geval zijn gelinkte lijsten beter, maar binaire bomen zijn sneller te doorzoeken. Omdat het domein bekend is, is het niet nodig om de zoeksleutels expliciet op te slaan; een waarde correspondeert met een vaste positie in de boom, zodat diens voorouders ook een knoop beslaan wanneer ze 0 keer voorkomen. Dat kost per getal maximaal log(#d) knopen aan geheugenruimte, met een maximum van O(#D) voor de hele boom. In plaats van een bit, gebruiken we een integer veld om te tellen hoe vaak een getal in de verzameling voorkomt. De broncode is te vinden in listing 2. Stelling I. De functie intersect() drukt alle elementen van de doorsnede van boom A en boom B éénmaal af in stijgende volgorde.

6 We geven een synopsis van het bewijs. De functie intersect() bestaat uit niets meer dan een aanroep van intersect_r( tree_a, tree_b, 0, M 1) voor het domein [0..M 1]. A. Als één (deel)verzameling leeg is, dan is de doorsnede van A en B ook leeg. Het if statement zorgt in dat geval dat de functie geen uitvoer produceert. if( node1 == NULL node2 == NULL) return; B. De bomen zijn zo opgezet dat knopen steeds corresponderen met dezelfde zoeksleutel. De node1 en node2 parameters verwijzen bij de eerste aanroep naar de beide wortels, bij de eerste recursieve aanroep naar diens linker zoon, de tweede recursieve aanroep naar diens rechter zoon. Dus verwijzen de parameters altijd naar de zelfde positie in de bomen. C. Als de doorsnede van de deelbomen, waarvan node1 en node2 de wortels zijn, niet leeg is, dan zorgt het for statement dat de functie de juiste uitvoer produceert als het om twee bladen gaat en geen uitvoer als een interne knoop bij is. for( i = 0; i < min( node1 >count, node2 >count); i++) printf( "Gevonden: \t%05d \n", node_key); D. De intersect_r() functie vergelijkt eerst de linker zonen, dan de knopen node1 en node2 zelf en vervolgens de rechter zonen. intersect_r( node1 >left, node2 >left, lo, node_key 1); for( i = 0; i < min( node1 >count, node2 >count); i++) printf( "Gevonden: \t%05d \n", node_key); intersect_r( node1 >right, node2 >right, node_key + 1, hi E. De intersect_r() functie drukt eerst de doorsnede van de linker deelbomen af, dan van de wortels van de deelbomen en vervolgens van de rechter deelbomen. Dit volgt met structurele inductie op bewering D, samen met de beweringen A, B, en C, die ervoor zorgen dat elk element van de doorsnede precies één keer wordt afgedrukt. F. De intersect_r() functie drukt elementen van de doorsnede op volgorde af. De parameters lo en hi zijn de onder en bovengrenzen van de deelbomen en de wortel deelt dat interval in drie delen, waarvan eerst het interval [0..node_key 1] wordt verwerkt, dan node_key zelf, gevolgd door [node_key+1, hi]. Dit volgt uit de code onder bewering D. int node_key = min(max(hi / 2 + lo / 2 + 1, lo), hi); G. Het domein [0..M] wordt zodanig onderverdeeld, dat elk element correspondeert met precies één knoop in de zoekboom. Voor interval [0..0] is de sleutel 0 en wordt intersect_r() aangeroepen op de delen [0.. 1] en [2..0]. Dat zijn ongeldige waarden en de NULL test zal die afvangen. Voor interval [0..1] is de sleutel 1 en wordt intersect_r() aangeroepen op de delen [0..0] en [2..0]. Het laatste is ongeldig en wordt door de NULL test afgevangen. Voor interval [0..2] is de sleutel 2 en wordt intersect_r() aangeroepen op de delen [0..1] en [3..2]. Het laatste is ongeldig en wordt door de NULL test afgevangen. Voor interval [3..3] is de sleutel 3 en wordt intersect_r() aangeroepen op de delen [3..2] en [4..3]. Die zijn ongeldig en worden door de NULL test afgevangen. Voor interval [0..3] is de sleutel 2 en wordt intersect_r() aangeroepen op de delen [0..1] en [3..3]. De bewering G klopt dus voor M = 0, 1, 2 en 3; inductie bewijst ze voor alle waarden van M. Stelling II. Een deelverzameling van domein D met e elementen kan worden gerepresenteerd door een binaire boom met ten hoogste 2 e knopen.

7 Als er e bladen zijn en e is een macht van 2, dan heeft de zoekboom e/2 = e 1 interne knopen nodig. In ons geval kunnen interne knopen eveneens elementen van de verzameling representeren. Voor multisets worden alle elementen met dezelfde waarde in 1 knoop opgeslagen en in één rekenstap verwerkt. Stelling III. Algoritme IX bepaalt de doorsnede van twee verzamelingen in O( #( A B )) rekentijd. Voor stelling I hebben we laten zien dat elk blad en elke interne knoop die nodig is voor een binaire boom van het resultaat één keer verwerkt wordt en in stelling II dat er minder interne knopen dan bladen nodig zijn. Voor elk blad in het resultaat zal intersect_r() tweemaal worden aangeroepen met een NULL parameter. De kosten van de if test vergroten de tijd voor de verwerking van het blad maar weinig, dus is de stelling geldig. Het opbouwen van de zoekboom kost O(N.log(N)) stappen, maar als de invoer gesorteerd is reduceert dat tot O(N). Eventueel is het mogelijk om het sorteren en opbouwen te combineren. X. Gesorteerde rijen Hierboven gebruikten we een boom waarin de getalswaarden impliciet uit de locatie volgen, als we daarentegen de locatie van de elementen vastleggen, krijgen we een array; als beide impliciet zijn, komen we uit op de bit vectoren van paragraaf II. De broncode is te vinden in listing 3. Dit algoritme is generieker dan het vorige. De zoeksleutels zijn niet van te voren vastgelegd, zodat geen geheugenruimte aan lege knopen verspild wordt. Het voornaamste verschil met algoritme VIII is dat de rij niet sequentieel wordt doorlopen, maar telkens wordt opgedeeld in twee delen van gelijke lengte. Als de zoeksleutel voor rij A kleiner is dan die voor rij B, dan kunnen we kleinere waarden dan a key vinden in de linker deelbomen van A en B, maar voor grotere waarden moeten we de rechter deelboom van A vergelijken met de gehele boom B; alleen als beide sleutels aan elkaar gelijk zijn kunnen beide bomen worden opgesplitst. De parameters xmin en xmax worden gebruikt om de zoektocht op tijd te beëindigen. De manier waarop dit interval recursief wordt gesplitst garandeert dat elke sleutelwaarde één keer wordt verwerkt; aanroepen van intersect() met overlappende array indices worden afgevangen door de if statements aan het begin. Die zorgen er tevens voor dat een deelboom van A niet verder wordt afgelopen als de deelboom van B al leeg is en omgekeerd, zodat de rekentijd van dit algoritme eveneens lineair toeneemt met de grootte van de uitvoer. Tests met algoritme IX geven aan dat het aantal recursieve aanroepen ongeveer 150 % van de grootte van de verzameling bedraagt, tegen 500 % voor algoritme X, terwijl ze ongeveer evenveel rekentijd kosten. Een oorzaak ligt in de malloc() functie om geheugen voor de boom te reserveren. Deze oplossing lijkt sterk op het divide and conquer merge van V.J. Duvanenko ( drdobbs.com/parallel/parallel merge/ ); hier de binaire zoek functie in de hoofdrecursie ingebouwd. Duvanenko bereikt daarmee toch een lineaire rekentijd, want als element i in O(log(n)) stappen wordt verwerkt, dan kost de gehele verzameling log N i N t N = =2 N i=1 2 i

8 Conclusies Met de algoritmen IX en X uit dit artikel is het mogelijk is het mogelijk om de doorsnede van twee verzamelingen te bepalen in lineaire rekentijd. Voor non uniform verdeelde zoeksleutels zal het iets sneller gaan. Bovengenoemde methoden vereisen dat de invoer gesorteerd is; als dat niet het geval is zorgen de algoritmen IV en VII en passant voor die sortering. De algoritmen IV, IX en X zijn alle drie gebaseerd op het recursief opsplitsen van een interval met verschillende oplossingen voor het probleem dat de mediaan van A niet die van B is. Uit de analyse van paragraaf VI volgt, dat als we de arrays elk verdelen over N buckets, een groot deel van de paren 0 elementen in bucket A i of B i zal bevatten, zodat we het antwoord vinden zonder alle elementen te testen. De overgeslagen elementen zijn te vinden in de bladen van de zoekbomen: een niveau hoger hebben we buckets met gemiddeld 2 elementen, zodat de kans op een lege al veel kleiner is, dan N/4,... Het resultaat is dat bijna de hele zoekboom doorlopen moet worden. Veel hogere snelheden zijn mogelijk door de algoritmen IX en X zodanig aan te passen, dat de twee recursieve functieaanroepen parallel worden uitgevoerd; door de resultaten tijdelijk op te slaan kunnen ze zonder weer te sorteren op volgorde worden afgedrukt.

9 Bijlagen C programma code geschreven onder Linux Listing 1. Rij sorteren en doorsnede bepalen #include <stdio.h> #include <stdlib.h> #include <limits.h> #include <time.h> #define N 40 #define M 60 #define min(a,b) (((a) < (b))? (a) : (b)) #define max(a,b) (((a) > (b))? (a) : (b)) int int a[ N]; b[ N]; /* vul rij met willekeurige waarden */ static void fill_arrays( void) int i; srand( time( 0)); for( i = 0; i < N; i++) a[i] = rand() % M; srand( time( 0) + 1); for( i = 0; i < N; i++) b[i] = rand() % M; /* druk de rijen af */ static void print_arrays() int i; for( i = 0; i <= N 1; i++) printf( "\t%05d\t%05d\n", a[i], b[i]); printf( "\n"); /* druk gemeenschappelijke elementen af */ static void report( int pivot, int amin, int amax, int bmin, int bmax) int i; for( i = 0; i <= min( amax amin, bmax bmin); i++) printf( "%05d\n", pivot); /* tel gemeenschappelijke elementen */ static void report2( int pivot, int amin, int amax, int bmin, int bmax) int ac = 0; int bc = 0; int i; for( i = amin; i <= amax; i++) if( a[i] == pivot) ac++; for( i = bmin; i <= bmax; i++) if( b[i] == pivot) bc++;

10 report( pivot, 1, ac, 1, bc); /* zoek minimum en maximum waarden */ static void find_min_max( int *a, int amin, int amax, int *lo, int *hi) int i; *lo = INT_MAX; *hi = INT_MIN; for( i = amin; i <= amax; i++) if( a[i] < *lo) *lo = a[i]; if( a[i] > *hi) *hi = a[i]; /* verwissel twee getallen */ static void swap( int *a, int *b) int c; c = *a; *a = *b; *b = c; /* * Splits een rij in drie delen met waarden <, =, > pivot * In parms: a: het array * pivot: waarde om mee te vergelijken * s: ondergrens van interval * m: bovengrens van interval * Uit parms: f: laagste index met pivot * g: hoogste index met pivot */ static void partition( int *a, int pivot, int s, int m, int *f, int *g) int i = s; int j = m; while( i < j) /* elementen die op juiste plaats staan overslaan */ if( a[i] < pivot) i++; /* elementen verplaatsen */ if( a[i] == pivot && i < *f) swap( &a[i], &a[ (*f)]); if( a[j] > pivot) j ; if( a[j] == pivot && j > *g) swap( &a[j], &a[++(*g)]); if( a[i] > pivot && a[j] < pivot) swap( &a[i++], &a[j ]); /* testen of we klaar zijn */ if( a[(*g)+1] == pivot) (*g)++; if( i == *f && j == *g) break; /* de pivots een positie opschuiven */ if( i == *f) if( a[(*g)+1] <= pivot) swap( &a[(*f)++], &a[++(*g)]); if( a[j] < pivot)

11 swap( &a[*f], &a[j]); while( a[*f]!= pivot) (*f)++; if( *f > *g) *g = *f; if( j == *g) if( a[(*f) 1] >= pivot) swap( &a[(*g) ], &a[ (*f)]); if( a[i] > pivot) swap( &a[*g], &a[i]); while( a[*g]!= pivot) (*g) ; if( *g < *f) *f = *g; /* Bepaal de doorsnede van deelrijen tussen Amin en Amax, Bmin en Bmax */ /* met lo en hi als laagste en hoogste waarden */ static void intersect( int *a, int amin, int amax, int *b, int bmin, int bmax, int lo, int hi) int f, g, ai, aj, bi, bj; int pivot, as, bs; /* tests voor geval dat we (bijna) klaar zijn */ if (amin > amax bmin > bmax) return; if (amin == amax) report2( a[amin], amin, amax, bmin, bmax); return; if( bmin == bmax) report2( b[bmin], amin, amax, bmin, bmax); return; /* De pivot wordt bepaald door lo en hi en hoeft zelf niet voor te komen */ as = bs = pivot = (lo + hi) / 2; ai = aj = f = (amin + amax) / 2; bi = bj = g = (bmin + bmax) / 2; /* partitioneer beide arrays */ if( amin < amax) swap( &as, &a[f]); partition( a, pivot, amin, amax, &ai, &aj); if( as < pivot) swap( &as, &a[ai++]); if( as > pivot) swap( &as, &a[aj ]); ai = aj = amin; if( bmin < bmax) swap( &bs, &b[g]); partition( b, pivot, bmin, bmax, &bi, &bj); if( bs < pivot) swap( &bs, &b[bi++]); if( bs > pivot) swap( &bs, &b[bj ]);

12 bi = bj = bmin; /* sorteer de arrays recursief */ intersect( a, amin, ai 1, b, bmin, bi 1, lo, pivot 1); report( pivot, ai, aj, bi, bj); intersect( a, aj+1, amax, b, bj+1, bmax, pivot + 1, hi); int main( int argc, char **argv) int alo, ahi, blo, bhi; fill_arrays(); print_arrays(); find_min_max( a, 0, N 1, &alo, &ahi); find_min_max( b, 0, N 1, &blo, &bhi); intersect( a, 0, N 1, b, 0, N 1, min( alo, blo), max( ahi, bhi)); exit( 0);

13 Listing 2. Doorsnede van twee binaire bomen #include <stdio.h> #include <stdlib.h> #include <stdint.h> #include <time.h> #define min(a,b) (((a) < (b))? (a) : (b)) #define max(a,b) (((a) > (b))? (a) : (b)) #define N 30 /* aantal elementen in verzameling */ #define M 100 /* maximum waarde van een element */ int a[ N]; /* tijdelijke opslag voor getalswaarden */ int b[ N]; typedef struct node int count; /* hoevaak de waarde voorkomt */ struct node *left; /* wijzer naar kleinere elementen */ struct node *right; /* wijzer naar grotere elementen */ NODE, *NODE_P; /* maak een nieuw element voor in de boom */ static NODE_P create_node( void) NODE_P result; if((result = (NODE_P) malloc( sizeof( NODE))) == NULL) fprintf( stderr, "Malloc() failed \n"); exit( 1); result > count = 0; result >left = result >right = NULL; return result; /* recursief deel van opbouwfunctie */ static void build_tree_r( NODE_P *node_p, int *keys, int *i, int lo, int hi) int node_key = min(max(hi / 2 + lo / 2 + 1, lo), hi); if( *i >= N keys[*i] < lo keys[*i] > hi) return; /* test om recursie te termineren */ if( *node_p == NULL) *node_p = create_node(); /* voeg nieuwe knoop toe aan boom */ if( keys[*i] == node_key) (*node_p) >count++; /* tel het element mee */ ++*i; if( keys[*i] < node_key) /* getal te klein; zoek verder */ build_tree_r( &(*node_p) >left, keys, i, lo, node_key 1); if( keys[*i] > node_key) /* getal te groot; zoek verder */ build_tree_r( &(*node_p) >right, keys, i, node_key + 1, hi); build_tree_r( node_p, keys, i, lo, hi); /* ga verder met volgende getal */ /* Bouw een zoekboom van de elementen van een gesorteerde rij */ void build_tree( NODE_P *root, int *keys) int i = 0; build_tree_r( root, keys, &i, 0, M 1); /* Recursief deel van de bepaling van de doorsnede */ static void intersect_r( NODE_P node1, NODE_P node2, int lo, int hi)

14 int node_key = min(max(hi / 2 + lo / 2 + 1, lo), hi); int i; if( node1 == NULL node2 == NULL) /* controleer of we al klaar zijn */ return; intersect_r( node1 >left, node2 >left, lo, node_key 1); /* het kleinste aantal malen dat element voorkomt bepaalt de doorsnede */ for( i = 0; i < min( node1 >count, node2 >count); i++) printf( "Gevonden: \t%05d \n", node_key); intersect_r( node1 >right, node2 >right, node_key + 1, hi); /* Druk de gemeenschappelijke elementen in twee bomen af */ void intersect( NODE_P tree1, NODE_P tree2) printf( "\nde doorsnede bestaat uit: \n"); intersect_r( tree1, tree2, 0, M 1); /* Vul rijen met willekeurige getallen */ static void fill_arrays( void) int i; srand( time( 0)); for( i = 0; i < N; i++) a[i] = rand() % M; srand( time( 0) + 1); for( i = 0; i < N; i++) b[i] = rand() % M; /* een hulpfunctie voor quicksort */ static int compare( const void *a, const void *b) return *(int *)a *(int *)b; /* het hoofdprogramma */ int main( int argc, char **argv) NODE_P tree_a = NULL; NODE_P tree_b = NULL; fill_arrays(); /* vul geheugen met de getallen */ qsort( a, N, sizeof( int), compare); qsort( b, N, sizeof( int), compare); /* sorteer de waarden eerst */ build_tree( &tree_a, a); /* om de bomen snel op te bouwen */ build_tree( &tree_b, b); intersect( tree_a, tree_b); /* bepaal de doorsnede */ return 0;

15 Listing 3. Doorsnede van twee gesorteerde rijen #include <stdio.h> #include <stdlib.h> #include <stdint.h> #include <time.h> #define N 30 #define M 60 #define min(a,b) (((a) < (b))? (a) : (b)) #define max(a,b) (((a) > (b))? (a) : (b)) int int a[ N]; b[ N]; /* there a standard sign functionsignum sgn in c c */ int sgn(int val) return (val > 0) (val < 0); /* vul rijen met willekeurige getallen */ void fill_arrays( void) int i; srand( time( 0)); for( i = 0; i < N; i++) a[i] = rand() % M; srand( time( 0) + 1); for( i = 0; i < N; i++) b[i] = rand() % M; /* hulpfunctie voor sorteren */ static int compare( const void *a, const void *b) return *(int *)a *(int *)b; void print_arrays( void) int i; for( i = 0; i < N; i++) printf( "%d:\t%05d\t%05d\n", i, a[i], b[i]); printf( "\n"); /* druk resultaat af */ void found( int x) if( x >= 0) printf( "Found value\t%05d \n", x); /* bepaal de doorsnede van twee (deel)rijen A en B */ static void intersect( int a[], int amin, int amax, int b[], int bmin, int bmax, int xmin, int xmax) int ai = min(max(amin / 2 + amax / 2 + 1, amin), amax); int bi = min(max(bmin / 2 + bmax / 2 + 1, bmin), bmax); int aj = ai; int bj = bi; int akey = a[ai]; /* de zoeksleutels */ int bkey = b[bi]; int i; /* controleer of de deelrijen leeg zijn */ if((amin > amax) (bmin > bmax)) return; /* controleer of de waarden binnen de grenzen vallen */ if((a[amin] > xmax) (a[amax] < xmin) (b[bmin] > xmax) (b[bmax] < xmin))

16 return; /* zoek getallen gelijk aan de sleutels */ while((ai > amin) && (a[ai 1] == akey)) ai ; while((aj < amax) && (a[aj+1] == akey)) aj++; while((bi > bmin) && (b[bi 1] == bkey)) bi ; while((bj < bmax) && (b[bj+1] == bkey)) bj++; /* pas het algoritme recursief toe op de rest van het array */ switch( sgn( akey bkey)) case 1: intersect( a, amin, aj, b, bmin, bi 1, xmin, akey); intersect( a, aj+1, amax, b, bmin, bmax, akey+1, xmax); break; case 1: intersect( a, amin, ai 1, b, bmin, bj, xmin, bkey); intersect( a, amin, amax, b, bj+1, bmax, bkey+1, xmax); break; case 0: intersect( a, amin, ai 1, b, bmin, bi 1, xmin, akey 1); for( i = 0; i <= min( aj ai, bj bi); i++) found( akey); intersect( a, aj+1, amax, b, bj+1, bmax, akey+1, xmax); break; int main( int argc, char **argv) fill_arrays(); qsort( a, N, sizeof( int), compare); /* standaard quicksort functie */ qsort( b, N, sizeof( int), compare); print_arrays(); intersect(a, 0, N 1, b, 0, N 1, max(a[0],b[0]), min(a[n 1],b[N 1])); exit( 0);

De doorsnede van twee verzamelingen vinden

De doorsnede van twee verzamelingen vinden De doorsnede van twee verzamelingen vinden Daniel von Asmuth Inleiding Dit artikel probeert enkele algoritmen te vergelijken om de doorsnede van twee verzamelingen of rijen van getallen te vinden. In een

Nadere informatie

Een eenvoudig algoritme om permutaties te genereren

Een eenvoudig algoritme om permutaties te genereren Een eenvoudig algoritme om permutaties te genereren Daniel von Asmuth Inleiding Er zijn in de vakliteratuur verschillende manieren beschreven om alle permutaties van een verzameling te generen. De methoden

Nadere informatie

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

Zevende college complexiteit. 7 maart Mergesort, Ondergrens sorteren (Quicksort) College 7 Zevende college complexiteit 7 maart 2017 Mergesort, Ondergrens sorteren (Quicksort) 1 Inversies Definitie: een inversie van de permutatie A[1],A[2],...,A[n] is een paar (A[i],A[j]) waarvoor

Nadere informatie

Zevende college algoritmiek. 24 maart Verdeel en Heers

Zevende college algoritmiek. 24 maart Verdeel en Heers Zevende college algoritmiek 24 maart 2016 Verdeel en Heers 1 Verdeel en heers 1 Divide and Conquer 1. Verdeel een instantie van het probleem in twee (of meer) kleinere instanties 2. Los de kleinere instanties

Nadere informatie

Zevende college Algoritmiek. 6 april Verdeel en Heers

Zevende college Algoritmiek. 6 april Verdeel en Heers Zevende college Algoritmiek 6 april 2018 Verdeel en Heers 1 Algoritmiek 2018/Backtracking Programmeeropdracht 2 Puzzel 2: D O N A L D G E R A L D + R O B E R T Elke letter stelt een cijfer voor (0,1,...,9)

Nadere informatie

Zevende college algoritmiek. 23/24 maart Verdeel en Heers

Zevende college algoritmiek. 23/24 maart Verdeel en Heers Zevende college algoritmiek 23/24 maart 2017 Verdeel en Heers 1 Algoritmiek 2017/Backtracking Tweede Programmeeropdracht 0 1 2 3 0 1 2 3 4 1 2 3 4 5 2 Algoritmiek 2017/Backtracking Tweede Programmeeropdracht

Nadere informatie

Lineaire data structuren. Doorlopen van een lijst

Lineaire data structuren. Doorlopen van een lijst Lineaire data structuren array: vast aantal data items die aaneensluitend gestockeerd zijn de elementen zijn bereikbaar via een index lijst: een aantal individuele elementen die met elkaar gelinkt zijn

Nadere informatie

Zevende college complexiteit. 17 maart Ondergrens sorteren, Quicksort

Zevende college complexiteit. 17 maart Ondergrens sorteren, Quicksort College 7 Zevende college complexiteit 17 maart 2008 Ondergrens sorteren, Quicksort 1 Sorteren We bekijken sorteeralgoritmen gebaseerd op het doen van vergelijkingen van de vorm A[i] < A[j]. Aannames:

Nadere informatie

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

Achtste college algoritmiek. 12 april Verdeel en Heers. Dynamisch Programmeren Achtste college algoritmiek 12 april 2019 Verdeel en Heers Dynamisch Programmeren 1 Uit college 7: Partitie Partitie Partitie(A[l r]) :: // partitioneert een (sub)array, met A[l] als spil (pivot) p :=

Nadere informatie

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

Zesde college complexiteit. 19 maart Mergesort, Ondergrens sorteren Quicksort, Shellsort College 6 Zesde college complexiteit 19 maart 2019 Mergesort, Ondergrens sorteren Quicksort, Shellsort 1 Vorige keer Voor sorteeralgoritmen gebaseerd op arrayvergelijkingen, waarbij per arrayvergelijking

Nadere informatie

Divide & Conquer: Verdeel en Heers vervolg. Algoritmiek

Divide & Conquer: Verdeel en Heers vervolg. Algoritmiek Divide & Conquer: Verdeel en Heers vervolg Algoritmiek Algoritmische technieken Vorige keer: Divide and conquer techniek Aantal toepassingen van de techniek Analyse met Master theorem en substitutie Vandaag:

Nadere informatie

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

Programmeermethoden. Recursie. week 11: november kosterswa/pm/ Programmeermethoden Recursie week 11: 21 25 november 2016 www.liacs.leidenuniv.nl/ kosterswa/pm/ 1 Pointers Derde programmeeropgave 1 Het spel Gomoku programmeren we als volgt: week 1: pointerpracticum,

Nadere informatie

Achtste college algoritmiek. 8 april Dynamisch Programmeren

Achtste college algoritmiek. 8 april Dynamisch Programmeren Achtste college algoritmiek 8 april 2016 Dynamisch Programmeren 1 Werkcollege-opgave Dutch Flag Problem Gegeven een array gevuld met R, W, en B. Reorganiseer dit array zo dat van links naar rechts eerst

Nadere informatie

Hoofdstuk 3. Week 5: Sorteren. 3.1 Inleiding

Hoofdstuk 3. Week 5: Sorteren. 3.1 Inleiding Hoofdstuk 3 Week 5: Sorteren 3.1 Inleiding Zoals al bleek in college 1 kunnen zoekalgoritmen veel sneller worden uitgevoerd, indien we weten dat de elementen in de lijst, waarin wordt gezocht, geordend

Nadere informatie

Vierde college complexiteit. 16 februari Beslissingsbomen en selectie

Vierde college complexiteit. 16 februari Beslissingsbomen en selectie Complexiteit 2016/04 College 4 Vierde college complexiteit 16 februari 2016 Beslissingsbomen en selectie 1 Complexiteit 2016/04 Zoeken: samengevat Ongeordend lineair zoeken: Θ(n) sleutelvergelijkingen

Nadere informatie

Tentamen Programmeren in C (EE1400)

Tentamen Programmeren in C (EE1400) TU Delft Tentamen Programmeren in C (EE1400) 3 feb. 2012, 9.00 12.00 Faculteit EWI - Zet op elk antwoordblad je naam en studienummer. - Beantwoord alle vragen zo nauwkeurig mogelijk. - Wanneer C code gevraagd

Nadere informatie

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

Tijd is geen goede maatstaf, want is afhankelijk van computer waarop algoritme wordt gedraaid. 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

Nadere informatie

Uitwerking tentamen Algoritmiek 10 juni :00 13:00

Uitwerking tentamen Algoritmiek 10 juni :00 13:00 Uitwerking tentamen Algoritmiek 10 juni 2014 10:00 13:00 1. Dominono s a. Toestanden: n x n bord met in elk hokje een O, een X of een -. Hierbij is het aantal X gelijk aan het aantal O of hooguit één hoger.

Nadere informatie

EE1400: Programmeren in C BSc. EE, 1e jaar, , 3e college

EE1400: Programmeren in C BSc. EE, 1e jaar, , 3e college EE1400: Programmeren in C BSc. EE, 1e jaar, 2012-201, e college Arjan van Genderen, Computer Engineering 4-12-2012 Delft University of Technology Challenge the future Hoorcollege Arrays, Pointers en Strings

Nadere informatie

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

recursie Hoofdstuk 5 Studeeraanwijzingen De studielast van deze leereenheid bedraagt circa 6 uur. Terminologie Hoofdstuk 5 Recursion I N T R O D U C T I E Veel methoden die we op een datastructuur aan kunnen roepen, zullen op een recursieve wijze geïmplementeerd worden. Recursie is een techniek waarbij een vraagstuk

Nadere informatie

Datastructuren: stapels, rijen en binaire bomen

Datastructuren: stapels, rijen en binaire bomen Programmeermethoden Datastructuren: stapels, rijen en binaire bomen week 12: 23 27 november 2015 www.liacs.leidenuniv.nl/ kosterswa/pm/ 1 Inleiding In de informatica worden Abstracte DataTypen (ADT s)

Nadere informatie

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

Vierde college complexiteit. 26 februari Beslissingsbomen en selectie Toernooimethode Adversary argument Complexiteit 2019/04 College 4 Vierde college complexiteit 26 februari 2019 Beslissingsbomen en selectie Toernooimethode Adversary argument 1 Complexiteit 2019/04 Zoeken: samengevat Ongeordend lineair

Nadere informatie

Vierde college complexiteit. 14 februari Beslissingsbomen

Vierde college complexiteit. 14 februari Beslissingsbomen College 4 Vierde college complexiteit 14 februari 2017 Restant zoeken Beslissingsbomen 1 Binair zoeken Links := 1; Rechts := n; while Links Rechts do Midden := Links + Rechts 2 ; if X = A[Midden] then

Nadere informatie

Recursie: definitie. De som van de kwadraten van de getallen tussen m en n kan als volgt gedefinieerd worden:

Recursie: definitie. De som van de kwadraten van de getallen tussen m en n kan als volgt gedefinieerd worden: Recursie: definitie Een object wordt recursief genoemd wanneer het partieel bestaat uit of partieel gedefinieerd is in termen van zichzelf. Recursie wordt gebruikt bij wiskundige definities, bijvoorbeeld:

Nadere informatie

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

Recursion. Introductie 37. Leerkern 37. Terugkoppeling 40. Uitwerking van de opgaven 40 Recursion Introductie 37 Leerkern 37 5.1 Foundations of recursion 37 5.2 Recursive analysis 37 5.3 Applications of recursion 38 Terugkoppeling 40 Uitwerking van de opgaven 40 Hoofdstuk 5 Recursion I N

Nadere informatie

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

Programmeermethoden. Recursie. Walter Kosters. week 11: november kosterswa/pm/ Programmeermethoden Recursie Walter Kosters week 11: 20 24 november 2017 www.liacs.leidenuniv.nl/ kosterswa/pm/ 1 Vierde programmeeropgave 1 De Grote getallen programmeren we als volgt: week 1: pointerpracticum,

Nadere informatie

Uitgebreide uitwerking Tentamen Complexiteit, juni 2017

Uitgebreide uitwerking Tentamen Complexiteit, juni 2017 Uitgebreide uitwerking Tentamen Complexiteit, juni 017 Opgave 1. a. Een pad van de wortel naar een blad stelt de serie achtereenvolgende arrayvergelijkingen voor die het algoritme doet op zekere invoer.

Nadere informatie

Tentamen Programmeren in C (EE1400)

Tentamen Programmeren in C (EE1400) TU Delft Tentamen Programmeren in C (EE1400) 5 april 2012, 9.00 12.00 Faculteit EWI - Zet op elk antwoordblad je naam en studienummer. - Beantwoord alle vragen zo nauwkeurig mogelijk. - Wanneer C code

Nadere informatie

Tweede Toets Datastructuren 29 juni 2016, , Educ-Γ.

Tweede Toets Datastructuren 29 juni 2016, , Educ-Γ. Tweede Toets Datastructuren 29 juni 2016, 13.30 15.30, Educ-Γ. Motiveer je antwoorden kort! Zet je mobiel uit. Stel geen vragen over deze toets; als je een vraag niet duidelijk vindt, schrijf dan op hoe

Nadere informatie

Uitwerking tentamen Algoritmiek 9 juni :00 17:00

Uitwerking tentamen Algoritmiek 9 juni :00 17:00 Uitwerking tentamen Algoritmiek 9 juni 2015 14:00 17:00 1. Clobber a. Toestanden: m x n bord met in elk hokje een O, een X of een -. Hierbij is het aantal O gelijk aan het aantal X of er is hooguit één

Nadere informatie

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

public boolean equaldates() post: returns true iff there if the list contains at least two BirthDay objects with the same daynumber Tentamen TI1310 Datastructuren en Algoritmen, 15 april 2011, 9.00-12.00 TU Delft, Faculteit EWI, Basiseenheid Software Engineering Bij het tentamen mag alleen de boeken van Goodrich en Tamassia worden

Nadere informatie

Uitwerking tentamen Algoritmiek 9 juli :00 13:00

Uitwerking tentamen Algoritmiek 9 juli :00 13:00 Uitwerking tentamen Algoritmiek 9 juli 0 0:00 :00. (N,M)-game a. Toestanden: Een geheel getal g, waarvoor geldt g N én wie er aan de beurt is (Tristan of Isolde) b. c. Acties: Het noemen van een geheel

Nadere informatie

Indexen.

Indexen. Indexen joost.vennekens@kuleuven.be Probleem Snel gegevens terugvinden Gegevens moeten netjes geordend zijn Manier waarop hangt af van gebruik Sequentieel Gesorteerde gegevens, die in volgorde overlopen

Nadere informatie

Tweede college algoritmiek. 12 februari Grafen en bomen

Tweede college algoritmiek. 12 februari Grafen en bomen College 2 Tweede college algoritmiek 12 februari 2016 Grafen en bomen 1 Grafen (herhaling) Een graaf G wordt gedefinieerd als een paar (V,E), waarbij V een eindige verzameling is van knopen (vertices)

Nadere informatie

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

Vierde college algoritmiek. 23/24 februari Complexiteit en Brute Force Algoritmiek 2017/Complexiteit Vierde college algoritmiek 23/24 februari 2017 Complexiteit en Brute Force 1 Algoritmiek 2017/Complexiteit Tijdcomplexiteit Complexiteit (= tijdcomplexiteit) van een algoritme:

Nadere informatie

10 Meer over functies

10 Meer over functies 10 Meer over functies In hoofdstuk 5 hebben we functies uitgebreid bestudeerd. In dit hoofdstuk bekijken we drie andere aspecten van functies: recursieve functies dat wil zeggen, functies die zichzelf

Nadere informatie

ALGORITMIEK: antwoorden werkcollege 5

ALGORITMIEK: antwoorden werkcollege 5 ALGORITMIEK: antwoorden werkcollege 5 opgave 1. a. Brute force algoritme, direct afgeleid uit de observatie: loop v.l.n.r. door de tekst; als je een A tegenkomt op plek i (0 i < n 1), loop dan van daaruit

Nadere informatie

Opgaven Zoekbomen Datastructuren, 20 juni 2018, Werkgroep.

Opgaven Zoekbomen Datastructuren, 20 juni 2018, Werkgroep. Opgaven Zoekbomen Datastructuren, 20 juni 2018, Werkgroep. Gebruik deze opgaven, naast die uit het boek, om de stof te oefenen op het werkcollege. Cijfer: Op een toets krijg je meestal zes tot acht opgaven.

Nadere informatie

Datastructuren en algoritmen voor CKI

Datastructuren en algoritmen voor CKI Datastructuren en algoritmen voor CKI Jeroen Bransen 1 11 september 2015 1 met dank aan Hans Bodlaender en Gerard Tel Heaps en heapsort Heap 1 2 3 4 5 6 7 8 9 10 16 14 10 8 7 9 3 2 4 1 16 14 10 8 7 9 3

Nadere informatie

Uitgebreide uitwerking tentamen Algoritmiek Dinsdag 5 juni 2007, uur

Uitgebreide uitwerking tentamen Algoritmiek Dinsdag 5 juni 2007, uur Uitgebreide uitwerking tentamen Algoritmiek Dinsdag juni 00, 0.00.00 uur Opgave. a. Een toestand bestaat hier uit een aantal stapels, met op elk van die stapels een aantal munten (hooguit n per stapel).

Nadere informatie

Derde college complexiteit. 7 februari Zoeken

Derde college complexiteit. 7 februari Zoeken College 3 Derde college complexiteit 7 februari 2017 Recurrente Betrekkingen Zoeken 1 Recurrente betrekkingen -1- Rij van Fibonacci: 0,1,1,2,3,5,8,13,21,... Vanaf het derde element: som van de voorgaande

Nadere informatie

Algoritmiek. 15 februari Grafen en bomen

Algoritmiek. 15 februari Grafen en bomen Algoritmiek 15 februari 2019 Grafen en bomen 1 Grafen (herhaling) Een graaf G wordt gedefinieerd als een paar (V,E), waarbij V een eindige verzameling is van knopen (vertices) en E een verzameling van

Nadere informatie

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

Elfde college algoritmiek. 18 mei Algoritme van Dijkstra, Heap, Heapify & Heapsort Algoritmiek 018/Algoritme van Dijkstra Elfde college algoritmiek 18 mei 018 Algoritme van Dijkstra, Heap, Heapify & Heapsort 1 Algoritmiek 018/Algoritme van Dijkstra Uit college 10: Voorb. -1- A B C D

Nadere informatie

continue in een for, while of do lus herhaalt de lus vroegtijdig. De volgende herhaling wordt onmiddellijk begonnen.

continue in een for, while of do lus herhaalt de lus vroegtijdig. De volgende herhaling wordt onmiddellijk begonnen. Hoofdstuk 3: controlestructuren instructies en blokken Naar elke instructie staat een ; Instructies worden door de haakjes {} in een block samengevat. if else if ( expression) statement1; else statement2;

Nadere informatie

9 Meer over datatypen

9 Meer over datatypen 9 Meer over datatypen We hebben al gezien dat het gebruik van symbolische constanten de leesbaarheid van een programma kan verbeteren. Door een geschikte naam (identifier) voor een constante te definiëren,

Nadere informatie

Datastructuren Uitwerking jan

Datastructuren Uitwerking jan Datastructuren Uitwerking jan 2015 1 1a. Een abstracte datastructuur is een beschrijving van een datastructuur, met de specificatie van wat er opgeslagen wordt (de data en hun structuur) en welke operaties

Nadere informatie

PROS1E1 Gestructureerd programmeren in C Dd/Kf/Bd

PROS1E1 Gestructureerd programmeren in C Dd/Kf/Bd Inhoudsopgave 1 Inleiding... 1 2 Toekenning- en herhalingsopdrachten (for loop)... 2 2.1 De wet van Ohm... 3 2.2 De spaarrekening... 3 2.3 De transformator... 3 3 Keuze- en herhalingsopdrachten (if, switch,

Nadere informatie

Examen Programmeren 2e Bachelor Elektrotechniek en Computerwetenschappen Faculteit Ingenieurswetenschappen Academiejaar juni, 2010

Examen Programmeren 2e Bachelor Elektrotechniek en Computerwetenschappen Faculteit Ingenieurswetenschappen Academiejaar juni, 2010 Examen Programmeren 2e Bachelor Elektrotechniek en Computerwetenschappen Faculteit Ingenieurswetenschappen Academiejaar 2009-2010 16 juni, 2010 **BELANGRIJK** 1. Schrijf je naam onderaan op elk blad. 2.

Nadere informatie

Vijfde college complexiteit. 21 februari Selectie Toernooimethode Adversary argument

Vijfde college complexiteit. 21 februari Selectie Toernooimethode Adversary argument Complexiteit 2017/05 College 5 Vijfde college complexiteit 21 februari 2017 Selectie Toernooimethode Adversary argument 1 Complexiteit 2017/05 Opgave 28 Gegeven twee oplopend gesorteerde even lange rijen

Nadere informatie

2 Recurrente betrekkingen

2 Recurrente betrekkingen WIS2 1 2 Recurrente betrekkingen 2.1 Fibonacci De getallen van Fibonacci Fibonacci (= Leonardo van Pisa), 1202: Bereken het aantal paren konijnen na één jaar, als 1. er na 1 maand 1 paar pasgeboren konijnen

Nadere informatie

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

Datastructuren. Analyse van algoritmen. José Lagerberg. FNWI, UvA. José Lagerberg (FNWI, UvA) Datastructuren 1 / 46 Datastructuren Analyse van algoritmen José Lagerberg FNWI, UvA José Lagerberg (FNWI, UvA) Datastructuren 1 / 46 Datastructuren en Algoritmen Datastructuren, 6 ECTS eerstejaars Bachelor INF Datastructuren,

Nadere informatie

Dynamisch geheugen beheer

Dynamisch geheugen beheer Dynamisch geheugen beheer + Normaal wordt laats in het werkgeheugen gereserveerd tijdens de comilatie aan de hand van de declaraties van de variabelen. + Deze geheugenreservering is statisch: in het bronbestand

Nadere informatie

Opdrachten numerieke methoden, week 1

Opdrachten numerieke methoden, week 1 Opdrachten numerieke methoden, week Opdracht : De potentiaal in een diode. [Bewijs dat ψ = u T arcsinh D 2n i ) ] ) ) D = n p = n i e ψ u T e ψ u ψ T = 2n i sinh u T ) D ψ = u T arcsinh 2n i.2 [Conditiegetal

Nadere informatie

Datastructuren: stapels, rijen en binaire bomen

Datastructuren: stapels, rijen en binaire bomen Programmeermethoden : stapels, rijen en binaire bomen Walter Kosters week 12: 26 30 november 2018 www.liacs.leidenuniv.nl/ kosterswa/pm/ 1 en Vierde programmeeropgave Othello programmeren we als volgt:

Nadere informatie

Onafhankelijke verzamelingen en Gewogen Oplossingen, door Donald E. Knuth, The Art of Computer Programming, Volume 4, Combinatorial Algorithms

Onafhankelijke verzamelingen en Gewogen Oplossingen, door Donald E. Knuth, The Art of Computer Programming, Volume 4, Combinatorial Algorithms Onafhankelijke verzamelingen en Gewogen Oplossingen, door Donald E. Knuth, The Art of Computer Programming, Volume 4, Combinatorial Algorithms Giso Dal (0752975) Pagina s 5 7 1 Deelverzameling Representatie

Nadere informatie

De volgorde van een linked list omkeren

De volgorde van een linked list omkeren De volgorde van een linked list omkeren Inleiding Daniel von Asmuth 21 januari 2015 Hierin presenteren we een algoritme om de volgorde van de knopen in een linked list om te keren dat wordt versneld door

Nadere informatie

Datastructuren en algoritmen voor CKI

Datastructuren en algoritmen voor CKI Datastructuren en algoritmen voor CKI Jeroen Bransen 1 9 oktober 2015 1 met dank aan Hans Bodlaender en Gerard Tel Zoekbomen Binaire boom Bestaat uit knopen Beginknoop is de wortel (root) Elke knoop heeft

Nadere informatie

Examen Datastructuren en Algoritmen II

Examen Datastructuren en Algoritmen II Tweede bachelor Informatica Academiejaar 2014 2015, eerste zittijd Examen Datastructuren en Algoritmen II Naam :.............................................................................. Lees de hele

Nadere informatie

Discrete Structuren. Piter Dykstra Opleidingsinstituut Informatica en Cognitie

Discrete Structuren. Piter Dykstra Opleidingsinstituut Informatica en Cognitie Discrete Structuren Piter Dykstra Opleidingsinstituut Informatica en Cognitie www.math.rug.nl/~piter piter@math.rug.nl 22 februari 2009 INDUCTIE & RECURSIE Paragrafen 4.3-4.6 Discrete Structuren Week 3:

Nadere informatie

3. Structuren in de taal

3. Structuren in de taal 3. Structuren in de taal In dit hoofdstuk behandelen we de belangrijkst econtrolestructuren die in de algoritmiek gebruikt worden. Dit zijn o.a. de opeenvolging, selectie en lussen (herhaling). Vóór we

Nadere informatie

Uitwerking tentamen Analyse van Algoritmen, 29 januari

Uitwerking tentamen Analyse van Algoritmen, 29 januari Uitwerking tentamen Analyse van Algoritmen, 29 januari 2007. (a) De buitenste for-lus kent N = 5 iteraties. Na iedere iteratie ziet de rij getallen er als volgt uit: i rij na i e iteratie 2 5 4 6 2 2 4

Nadere informatie

Datastructuren en Algoritmen

Datastructuren en Algoritmen Datastructuren en Algoritmen Tentamen Vrijdag 6 november 2015 13.30-16.30 Toelichting Bij dit tentamen mag je gebruik maken van een spiekbriefje van maximaal 2 kantjes. Verder mogen er geen hulpmiddelen

Nadere informatie

Opgaven Zoekbomen Datastructuren, 15 juni 2016, Werkgroep.

Opgaven Zoekbomen Datastructuren, 15 juni 2016, Werkgroep. Opgaven Zoekbomen Datastructuren, 15 juni 2016, Werkgroep. Gebruik deze opgaven, naast die uit het boek, om de stof te oefenen op het werkcollege. Cijfer: Op een toets krijg je meestal zes tot acht opgaven.

Nadere informatie

EE1400: Programmeren in C BSc. EE, 1e jaar, , 4e college

EE1400: Programmeren in C BSc. EE, 1e jaar, , 4e college EE1400: Programmeren in C BSc. EE, 1e jaar, 2012-2013, 4e college Arjan van Genderen, Computer Engineering 11-12-2012 Delft University of Technology Challenge the future Mededelingen Voortgangstoets: Woensdagmiddag

Nadere informatie

Combinatorische Algoritmen: Binary Decision Diagrams, Deel III

Combinatorische Algoritmen: Binary Decision Diagrams, Deel III Combinatorische Algoritmen: Binary Decision Diagrams, Deel III Sjoerd van Egmond LIACS, Leiden University, The Netherlands svegmond@liacs.nl 2 juni 2010 Samenvatting Deze notitie beschrijft een nederlandse

Nadere informatie

Doorzoeken van grafen. Algoritmiek

Doorzoeken van grafen. Algoritmiek Doorzoeken van grafen Algoritmiek Vandaag Methoden om door grafen te wandelen Depth First Search Breadth First Search Gerichte Acyclische Grafen en topologische sorteringen 2 Doolhof start eind 3 Depth

Nadere informatie

Tentamen Discrete Wiskunde

Tentamen Discrete Wiskunde Discrete Wiskunde (WB011C) 22 januari 2016 Tentamen Discrete Wiskunde Schrijf op ieder ingeleverd blad duidelijk leesbaar je naam en studentnummer. De opgaven 1 t/m 6 tellen alle even zwaar. Je hoeft slechts

Nadere informatie

Instructies en blokken

Instructies en blokken Herhaling 1 Instructies en blokken Naar elke instructie staat een ; puntkomma Verschillende instructies worden door de accolades in een block samengevat. Een blok is het zelfde als een enkele instructie.

Nadere informatie

Amorized Analysis en Union-Find Algoritmiek

Amorized Analysis en Union-Find Algoritmiek Amorized Analysis en Union-Find Vandaag Amortized analysis Technieken voor tijdsanalyse van algoritmen Union-find datastructuur Datastructuur voor operaties op disjuncte verzamelingen Verschillende oplossingen

Nadere informatie

Oefententamen 2. Tijd: 2 uur. Maximaal aantal punten: 30. Naam: Studentnummer:

Oefententamen 2. Tijd: 2 uur. Maximaal aantal punten: 30. Naam: Studentnummer: Oefententamen 2 C Naam: Studentnummer: Tijd: 2 uur Maximaal aantal punten: 30 Menselijke compiler (10 punten) 0. (1 punt) Stel, je haalt het tentamen als je tenminste een 5.5 gemiddeld hebt gehaald voor

Nadere informatie

Tree traversal. Bomen zijn overal. Ferd van Odenhoven. 15 november 2011

Tree traversal. Bomen zijn overal. Ferd van Odenhoven. 15 november 2011 15 november 2011 Tree traversal Ferd van Odenhoven Fontys Hogeschool voor Techniek en Logistiek Venlo Software Engineering 15 november 2011 ODE/FHTBM Tree traversal 15 november 2011 1/22 1 ODE/FHTBM Tree

Nadere informatie

Divide & Conquer: Verdeel en Heers. Algoritmiek

Divide & Conquer: Verdeel en Heers. Algoritmiek Divide & Conquer: Verdeel en Heers Algoritmiek Algoritmische technieken Trucs; methoden; paradigma s voor het ontwerp van algoritmen Gezien: Dynamisch Programmeren Volgend college: Greedy Vandaag: Divide

Nadere informatie

Opgaven Heaps Datastructuren, 8 juni 2018, Werkgroep.

Opgaven Heaps Datastructuren, 8 juni 2018, Werkgroep. Opgaven Heaps Datastructuren, 8 juni 2018, Werkgroep. Gebruik deze opgaven, naast die uit het boek, om de stof te oefenen op het werkcollege. Cijfer: Op een toets krijg je meestal zes tot acht opgaven.

Nadere informatie

Grafen. Indien de uitgraad van ieder punt 1 is, dan bevat de graaf een cykel. Indien de ingraad van ieder punt 1 is, dan bevat de graaf een cykel.

Grafen. Indien de uitgraad van ieder punt 1 is, dan bevat de graaf een cykel. Indien de ingraad van ieder punt 1 is, dan bevat de graaf een cykel. Grafen Grafen Een graaf bestaat uit een verzameling punten (ook wel knopen, of in het engels vertices genoemd) en een verzameling kanten (edges) of pijlen (arcs), waarbij de kanten en pijlen tussen twee

Nadere informatie

Instructies en blokken

Instructies en blokken Herhaling 1 Instructies en blokken 2 Naar elke instructie staat een ; puntkomma Verschillende instructies worden door de accolades in een block samengevat. Een blok is het zelfde als een enkele instructie.

Nadere informatie

REEKS I. Zaterdag 6 november 2010, 9u

REEKS I. Zaterdag 6 november 2010, 9u TEST INFORMATICA 1STE BACHELOR IN DE INGENIEURSWETENSCHAPPEN - ACADEMIEJAAR 2010-2011 REEKS I Zaterdag 6 november 2010, 9u NAAM :... VRAAG 1: MINSTENS [5 PUNTEN] Schrijf een methode minstens(), met twee

Nadere informatie

Examen Datastructuren en Algoritmen II

Examen Datastructuren en Algoritmen II Tweede bachelor Informatica Academiejaar 2016 2017, eerste zittijd Examen Datastructuren en Algoritmen II Naam :.............................................................................. Lees de hele

Nadere informatie

int main() { int m; m = power(2,3) /* berekent 2^3 en geeft de resultaat naar m terug */ }

int main() { int m; m = power(2,3) /* berekent 2^3 en geeft de resultaat naar m terug */ } 1 Functies ( ) voorbeeld: int power(int base, int n) int i, p; p = 1; for ( i=1, i

Nadere informatie

Divide & Conquer: Verdeel en Heers. Algoritmiek

Divide & Conquer: Verdeel en Heers. Algoritmiek Divide & Conquer: Verdeel en Heers Algoritmiek Algoritmische technieken Trucs; methoden; paradigma s voor het ontwerp van algoritmen Gezien: Dynamisch Programmeren Hierna: Greedy Vandaag: Divide & Conquer

Nadere informatie

Uitgebreide uitwerking Tentamen Complexiteit, juni 2018

Uitgebreide uitwerking Tentamen Complexiteit, juni 2018 Uitgebreide uitwerking Tentamen Complexiteit, juni 018 Opgave 1. a. Een pad van de wortel naar een blad stelt de serie achtereenvolgende arrayvergelijkingen voor die het algoritme doet op zekere invoer.

Nadere informatie

Twaalfde college complexiteit. 11 mei 2012. Overzicht, MST

Twaalfde college complexiteit. 11 mei 2012. Overzicht, MST College 12 Twaalfde college complexiteit 11 mei 2012 Overzicht, MST 1 Agenda voor vandaag Minimum Opspannende Boom (minimum spanning tree) als voorbeeld van greedy algoritmen Overzicht: wat voor technieken

Nadere informatie

17 Operaties op bits. 17.1 Bitoperatoren en bitexpressies

17 Operaties op bits. 17.1 Bitoperatoren en bitexpressies 17 Operaties op bits In hoofdstuk 1 is gezegd dat C oorspronkelijk bedoeld was als systeemprogrammeertaal om het besturingssysteem UNIX te implementeren. Bij dit soort toepassingen komt het voor dat afzonderlijke

Nadere informatie

Uitgebreide uitwerking tentamen Algoritmiek Dinsdag 2 juni 2009, uur

Uitgebreide uitwerking tentamen Algoritmiek Dinsdag 2 juni 2009, uur Uitgebreide uitwerking tentamen Algoritmiek Dinsdag 2 juni 2009, 10.00 13.00 uur Opgave 1. a. Een toestand wordt bepaald door: het aantal lucifers op tafel, het aantal lucifers in het bezit van Romeo,

Nadere informatie

Getallensystemen, verzamelingen en relaties

Getallensystemen, verzamelingen en relaties Hoofdstuk 1 Getallensystemen, verzamelingen en relaties 1.1 Getallensystemen 1.1.1 De natuurlijke getallen N = {0, 1, 2, 3,...} N 0 = {1, 2, 3,...} 1.1.2 De gehele getallen Z = {..., 4, 3, 2, 1, 0, 1,

Nadere informatie

Tentamen Programmeren in C (EE1400)

Tentamen Programmeren in C (EE1400) TU Delft Faculteit EWI Tentamen Programmeren in C (EE1400) 28 jan 2011, 9.00 12.00 - Zet op elk antwoordblad je naam en studienummer. - Beantwoord alle vragen zo nauwkeurig mogelijk. - Wanneer C code gevraagd

Nadere informatie

Tweede Toets Datastructuren 28 juni 2017, , Educ-β.

Tweede Toets Datastructuren 28 juni 2017, , Educ-β. Tweede Toets Datastructuren 28 juni 2017, 13.30 15.30, Educ-β. Motiveer je antwoorden kort! Stel geen vragen over deze toets; als je een vraag niet duidelijk vindt, schrijf dan op hoe je de vraag interpreteert

Nadere informatie

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

Derde college algoritmiek. 23 februari Complexiteit Toestand-actie-ruimte Algoritmiek 2018/Complexiteit Derde college algoritmiek 2 februari 2018 Complexiteit Toestand-actie-ruimte 1 Algoritmiek 2018/Complexiteit Tijdcomplexiteit Complexiteit (= tijdcomplexiteit) van een algoritme:

Nadere informatie

(iii) Enkel deze bundel afgeven; geen bladen toevoegen, deze worden toch niet gelezen!

(iii) Enkel deze bundel afgeven; geen bladen toevoegen, deze worden toch niet gelezen! Examen Wiskundige Basistechniek, reeks A 12 oktober 2013, 13:30 uur Naam en Voornaam: Lees eerst dit: (i) Naam en voornaam hierboven invullen. (ii) Nietje niet losmaken. (iii) Enkel deze bundel afgeven;

Nadere informatie

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

Twaalfde college algoritmiek. 13 mei Branch & Bound Heap, Heapsort & Heapify Algoritmiek 2016/Branch & Bound Twaalfde college algoritmiek 13 mei 2016 Branch & Bound Heap, Heapsort & Heapify 1 Algoritmiek 2016/Branch & Bound TSP met Branch & Bound Mogelijke ondergrenzen voor de

Nadere informatie

Java Programma structuur

Java Programma structuur Java Programma structuur public class Bla // div. statements public static void main(string argv[]) // meer spul Voortgezet Prog. voor KI, week 4:11 november 2002 1 Lijsten Voorbeelden 2, 3, 5, 7, 13 Jan,

Nadere informatie

9. Strategieën en oplossingsmethoden

9. Strategieën en oplossingsmethoden 9. Strategieën en oplossingsmethoden In dit hoofdstuk wordt nog even terug gekeken naar alle voorgaande hoofdstukken. We herhalen globaal de structuren en geven enkele richtlijnen voor het ontwerpen van

Nadere informatie

Examen Datastructuren en Algoritmen II

Examen Datastructuren en Algoritmen II Tweede bachelor Informatica Academiejaar 2012 2013, tweede zittijd Examen Datastructuren en Algoritmen II Naam :.............................................................................. Lees de hele

Nadere informatie

Als een PSD selecties bevat, deelt de lijn van het programma zich op met de verschillende antwoorden op het vraagstuk.

Als een PSD selecties bevat, deelt de lijn van het programma zich op met de verschillende antwoorden op het vraagstuk. HOOFDSTUK 3 3.1 Stapsgewijs programmeren In de vorige hoofdstukken zijn programmeertalen beschreven die imperatief zijn. is het stapsgewijs in code omschrijven wat een programma moet doen, net als een

Nadere informatie

Inleiding Programmeren 2

Inleiding Programmeren 2 Inleiding Programmeren 2 Gertjan van Noord November 26, 2018 Stof week 3 nogmaals Zelle hoofdstuk 8 en recursie Brookshear hoofdstuk 5: Algoritmes Datastructuren: tuples Een geheel andere manier om te

Nadere informatie

Modelleren en Programmeren

Modelleren en Programmeren Modelleren en Programmeren Jeroen Bransen 13 december 2013 Terugblik Fibonacci public class Fibonacci { public static void main(string[] args) { // Print het vijfde Fibonaccigetal System.out.println(fib(5));

Nadere informatie

De symmetrische min-max heap

De symmetrische min-max heap De symmetrische min-max heap Tweede programmeeropdracht Datastructuren, najaar 2006 De symmetrische min-max heap (SMM heap) is een datastructuur waarin getallen (of andere elementen met een lineaire ordening)

Nadere informatie

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

4EE11 Project Programmeren voor W. College 3, 2008 2009, Blok D Tom Verhoeff, Software Engineering & Technology, TU/e 4EE11 Project Programmeren voor W College 3, 2008 2009, Blok D Tom Verhoeff, Software Engineering & Technology, TU/e 1 Onderwerpen Grotere programma s ontwerpen/maken Datastructuren en algoritmes 2 Evolutie,

Nadere informatie

Negende college algoritmiek. 15 april Dynamisch Programmeren

Negende college algoritmiek. 15 april Dynamisch Programmeren Negende college algoritmiek 15 april 2016 Dynamisch Programmeren 1 algemeen Uit college 8: DP: - nuttig bij problemen met overlappende deelproblemen - druk een oplossing van het probleem uit in oplossingen

Nadere informatie

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

Eerste Toets Datastructuren 22 mei 2019, , Educ-β en Megaron. Eerste Toets Datastructuren 22 mei 209, 3.30 5.30, Educ-β en Megaron. Motiveer je antwoorden kort! Stel geen vragen over deze toets; als je een vraag niet duidelijk vindt, schrijf dan op hoe je de vraag

Nadere informatie