Programmeeropdracht 2 (backtracking)

Download Report

Transcript Programmeeropdracht 2 (backtracking)

Tweede programmeeropgave — Backtracking
Algoritmiek voorjaar 2014, Universiteit Leiden
We willen graag weten op hoeveel manieren een m bij n schaakbord bedekt kan worden met
langwerpige stenen die precies een horizontale of verticale serie van s aaneengesloten vakjes
bedekken. Als s geen deler van m ∗ n is, kan het uiteraard niet. Als s = 1 kan het op precies
´e´en manier. Als bijvoorbeeld m = 3, n = 9 en s = 3, kan het op 19 manieren. Voor m = n = 8
(het gebruikelijke schaakbord) en s = 2 (de gebruikelijke dominostenen) zijn er maar liefst
12.988.816 mogelijke standen.
We kunnen ook het aantal standen tellen waarbij precies een van tevoren door de gebruiker
aangegeven aantal stenen horizontaal (en de overige dus verticaal) komt te liggen. Zo zijn er
voor m = 3, n = 9 en s = 3, en precies 3 horizontale stukken, exact 7 mogelijkheden.
Een derde variant is om te kijken naar het aantal zogenaamde “rotatie-invariante” standen.
Dit zijn standen die niet veranderen bij een rotatie over π/2 (= 90 ◦ ) rond het midden van het
bord. Deze kunnen overigens alleen maar bestaan als m = n. Voorbeeld: voor m = n = 4 en
s = 2 zijn er in totaal 36 gewone standen, maar slechts 2 rotatie-invariante.
Om dit probleem (voor genoemde drie varianten) op te lossen moet gebruik worden gemaakt
van backtracking. We leggen de stenen op een systematische manier een voor een op het bord
neer, bijvoorbeeld van boven naar beneden. Zoek het ‘eerste’ lege vakje, dat wil zeggen het lege
vakje dat in een zo hoog mogelijke rij (dus met een zo laag mogelijke rij-index) in het array zit,
en binnen zo’n rij zover mogelijk naar links. Leg hier, beginnend bij het betreffende vakje, op
maximaal twee manieren een steen in: naar rechts en naar beneden (als dat kan tenminste), en
ga recursief verder. Bij het opbouwen van een rotatie-invariante stand kan bij het genereren
steeds wanneer een steen wordt neergezet, meteen een drietal geroteerde stenen —die elkaar
niet mogen overlappen!— worden geplaatst.
Zoals gebruikelijk bestaat deze opdracht uit twee delen, een C++-programma en een verslag.
1. Het C++-programma.
• Het programma vraagt aan de gebruiker om m, n en s; vervolgens kan de gebruiker
uit drie opties kiezen:
1. alle gewone standen, 2. alle standen met een door de gebruiker te kiezen aantal
horizontale stenen, 3. alle rotatie-invariante standen.
• Op het beeldscherm moet in elk geval het aantal berekende standen worden afgedrukt.
• Neem aan dat m en n beide niet al te groot zijn (gebruik een constante om de
maximale waarde aan te geven).
• Voor het invoeren van n, m en s en (bij optie 2.) het aantal horizontaal te leggen
stenen door de gebruiker mag gewoon cin worden gebruikt (je mag aannemen dat
er een geheel getal wordt ingevoerd). Let er wel op dat de ingevoerde waarden het
maximum niet overschrijden.
1
• Gebruik een verstandige klasse-structuur met een klasse schaakbord, waarin in elk
geval drie memberfuncties die de drie verschillende varianten (‘gewoon’, ‘gewoon met
aantal horizontaal/verticaal’,‘rotatie-invariant’) verzorgen.
• Het makkelijkst is het om recursie te gebruiken, maar je mag je backtracking-functies
ook zonder recursie implementeren.
• Boven elke functie moet een commmentaarblokje komen met daarin een (zeer) korte
beschrijving van wat de functie doet. Noem daarin ook de gebruikte parameters:
geef hun betekenis en geef aan hoe ze eventueel veranderd worden door de functie.
Geef bij memberfuncties ook aan wat deze met de membervariabelen van het object
doen. Let verder op de layout (consequent inspringen) en op het overige commentaar
bij de programmacode. Schrijf duidelijke, begrijpelijke code en voeg hier en daar
commentaar toe om je methode toe te lichten. Let erop dat het commentaar zinvol
is en kort.
• Het programma moet (ook) onder Linux werken.
2. Het verslag.
• Het verslag moet getypt zijn in LATEX, en moet uiteraard een introductie bevatten
en de probleemstelling. Verder moet voor het rotatie-invariante geval duidelijk de
gebruikte methode worden uitgelegd.
• Neem in het verslag ook een hoofdstukje op met resultaten. Dit kan in de vorm van
tabellen die voor verschillende waarden van de parameters m, n en s de aantallen
gevonden standen bevatten voor de drie varianten. Het spreekt vanzelf dat daar
ook enige verbindende tekst bij hoort; dus niet alleen tabellen zonder enig verder
commentaar.
• Verder moeten voor de situatie waarin m = s en/of n = s recurrente betrekkingen
worden gegeven (met uitleg) betreffende de aantallen mogelijkheden voor het ‘gewone’ geval. Probeer een of meer gesloten formules te geven, bijvoorbeeld voor de
gevallen m = 2s, n = s en m = 3s, n = s, etcetera.
Let op: voor studenten die de minor Computers & Computing doen is dit onderdeel
niet verplicht, maar telt als bonus (van 0,5 punt).
Voor eventuele aanvullingen of tips bij de programmeeropdracht of andere informatie, zie:
http://www.liacs.nl/~graaf/ALGO/. Hier komen t.z.t. ook de behaalde cijfers te staan.
Uiterste inleverdatum: maandag 14 april 2014, uiterlijk 23:59 uur.
Voor elke week te laat inleveren gaat er een punt van het cijfer af. Het programma per e-mail
sturen naar: [email protected]. Zorg dat het onderwerp van je mail begint met
“[ALGO]”. Dat scheelt de docent een hoop gezoek. Listing en verslag moeten op papier worden
ingeleverd en in de daartoe bestemde doos met opschrift Algoritmiek in de postkamer van Informatica (kamer 156) worden gedeponeerd. Vermeld overal duidelijk de namen van de makers.
Normering:
verslag 2; commentaar en layout 1,5; modulaire opbouw en OOP 1,5; werking 5
2