Opgaven Stacks, Lijsten, Queues Datastructuren, Werkgroep, 2 juni 2017.

Vergelijkbare documenten
Opgaven Abstracte Datastructuren Datastructuren, Werkgroep, 31 mei 2017.

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

Lineaire data structuren. Doorlopen van een lijst

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

Tweede Toets Datastructuren 27 juni 2018, , Olympos Hal 2.

Stacks and queues. Hoofdstuk 6

Tweede deeltoets Algoritmiek 14 april 2015, , Educ-Γ.

Achtste college algoritmiek. 8 april Dynamisch Programmeren

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

Opgaven Hash Tabellen Datastructuren, 15 juni 2018, Werkgroep.

Derde college complexiteit. 7 februari Zoeken

Divide & Conquer: Verdeel en Heers vervolg. Algoritmiek

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

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

Stacks and queues. Introductie 45. Leerkern 45. Terugkoppeling 49. Uitwerking van de opgaven 49

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

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

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

Minimum Opspannende Bomen. Algoritmiek

Examen Datastructuren en Algoritmen II

Uitwerking tentamen Algoritmiek 9 juli :00 13:00

Programmeermethoden NA. Week 6: Lijsten

Zevende college algoritmiek. 24 maart Verdeel en Heers

Vierde college complexiteit. 14 februari Beslissingsbomen

Zevende college algoritmiek. 23/24 maart Verdeel en Heers

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

Zevende college Algoritmiek. 6 april Verdeel en Heers

7 Omzetten van Recursieve naar Iteratieve Algoritmen

Combinatoriek groep 1 & 2: Recursie

Tiende college algoritmiek. 26 april Gretige algoritmen

Opgaven Registers Concurrency, 29 nov 2018, Werkgroep.

Vierde college complexiteit. 16 februari Beslissingsbomen en selectie

Tiende college algoritmiek. 14 april Gretige algoritmen

Algoritmiek. 2 februari Introductie

Vierde college algoritmiek. 2 maart Toestand-actie-ruimte Exhaustive Search

10 Meer over functies

Datastructuren: stapels, rijen en binaire bomen

Datastructuren en Algoritmen

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

Examen Datastructuren en Algoritmen II

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

ALGORITMIEK: antwoorden werkcollege 5

ALGORITMIEK: antwoorden werkcollege 5

Examen Datastructuren en Algoritmen II

Vijfde college algoritmiek. 2/3 maart Exhaustive search

Examen Datastructuren en Algoritmen II

Amorized Analysis en Union-Find Algoritmiek

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

Datastructuren en algoritmen voor CKI

Programmeermethoden NA

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

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

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

Datastructuren Uitwerking jan

Datastructuren en algoritmen voor CKI

Derde college algoritmiek. 18 februari Toestand-actie-ruimte

Greedy algoritmes. Algoritmiek

Eerste deeltoets Algoritmiek 4 maart 2015, , Educ-β.

Uitwerking tentamen Analyse van Algoritmen, 29 januari

Minimum Spanning Tree

1 Recurrente betrekkingen

Opgaven Eigenschappen van Getallen Security, 2018, Werkgroep.

Kortste Paden. Algoritmiek

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

Examen Datastructuren en Algoritmen II

ALGORITMIEK: antwoorden werkcollege 5

Tiende college algoritmiek. 2 mei Gretige algoritmen, Dijkstra

Inleiding Programmeren 2

Divide & Conquer: Verdeel en Heers. Algoritmiek

Derde college algoritmiek. 16/17 februari Toestand-actie-ruimte

Opgaven Recursie: Analyse en Master Theorem Datastructuren, 6 juni 2018, Werkgroep.

Tweede college complexiteit. 12 februari Wiskundige achtergrond

Opgaven Fibonacci-getallen Datastructuren, 23 juni 2017, Werkgroep.

Tweede Toets Datastructuren 26 juni 2019, , Educ-β.

Opgaven Heaps Datastructuren, 8 juni 2018, Werkgroep.

De Leidsche Flesch Studievereniging voor Natuurkunde, Sterrenkunde, Wiskunde en Informatica sinds DLF Pointerworkshop

Vijfde college complexiteit. 21 februari Selectie Toernooimethode Adversary argument

Negende college algoritmiek. 15 april Dynamisch Programmeren

Arrays in LOGO. In LOGO heeft de eerste item van de array standaard index 1.

Opgaven Analyse van Algoritmen 10 mei 2019, Datastructuren, Werkgroep.

Divide & Conquer: Verdeel en Heers. Algoritmiek

Programmeren A. Genetisch Programma voor het Partitie Probleem. begeleiding:

Inleiding Programmeren 2

Discrete Structuren. Piter Dykstra Opleidingsinstituut Informatica en Cognitie

Uitgebreide uitwerking Tentamen Complexiteit, juni 2017

Examen Datastructuren en Algoritmen II

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

Opgaven Zoekbomen Datastructuren, 20 juni 2018, Werkgroep.

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

Tweede Huiswerk Security 26 of 28 oktober, 11.00, Nabespreken op Werkcollege.

Combinatoriek groep 1

Derde college algoritmiek. 23 februari Toestand-actie-ruimte

Opgaven Zoekbomen Datastructuren, 15 juni 2016, Werkgroep.

Combinatoriek groep 1

Combinatoriek groep 2

Uitwerking tentamen Algoritmiek 9 juni :00 17:00

Datastructuren Uitwerking jan

Twaalfde college complexiteit. 11 mei Overzicht, MST

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

Tweede college algoritmiek. 12 februari Grafen en bomen

Transcriptie:

Opgaven Stacks, Lijsten, Queues Datastructuren, Werkgroep, 2 juni 2017. 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. 1. De MinStack: Een MinStack kent, net als de gewone Stack, een Push(x) en Pop operatie. Daarnaast is er een operatie MinKey die de kleinste waarde in de MinStack oplevert (maar niet verwijdert). Geef een implementatie van MinStack die deze drie genoemde operaties in O(1) tijd uitvoert. Oplossing: Je kunt zowel de statische als de dynamische implementatie gemakkelijk uitbreiden. Voor de dynamische: Maak Nodes met daarin de gebruikelijke Key en Prev, en daarnaast een veld Mini, voorstellende de kleinste waarde onder deze en oudere keys. Bij het Pushen moet je de waarde van Mini invullen als min(key, Prev.Mini). De MinKey query geeft antwoord top.mini. 2. Twee Stacks: Boek Cormen, Vraag 10.1-2. Oplossing: Zet de ene stack vooraan in de array en de andere achteraan. Zeg de stacks heten L en R en je weet al dat er samen nooit meer dan n dingen op staan. Maak een Array A van n lang en initialiseer Ltop=0; Rtop=n-1;. De Push(x) voor L is A[Ltop++]=x; en de Pop voor L is return [A--Ltop];. De Push(x) voor R is A[Rtop--]=x;. 3. De SomQueue: Een SomQueue kent, net als de gewone Queue, een Enq(x) en Deq operatie. Daarnaast is er een operatie SumKey die de som van alle aanwezige waarden in de MinQueue oplevert. Geef een implementatie van MinQueue die deze drie genoemde operaties in O(1) tijd uitvoert. Oplossing: Je kunt, bij elke implementatie van een Queue, de som van de keys gemakkelijk apart bijhouden. De MinQueue bestaat dus uit een Queue Q en een int total. De Enq(x) is dan Q.Enq(x); total+=x;.

4. Queue met Twee Stacks: Boek Cormen, Vraag 10.1-6. Oplossing: Gebruik Stack A als binnenkomende stack en B als uitgaande stack. Alle elementen in A zijn nieuwer dan alle elementen in B, in A staan de nieuwste elementen bovenin en in B staan de oudste elementen bovenin. Een enq(x) wordt een push(x) op A, een deq wordt een pop van B. Alleen als je wilt dequeuen en B is leeg, stapel je eerst alle elementen van A over naar B (hierbij wordt de volgorde natuurlijk omgekeerd, de nieuwere elementen komen nu onderop). De tijd is O(1) als er niet overgestapeld wordt. Zo nu en dan heb je een dure dequeue, namelijk als er wel wordt omgestapeld. Omdat elk element hoogstens 1 keer wordt omgestapeld, nadat het is ge-enqueued, kost het omstapelen gemiddeld O(1) over alle enqueues. 5. De MinQueue: Een MinQueue kent, net als de gewone Queue, een Enq(x) en Deq operatie. Daarnaast is er een operatie MinKey die de kleinste waarde in de MinQueue oplevert (maar niet verwijdert). Geef een implementatie van MinQueue die deze drie genoemde operaties in O(1) tijd uitvoert. Oplossing: Gebruik de implementatie van Queue s met twee Stacks, en ga uit van het bestaan van een MinStack. De MQ.MinKey wordt berekend als min(sin.minkey, Sout.MinKey). 6. De PeepQueue: De PeepQueue kent, net als de gewone Queue, operaties Enqueue(x) en Dequeue, maar daarnaast (in analogie met de Top van een Stack) een methode Peep die de voorste waarde in de Queue oplevert, maar niet verwijdert. Laat zien hoe je een gegeven Queue kunt uitbreiden naar een peepqueue, waarbij alle operaties O(1) tijd blijven. Oplossing: Truukje is hier, om het voorste element in de PeepQueue apart te houden van de Queue. Dus je peepqueue bestaat uit elementen in een Queue, plus een extra element front. Enqueue gaat gewoon achterin de Queue; Peep is return front zonder iets te veranderen, Dequeue is front opleveren en vervangen door een Dequeue uit de Queue. Gevallen waar de PeepQueue 0 of 1 element bevat even apart afhandelen. Om aan een Stack de Top operatie toe te voegen, kun je een element Poppen, bekijken en terugpushen, maar zo kan het voor een Queue niet (in constante tijd). 7. Duur van Hanoi: Hoeveel zetten zijn nodig in de Torens van Hanoi met n schijven? Oplossing: De reeks bestaat uit twee subreeksen vvoor n 1 schijven, plus een zet. Dit geeft een recursie H(n) = 2H(n 1) + 1, met randvoorwaarde H(1) = 1 (of H(0) = 0). De oplossing is H(n) = 2 n 1. Er is een legende dat monnikken bezig zijn een stapel van 64 te verplaatsen, en dat de wereld vergaat als ze klaar zijn. Gelukkig dus maar dat de lengte van de reeks exponentieel is!

8. Hanoi met handicap: In de originele Hanoi puzzle kun je een schijf willekeurig verplaatsen. Veronderstel nu, dat de drie pinnen A, B en C op een rij staan, dus met B in het midden, en dat een verplaatsing rechtstreeks van A naar C hierdoor niet mogelijk is. (a) Bedenk hoe je een stapel van n schijven kunt verplaatsen van A naar C. (b) Hoeveel stappen zijn nodig? (c) Bewijs, dat je tijdens dit proces, elke legale configuratie van schijven tegenkomt. Oplossing: (a) Kijk weer naar de grootste van de n schijven. Er moet een stap X zijn waarin die van A naar B gaat, en een stap Y waarin die van B naar C gaat. Op het moment van stap X moeten alle kleinere schijven op C staan, en op het moment van stap T moeten al die kleinere schijven op A staan. De reeks HH(A, C, n) bestaat dus uit HH(A, C, n 1), een verschuiving AB, HH(C, A, n 1), een verschuiving BC, en HH(A, C, n 1). (b) Voor de lengte van deze reeks geldt L(n) = 2 + 3L(n 1). Door een klein aantal waarden uit te schrijven, kun je op het idee komen dat de oplossing wel eens L(n) = 3 n 1 zou kunnen zijn. Met inductie kun je dat ook bewijzen. (c) Omdat je 3 n 1 stappen doet, zie je 3 n achtereenvolgende configuraties. Als hier een dubbele in zou zitten, dan was een kortere reeks mogelijk, en hoewel ik dat niet helemaal bewezen heb, heb ik toch het idee dat de geschetste oplossing optimaal is. We krijgen dus 3 n verschillende configuraties te zien. Omdat per pin de schijven altijd van groot naar klein liggen, wordt elke configuratie volledig bepaald door waar elke schijf ligt. Elk van de n schijven kan op 3 posities liggen, dus er bestaan 3 n mogelijke configuraties.

9. Stack met Twee Queues: Boek Cormen, Vraag 10.1-7. Oplossing: Een Stack maken uit twee Queues kan volgens mij niet beter dan in lineaire tijd worst case. Als je iets in een queue hebt gestopt, komt dat er pas na lineair veel operaties weer uit, terwijl je het bij een stack in de volgende pop weer nodig hebt. Die ene pop zal dus lineair veel dequeues moeten doen. Je kunt misschien enkele elementen buiten de queues bewaren om een pop dirct na een push snel te kunnen beantwoorden. Maar het lijkt me tegen de geest van de opdracht om meer dan een constant aantal keys, zeg d, apart te houden. Als je dan d keer pusht gaat toch een van je recente keys een queue in, en kun je er niet snel weer bij. Maar geamortiseerd kan het wel beter namelijk in gemiddeld O( n) tijd per stack operatie. Gebruik een OnderQueue voor het oudste deel van je elementen (de oudste vooraan) en een BovenQueue voor het nieuwst toegevoegde gedeelte (de allernieuwste achteraan en de bijna nieuwe vooraan). Voor een Push(x) voeg je x toe in de BovenQueue met Boven.Enqueue(x). Voor een Pop moet je de hele BovenQueue ronddraaien, dus alles dequeuen en weer enqueuen behalve de laatste want die lever je op. De tijd voor een Pop is dus lineair in de omvang van de BovenQueue. Als de BovenQueue leeg is of te groot wordt, is het tijd voor een uitwisseling met de Onder- Queue. Bij een te grote BovenQueue draai je ze allemaal rond, waarbij een aantal van de voorkant weer achteraan erin worden gestopt, maar de latere (dus oudere) aan de Onder- Queue worden toegevoegd. De BovenQueue is nu kleiner geworden in tijd evenredig met zijn oude omvang. Als de BovenQueue leeg is gaan we de hele OnderQueue doordraaien, waarbij we het eerste gedeelte (dat het oudst is) weer terugzetten en het laatste gedeelte (dat de nieuwere keys bevat) zetten we in de BovenQueue. Hierdoor wordt de BovenQueue weer aangevuld, maar dit is wel de duurste operatie want alle keys komen langs dus dit is Θ(n) tijd. De kunst is nu heel simpel om de omvang van de BovenQueue te bepalen op ongeveer Θ( n) keys, en ook met een zo grote bandbreedte, dus bv 1 tot 3 maal n. De operaties die alleen de BovenQueue doordraaien kosten nu sowieso maar Θ( n) tijd. Het dure doordraaien van de OnderQueue komt maar eens per Ω( n) operaties voor dus komt op O( n) gemiddeld. Ik vind dit wel een leuke opgave, maar qua moeilijkheid is hij waarschijnlijk meer iets voor het vak Algoritmiek. Zou het ook met drie queues kunnen in O(n 1/3 ) of met vier in O( n)?

10. A2B Recursief: Renske heeft een veel simpeler idee om A2B op te lossen. Immers, je kunt vanuit a, b bereiken, als b = a, of b is te bereiken vanuit a+1 (na een Inc) of 2a (na een Dub). Dus: Mogelijk(A,B) = (A==B) OF Mogelijk (A+1,B) OF Mogelijk(2A,B). En voor het minimale aantal stappen geldt: Stap(A,B) = IF (A==B) 0 ELSE Min(Stap(A+1,B), Stap(2A,B)). (a) Implementeer Renske s idee met een recursief algoritme. (b) Voor welke invoeren werkt het sneller en voor welke trager? (c) Helpt het om de clausules andersom in je programma op te nemen? Oplossing: 11. De MinStack: Een MinStack kent naast de standaard Stack-operaties, een operatie MinKey die de kleinste waarde in de MinStack oplevert (maar niet verwijdert). (a) Wat zijn de standaard operaties om data toe te voegen aan en te verwijderen van een gewone Stack en in hoeveel tijd worden ze uitgevoerd? (b) Geef een implementatie (drie methoden) van MinStack die deze operaties en de MinKey in O(1) tijd uitvoert. Oplossing: (a) Toevoegen doe je met Push(x) en verwijderen met Pop(). (b) Je kunt zowel de statische als de dynamische implementatie gemakkelijk uitbreiden. Voor de statische neem je twee arrays, k en m, waarbij k[i] de i de key bevat en m[i] het minimum van de eerste i+1 keys. Voor de dynamische: Maak Nodes met daarin de gebruikelijke Key en Prev, en daarnaast een veld Mink, voorstellende de kleinste waarde onder deze en oudere keys. Bij het Pushen moet je de waarde van Mink invullen als min(key, Prev.Mink). De Push(x) is dan top = new Node(x, Min(x, top.mink), top). De Pop doet r = top.key; top = top.next; return r;. De MinKey query geeft antwoord top.mink. Tot 3pt, eentje voor (a) en 2 voor (b). Codes: M = Implementatie die alleen de bestaande uitbreidt. S = Alleen de Standaardoperaties (Push en Pop) werken, 1pt. 12. A2B met Kwadraat: Download het PILletje A2BFS. (a) Extra stap: Stel dat je ook in een stap mag kwadrateren. Breid het programma uit om een kortste reeks uit te rekenen. Het mooist is als deze extra mogelijkheid aan en uit te schakelen is (net als de Mineen). (b) Beprijsde A2B: Neem aan dat de verschillende stappen een verschillende prijs hebben. Bv I of M kost 1, D kost 2 en K kost 3. Of nog mooier: maak een commando c i m d k dat de vier kosten inleest. Pas je programma aan om de goedkoopste A-B reeks te vinden. (c) Queue geheugengebruik: Breidt het programma uit om bij te houden hoeveel states er maximaal tegelijk in de Queue zitten. Oplossing: (a) Even wat programmeerwerk om te kijken of je het echt een beetje snapt. (b) Voor een gewogen variant van het probleem heb je Dijkstra nodig! (c) Vergelijk deze maximale Queue-lengte bij BFS eens met de maximale Stack-hoogte bij Hanoi (of QuickSort) en schrik!

13. QuickSort Non-Recursief: Gebruik een Stack om een niet-recursieve implementatie van QuickSort te maken. Oplossing: 14. Torens van Hanoi: Download en bekijk de PIL StackHanoi. (a) Voor de reeks met n schijven, wat is de maximale hoogte die de Stack bereikt? (b) Hoeveel Pops vinden er plaats? (c) Breid het programma zo uit, dat na elke stap ook wordt afgedrukt, hoeveel schijven er daarna op elke pin liggen. Oplossing: Je kunt hier natuurlijk vreselijk hard over gaan nadenken, maar je kunt ook je programma met een paar assignments uitbreiden om die maxhoogte bij te houden. Dan zie je al snel dat de maxhoogte 2n 1 is en het aantal items exponentieel. Het geheugengebruik is dus significant kleiner dan het totale aantal dingen dat in de Stack wordt opgeslagen. 15. BFS en Caveman: Download het PILletje A2BFS. De enige plaats waar de structuur van het probleem wordt gebruikt is de berekening van de List<int> Suc met opvolgers (successors) van getal u. Bekijk het puzzeltje Icecube Caveman in GooglePlay of AppStore. Je kunt een positie van Caveman coderen in een integer, en uitrekenen welke andere posities (integers) je vanuit een positie u kunt bereiken. Dwz. door drie regels in A2BFS te vervangen door andere (en waarschijnlijk iets meer) regels, krijg je een Icecube Caveman solver. Succes! Oplossing: Gebruik een paar bits (bv 8 voor breedte/hoogte tot 256) voor de x en y positie, en twee bits voor de orientatie van Caveman. De hogere levels van Icecube kennen ook toverschotsen. Zolang dat er niet al te veel zijn, kun je hun stand meecoderen met een paar bits in de toestandsinteger. Het bouwen van deze solver is een praktikumopdracht van Algoritmiek geweest. 16. BFS en RushHour: Download het PILletje A2BFS. De enige plaats waar de structuur van het probleem wordt gebruikt is de berekening van de List<int> Suc met opvolgers (successors) van getal u. Bekijk het puzzeltje Rush Hour in GooglePlay of AppStore. Je kunt een bordstand coderen in een rijtje integers, en uitrekenen welke andere posities (rijtjes) je vanuit een positie u kunt bereiken. Dwz. door een handvol regels in A2BFS te vervangen door andere (en waarschijnlijk iets meer) regels, krijg je een Rush Hour solver. Succes! Oplossing: Het bouwen van deze solver is een praktikumopdracht van Concurrency geweest.