29.08.2013 Views

TENTAMEN

TENTAMEN

TENTAMEN

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

Institutionen för Kommunikation och Information<br />

Kurs:<br />

Delkurs:<br />

Kurskod:<br />

Datum:<br />

Ansvarig lärare:<br />

Berörda lärare<br />

Hjälpmedel/<br />

Bilagor:<br />

Övrigt:<br />

Anvisningar<br />

<strong>TENTAMEN</strong><br />

Algoritmer och Datastrukturer<br />

DA114G<br />

2010-01-14<br />

Gunnar Mathiason<br />

Högskolepoäng: 7.5 hp<br />

Ta nytt blad för varje lärare (endast för lärare på IVN)<br />

Ta nytt blad för varje ny fråga<br />

Skriv endast på en sida av papper.<br />

Använd inte röd penna.<br />

Skriv namn och personnummer på samtliga inlämnade blad.<br />

Numrera lösbladen löpande.<br />

Markera med kryss på omslaget vilka uppgifter som är lösta.<br />

Skrivtid: 14:30-19:30<br />

Poänggränser Examination sker utfrån kursmålen. En fråga på varje mål kan ge max 10 p.<br />

För godkänt krävs minst 5 p på alla frågor utom en.<br />

För betyg 4 krävs minst 7 p på alla frågor utom en.<br />

För betyg 5 krävs minst 9 p på alla frågor utom en.<br />

Skrivningsresultat bör offentliggöras inom 18 arbetsdagar<br />

Lycka till!<br />

Sidan 0(6)


Tentamen har 4+2 sidor (inklusive en bilaga).<br />

Alla svar skall motiveras väl, d.v.s. det räcker inte med ett faktasvar. Enbart en faktauppgift<br />

(exempelvis, ett tal eller en benämning) är aldrig tillräckligt. Om en fråga verkar oklar, ange din<br />

egen tolkning först i ditt svar på frågan.<br />

Denna tentamen examinerar utifrån kursmålen, där det avgivna svaret värderas mot varje<br />

kursmål. Svaret för varje kursmål poängbedöms 1-10.<br />

• Kursmål 1: Användning av komplexitetsteori.<br />

• Kursmål 2: Användning av grundläggande datastrukturer.<br />

• Kursmål 3: Användning sorteringsalgoritmer.<br />

• Kursmål 4: Användning av grafer och tillämpliga algoritmer.<br />

• Kursmål 5: Användning av generella principer för algoritmdesign: giriga algoritmer,<br />

söndra och härska, dynamisk programmering, samt backtracking.<br />

• (Kursmål 6: Examineras i laborationsuppgiften, inte i denna tentamen).<br />

Frågor:<br />

1. [Kursmål 1]<br />

Algoritmanalys.<br />

a. Komplexitetsbegrepp<br />

i. Beskriv vad O() ‐begreppet (Big‐Oh) innebär i algoritmanalys. Varför är detta<br />

begrepp så viktigt vid konstruktion av en algoritm?<br />

ii. Hur skiljer sig O() från Ω() (dvs. Big‐Omega) och Θ() (dvs. Big‐Theta)?<br />

iii. Som komplexitetsuttryck används ofta en grov uppskattning. Vilka två grova<br />

antaganden gör man ofta för att få fram ett enklare komplexitetsuttryck?<br />

Varför gör man detta? Tips: Man är ute efter att veta hur komplexiteten<br />

växer med problemets storlek.<br />

1


. Grenanders problem (“Maximum Sub Sequence Problem”). Se följande<br />

implementation av algoritmen, vilken har logaritmisk tidskomplexitet.<br />

2. [Kursmål 2]<br />

int grenander4(int a[], int l, int h) {<br />

if (l > h) return 0;<br />

if (l == h) return max(0, a[l]);<br />

int m = (l + h) / 2;<br />

int sum = 0;<br />

int maxLeft = 0;<br />

for (int i = m; i >= l; i‐‐) {<br />

sum += a[i];<br />

maxLeft = max(maxLeft, sum);<br />

}<br />

sum = 0;<br />

int maxRight = 0;<br />

for (int i = m + 1; i


. Köer<br />

i. Jämför två olika implementationer av köer, dels som array och dels som<br />

länkad lista. Motivera skillnaden i deras komplexitet för de följande<br />

operationerna:<br />

insert(a), (insättning av element a i kö:n)<br />

remove(a), (hämta ut och ta bort element a ur kö:n)<br />

n=lookupElementIndex(a), (returnera element a på position n)<br />

där a är ett element och n är en position i kö:n.<br />

c. Binära sökträd<br />

i. Beskriv ett allvarligt problem med binära träd och vad konsekvenserna blir<br />

när det uppträder.<br />

ii. Beskriv angreppssättet hur man ofta löser detta. Ge exempel på två kända<br />

algoritmer som försöker lösa detta problem och principen för hur detta görs.<br />

d. Sentinels<br />

i. Vad är meningen med en sentinel?<br />

ii. Vad är en sentinel‐nod och när används detta?<br />

3. [Kursmål 3]<br />

Sorteringsalgoritmers komplexitet.<br />

a. Jämför en sorteringsalgoritm med tidskomplexiteten O(n log n) med en<br />

sorteringsalgoritm med tidskomplexiteten O(n 2 ).<br />

Detta är en essäfråga, besvara frågan utförligt och noggrant.<br />

i. Basera analysen på komplexiteten för de olika operationerna som ingår.<br />

ii. Vilken del bidrar med största beräkningskomplexiteten?<br />

iii. Jämför hur enkelt/svårt de båda sorteringsalgoritmerna realiseras.<br />

Hur påverkas beräkningstiden av indatas beskaffenhet?<br />

Vad är värsta och bästa fallet?<br />

iv. Stabilitet, behålls en underliggande sorteringsordning?<br />

4. [Kursmål 4]<br />

Traversering av grafer<br />

a. Ge en algoritm, i pseudokod, som med hjälp av en kö och ett minne för besökta<br />

noder traverserar alla noderna i en graf enligt en bredden‐först‐ordning. Varje nod<br />

besöks alltså endast en gång.<br />

3


5. [Kursmål 5]<br />

Giriga algoritmer<br />

a. I ett kassasystem vill vi kunna ge tillbaka växel till en kund. Mynten vi har att tillgå<br />

är på 1, 5, 10 respektive 25 enheter. Problemet är nu att för ett godtyckligt<br />

växelbelopp välja ett antal mynt av de olika valörerna så att: 1) myntens<br />

sammanlagda värde exakt uppgår till det eftersökta växelbeloppet; 2) ett så litet<br />

antal mynt som möjligt används. Vi antar att det finns tillräckligt många mynt av<br />

varje valör.<br />

i. Använd pseudokod för att ge en utförlig beskrivning av en girig algoritm<br />

som löser ovanstående problem.<br />

ii. Antag att vi förutom valörerna ovan också har mynt som är värda 12<br />

enheter. På vilket sätt påverkar det din giriga lösning?<br />

iii. Har vi situationen ”ii” är det bättre att försöka lösa växlingsproblemet<br />

m.h.a. söndra och härska (divide‐and‐conquer). Använd pseudokod för att<br />

ge en utförlig beskrivning av en algoritm som löser växlingsproblemet med<br />

denna teknik.<br />

Ledning: Tänk rekursivt! Antingen så kan vi växla hela beloppet med<br />

endast ett mynt eller så kan vi (på något lämpligt sätt) dela upp<br />

växelbeloppet, växla delbeloppen med minimalt antal mynt rekursivt och<br />

sedan konstruera en fullständig lösning från dellösningarna.<br />

b. En naiv lösning för problemet med 12‐enhetersmyntet (”iii”) lider av ett problem<br />

som är vanligt hos söndra‐och‐härska algoritmer. Beskriv detta problem. Vilken<br />

generell lösning finns på problemet?<br />

4


BILAGA 1: Att beskriva algoritmer<br />

Ett schema för hur man kan beskriva en algoritm är följande:<br />

1. ge en informell algoritm (intutiv beskrivning)<br />

2. ge en abstrakt algoritm (i pseudokod)<br />

3. analysera egenskaper, framförallt tidskomplexitet<br />

4. förklara de datastrukturer som används<br />

5. förfina algoritmen stegvis.<br />

Nedan ges en mer utförlig beskrivning av de olika stegen.<br />

1. Förklara hur algoritmen fungerar<br />

Först måste man förklara varför (i vilken mening/på vilket sätt) algoritmen löser problemet i<br />

fråga. För att göra detta kan man med fördel använda både sig av både text och bild.<br />

Beskrivningen ska vara intuitiv och lättförstålig men samtidigt kortfattad och koncis (med fördel<br />

används en mer matematisk notation på lagom nivå). Ett bra sätt är ofta att göra en "torrsimning"<br />

på ett konkret exempel. Det väsentliga i detta första steg är att algoritmens idé framgår tydligt<br />

och att man får hjälp med att förstå den abstrakta algoritmen i nästa steg.<br />

2. Ge (beskriv) en abstrakt algoritm<br />

Detta är en programspråksliknande beskrivning (i pseudokod) där man kan använda ADT:er för<br />

t.ex. listor, matriser och grafer, samt satser (instruktioner) av typen "för varje nod n i grafen G<br />

gör" och "om x finns i listan L så". Denna beskrivning ska alltså så långt som möjligt vara<br />

programspråksoberoende.<br />

Det väsentliga i detta steg är att algoritmens struktur framgår tydligt, att man får en förståelse<br />

för hur algoritmen skulle kunna implementeras i ett (imperativt) programspråk.<br />

Om man använder resultatet från en känd algoritm, t.ex. binärsökning i en sorterad lista, så räcker<br />

det att man i detta steg bara beskriver hur resultatet ser ut (och nämner vilken algoritm man har<br />

använt för att beräkna det). Anpassar man en känd algoritm för att passa den algoritm man håller<br />

på att beskriva så måste den anpassade algoritmen beskrivas i sin tur (vilket görs efteråt).<br />

Men man får inte vara för abstrakt! Om man t.ex. arbetar med ett binärt träd och vill skriva ut alla<br />

löv i trädet så är inte "traversera trädet" en bra abstraktion. En bra tumregel är att de satser som<br />

man använder i detta steg ska vara så abstrakta som det går samtidigt som det direkt måste framgå<br />

att de är fullt möjliga att implementera. Om detta inte är uppenbart måste man visa hur man har<br />

tänkt sig att implementera dessa satser. Detta gör man i sådana fall efter den abstrakta algoritmen,<br />

inte i den.<br />

3. Analysera algoritmens komplexitet<br />

Här är det nästan alltid tidskomplexiteten som är det mest intressanta. Analysen behöver inte vara<br />

formell utan det handlar snarare om att ge en uppskattning av komplexiteten och om att ge en<br />

övertygande motivering för hur man kom fram till denna. I mer generell mening är syftet med<br />

detta steg att beskriva algoritmens egenskaper.<br />

5


4. Beskriv de olika delarna i den abstrakta algoritmen<br />

Här beskriver man t.ex. hur man implementerar de ADT:er som ingår i den abstrakta algoritmen,<br />

hur "för varje nod n i grafen G gör" utförs och hur eventuella hjälpalgoritmer (både kända och<br />

egenkonstruerade) fungerar. Kända hjälpalgoritmer behöver normalt bara beskrivas enligt<br />

punkterna 1- 2 ovan. Naturligtvis behöver man inte beskriva hur en länkad lista implementeras<br />

eller hur linjär sökning i en lista går till (såvida de inte har modifierats förstås).<br />

Syftet med detta steg är att ge ytterligare förståelse för att den abstrakta algoritmen verkligen kan<br />

implementeras, att ge grundläggande idéer till hur den abstrakta algoritmen kan implementeras,<br />

att ge ytterligare detaljer till en eventuell utförligare komplexitetsanalys samt, inte minst, att<br />

förbereda inför nästa steg.<br />

5. Implementera algoritmen<br />

Här beskrivs hur algoritmen implementeras i valt programspråk. Detta sker ofta genom stegvisa<br />

förfiningar av algoritmen, där man för varje steg implementerar fler och fler detaljer. Eventuellt<br />

ska alla detaljer implementeras (ska algoritmen kunna köras på en dator är ju detta en<br />

förutsättning). Observera att implementationen av en algoritm kan skilja sig markant från den<br />

abstrakta algoritmen. Ett komplett körbart program är inte målet här, det räcker med att<br />

implementera den del av programmet som utgörs av själva algoritmen.<br />

6

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!