Oppgave 1 Minimum edit distance

Like dokumenter
INF2810: Funksjonell Programmering. Trær og mengder

INF2810: Funksjonell Programmering. Lokale variabler. Og trær.

Definisjon. I et binært tre har hver node enten 0, 1 eller 2 barn

INF2220: Forelesning 1. Praktisk informasjon Analyse av algoritmer (kapittel 2) (Binær)trær (kapittel )

EKSAMEN med løsningsforslag

Definisjon av binært søketre

Binære trær: Noen algoritmer og anvendelser

Definisjon: Et sortert tre

EKSAMEN Løsningsforslag. med forbehold om bugs :-)

Binære søketrær. Et notat for INF1010 Stein Michael Storleer 16. mai 2013

INF Algoritmer og datastrukturer. Hva er INF2220? Algoritmer og datastrukturer

INF2810: Funksjonell Programmering

INF2810: Funksjonell Programmering

Algoritmer og Datastrukturer

Binære søketrær. En ordnet datastruktur med raske oppslag. Sigmund Hansen

(define (naer-nok-kuberot? y x) (< (abs (- (kube y) x)) 0.001)) (define (naermere-kuberot y x) (/ (+ (* y 2) (/ x (kvadrat y))) 3))

INF1010 Rekursive metoder, binære søketrær. Algoritmer: Mer om rekursive kall mellom objekter Ny datastruktur: binært tre

PG4200 Algoritmer og datastrukturer Forelesning 7

Hva er en algoritme? INF HØSTEN 2006 INF1020. Kursansvarlige Ragnar Normann E-post: Dagens tema

INF2220: Forelesning 2

Høyere-ordens prosedyrer

UNIVERSITETET I OSLO

INF2220: Time 12 - Sortering

INF2810: Funksjonell Programmering. Kommentarer til prøveeksamen

Rekursjon og lister. Stephan Oepen & Erik Velldal. 1. februar, Universitetet i Oslo

INF1010 Binære søketrær ++

Løsnings forslag i java In115, Våren 1998

Eksamen i IN 110, 18. mai 1993 Side 2 Del 1 (15%) Vi skal se på prioritetskøer av heltall, der vi hele tiden er interessert i å få ut den minste verdi

Et eksempel: Åtterspillet

Innlevering 2a i INF2810, vår 2017

Algoritmer og Datastrukturer IAI 21899

LO118D Forelesning 2 (DM)

Løsnings forslag i java In115, Våren 1996

Vi skal se på lambda-uttrykk. Følgende er definerte og vil bli brukt gjennom oppgaven

INF2810: Funksjonell Programmering

Algoritmer og datastrukturer Løsningsforslag

Løsningsforslag. Emnekode: Emne: Matematikk for IT ITF Eksamenstid: Dato: kl til kl desember Hjelpemidler: Faglærer:

Et eksempel: Åtterspillet

UNIVERSITETET I OSLO

Balanserte binære søketrær

UNIVERSITETET I OSLO

INF2810: Funksjonell Programmering. Lister og høyereordens prosedyrer

Rekursiv programmering

Dynamisk programmering Undervises av Stein Krogdahl

INF2220: Forelesning 1

Algoritmer og Datastrukturer

Datastrukturer for rask søking

Innledning. IN2010/INF Algoritmer og datastrukturer. Tirsdag 27. november 2018 Kl (4 timer)

Par og Lister (først et par sider fra forrige uke) Par er byggestener for lister og trær og sammensatte datatyper.

INF2810: Funksjonell Programmering

INF2810: Funksjonell Programmering. Huffman-koding

INF2810: Funksjonell Programmering. Lister og høyereordens prosedyrer

Algoritmer og datastrukturer Løsningsforslag

EKSAMEN. Dato: 18. mai 2017 Eksamenstid: 09:00 13:00

Søkeproblemet. Gitt en datastruktur med n elementer: Finnes et bestemt element (eller en bestemt verdi) x lagret i datastrukturen eller ikke?

INF2810: Funksjonell Programmering. Huffman-koding

INF Algoritmer og datastrukturer

INF2810: Funksjonell programmering: Mer om Scheme. Rekursjon og iterasjon.

TMA4140 Diskret Matematikk Høst 2016

Dagens tema. INF Algoritmer og datastrukturer. Binærtrær. Generelle trær

Symbolske data SICP 2.3

Dynamisk programmering

Alg. Dat. Øvingsforelesning 3. Grafer, BFS, DFS og hashing. Børge Rødsjø

ITF20006 Algoritmer og datastrukturer Oppgavesett 7

EKSAMEN. Algoritmer og datastrukturer

Dagens plan. INF Algoritmer og datastrukturer. Koding av tegn. Huffman-koding

Hvorfor sortering og søking? Søking og sortering. Binære søketrær. Ordnet innsetting forbereder for mer effektiv søking og sortering INF1010 INF1010

Dynamisk programmering

INF110 Algoritmer og datastrukturer TRÆR. Vi skal i denne forelesningen se litt på ulike typer trær:

Kap 9 Tre Sist oppdatert 15.03

EKSAMEN. Emne: Algoritmer og datastrukturer

Algoritmer og datastrukturer Eksamen 22. februar 2011

Notater til INF2220 Eksamen

Eksamen iin115, 14. mai 1998 Side 2 Oppgave 1 15 % Du skal skrive en prosedyre lagalle som i en global character array S(1:n) genererer alle sekvenser

Transkript:

INF-2810 V 2012 Oppgavesett 10, kalenderuke 12. Oppgave 1 Minimum edit distance Vi vil finne det minste antall redigeringsoperasjoner som kreves for å komme fra strengen A til strengen B. Strengene oppgis som symboler og konverteres til strenger som igjen konverteres til lister med tegn. (string->list (symbol->string 'hallo)) ==> (#\h #\a #\l #\l #\o). For sammenligning av listelementer bruker vi primitiven char=?. 1.a Prosedyren min-edit-dist-functional finner det minste antall redigeringsoperasjoner ved å løpe gjennom de to listene i en rekursive prosedyre. - Hvis A tar slutt før B økes kostnaden med lengden til resten av B, og vice versa. - Så lenge car-elementene i de to listen er like, går vi videre i begge uten at kostnaden øker. - Når car-elementene er ulike, fortsetter rekursjonen i to grener - til venstre med (cdr A) og B og - til høyre med A og (cdr B) og returnerer omkostningene ved den billigste av de to grenene. For hver forgrening økes kostnaden med 1. Eks: (forskjell '(h a l l o) '(h a l lo)) ==> 0 (forskjell '(h a l l o) '(h a l o)) ==> 1 (forskjell '(h a l l o) '(h o l a)) ==> 5 (forskjell '(h a l l o) '(t y t t e b æ r)) ==> 13 Implementer min-edit-dist-functional. 1.b Prosedyre n min-edit-dist-destructive finner det minste antall redigeringsoperasjoner ved hjelp av en matrise (todimensjonal tabell) M der liste A bestemmer radene og liste B bestemmmer kolonnene. La a-leng og b-leng være lengdene til henholdsvis A og B. Da skal første rad i M være en enumerering fra 0 tilb-leng. Under dettte skal det være a-leng rader som starter med henholdsvis 1, 2, osv. og som ellers inneholder nuller. 1

F.eks. hvis A = (h a l l o) og B = (h o l a), får vi (0 1 2 3 4) (1 0 0 0 0) M = (2 0 0 0 0) (3 0 0 0 0) (4 0 0 0 0) (5 0 0 0 0) som vi for leselighetens skyld skriver slik: 0 1 2 3 4 1 0 0 0 0 h 2 0 0 0 0 a 3 0 0 0 0 l 4 0 0 0 0 l 5 0 0 0 0 o h o l a Den første radene er indeksene til tegnene i B, regnet fra 1, og gir samtidig kostnadene ved å settte inn hele B. Den første kolonnen er indeksene til tegnene i A, regnet fra 1, og gir samtidig kostnadene ved å slettte hele A. Der neste tegn i A = neste tegn i B, kan vi gå diagonalt uten omkostninger. Algoritmen løper gjennom matrisen og fyller cellene med kostnadene ved å komme dit. Utfylling av kostnadene i de enkelte cellene Står vi i celle M[i, j], så er - kostnaden ved å gå ett trinn bort, til M[i + 1, j], eller ett trinn ned, til M[i, j + 1] = 1, mens - kostnadene ved å gå diagonalt, til M[i + 1, j + 1] er enten 0 eller 2, avhengig av om B[i + 1] = A[j + 1] eller ikke. Disse ett-trinns-kostnadene legges til det det har kostet å komme til M[i, j]. Med eksemplet over får vi, når hele matrisen en er gjennomløpt, 0 1 2 3 4 1 0 1 2 3 h 2 1 2 3 4 a 3 2 3 2 3 l 4 3 4 3 4 l 5 4 3 4 5 o h o l a De røde tallene viser én mulig vei, mens de fete tallene viser det området den korteste veien må gå gjennom. Fyll ut prosedyren traverse i skallet min-edit-distance-skall.scm. Her er en nokså ordrik gjennomgang av minimum edit distance algoritmen: http://folk.uio.no/asbr/lecturesandcompendia/mineddist.pdf 2

Oppgave 2 Antall binære trær med n noder Med null noder får vi ett tre det tomme treet Med én node får vi også ett tre. Med to noder får vi to trær Med tre noder får vi fem trær Med fire node får vi fjorten trær I mengden av trær med nodene {1, 2, 3, 4, 5} har alle én av disse nodene som rot. I mengden av trær der 1 er rot har vi ett venstre-subtre,, og 14 høyre-subtrær, tilsammen 14 trær. Med 2 som rot har vi 1 venstre- og 5 høyre-subtrær, tilsammen 5 trær. Med 3 som rot har vi 2 venstre og 2 høyre-subtrær som, når vi kombinerer dem, gir tilsammen 2 2 = 4 trær. Med rot 4 og 5 har vi, som med rot 2 og 1, hhv. 5 og 14 trær, og legger vi alt dette sammen får vi 42 trær. Tilsvarende, med nodene 1.. 6, får vi 1 42 + 1 14 + 2 5 + 5 2 + 14 1 + 42 1 = 132 trær. Generelt, med n noder og rot k, 1 k n er antall venstre-subtrær = antall trær med k 1 noder, antall høyre-subtrær = antall trær med n k noder, og antall trær totalt = produktet av disse. Tilsammen er antall trær med n noder = summen av produktene av antall trær med i 1 noder og antall trær med n i noder, for i = 1 til n. Eller med andre ord, hvis f(n) = antall trær med n noder, har vi: n f(n) = f(0) f(n 1) +.. + f(n 1)f(0) = f(i 1)f(n i), n 1 (1) i=1 3

2a. Algoritme 1 Med henblikk på en implementasjon kan vi bruke en lokal iterator for akkumulering av summetermen f(i 1)f(n i). (define (count-b-trees-1 n) (2) (define (sum i s) <tell fra og med i til og med n og akkumulér produktene i summen s>) <kroppen til count-b-trees-1>) Skriv count-b-trees i hht. algoritme 1. 2b. Algoritme 2 Selv om vi har en lokal akkumulerende iterator i (2) får vi allikevel eksponensiell vekst, i og med at vi hele tiden tar produktet av to kall på count-b-trees. For å unngå dette kan vi lage en liste med de resultatene vi har funnet i stigende orden (r 1,, r k ). Da vil r k+1 være r 1 r k + r 2 r k 1 + + r k r 1. (3) F.eks. de 6 første resultatene, fra f(0) til f(5), er 1, 1, 2, 5, 14, 42. Dette gir 1 1 2 5 14 42 1 1 2 5 14 42 132 f(6) = + + + + + f(7) = + + + + + + (4) 42 14 5 2 1 1 132 42 14 5 2 1 1 = 42 + 14 + 10 + 10 + 14 + 42 = 132 = 132 + 42 + 28 + 25 + 28 + 42 + 132 = 429 Denne algoritmen gir kvadratisk vekst. Skriv count-b-trees-2 i hht. algoritme 2. 2c. Algoritme 3 Som vi ser gir beregningen i implementasjon 2 en symmetrisk liste med produkter. Dette kan vi utnytte slik: Hvis vi har et like antall summer dobler vi resultatet av summeringen av den første halvdelen av produktene, og hvis vi har et odde antall summer legger vi kvadratet av det midterste tallet til det dobbelte av summen opp til midten. F.eks. slik: (1 42 + 1 14 + 2 5 + 5 2 + 14 1 + 42 1) = 2(1 42 + 1 14 + 2 5) (1 132 + 1 42 + 2 14 + 5 5 + 14 2 + 42 1 + 132 1) = 2(1 132 + 1 42 + 2 14) + 5 2. (5) Skriv count-b-trees-3 i hht. algoritme 3. 4

2d. Algoritme 4 Vi antar nå at det finnes en lineær funksjon g slik at I så fall skal vi ha f(n) = g(n)f(n 1). (6) For n = 10 får vi g(1), g(2),, g(n 1) = f(2) / f (1), f(3) / f (2),, f(n) / f (n 1), 1 4 1 1 1 2 5 1, 2, 2, 2, 3, 3, 3, 3, 3, 3 (7) 2 5 7 4 3 5 11 1 2 5 14 3 22 13 10 17 38 =,,,,,,,,, (8) 1 1 2 5 1 7 4 3 5 11 Etter våre antagerlser skal det være mulig å skrive om (8) slik at rekkene med tellere og nevnere blir jevnt stigende. Vi kan gjette, eller vi kan skrive en prosedyre som gir oss slike rekker, om input passer. - Vi løper gjennom listen med tall og ser på tre suksessive tall av gangen, a, b og c og - beregner d til taket av snittet av a og c, (a + b)/2, i Scheme: (inexact->exact (ceiling (/ (+ a c) 2))). - Hvis b d legger vi d inn i ut-listen, og, for å få rett gjennomsnitt i neste runde, legger vi også d først i resten av in-listen; og så noterer vi oss at listen ble endret. Prosessen gjentas inntil ingen endringer ble utført. Feks. skal vi for rekken av tellerne i (8) få (lift '(1 2 5 14 3 22 13 10 17 38)) ==> (1 6 10 14 18 22 26 30 34) Vi ser at fra og med det andre tallet stiger rekken jevnt med 4. Skriv prosedyren lift for løfting og utjevning av lister med tall, bruk prosedyren til å bestemme funksjonen g, og skriv count-b-trees som en implementasjon av (6). Drøfting av prosedyren lift La P = (p 1,, p n ) og Q = (q 1,, q n ) være lister med heltall slik at P er jevnt stigende, Q P, q 1 = p 1, q n = p n, og q i p i, for 1 i n, (P og Q begynner og slutter med samme tall, og ellers er tallene i Q de tilsvarende tallene i P). Da er lift(q) = P. - At P er jevnt stigende betyr at for alle tripler xyz i P så er y = (x + z)/2. - Hvis Q P så finnes det en trippel xyz i Q slik at y < (x + z)/2, fordi siden P er stigende må q n være større enn q 1, Q må ha et minimum m < q n, og hvis q m er det siste tallet i Q som er lik m, må q m < (q m 1 + q m+1 )/2. Etter en runde i den indre iteratoren vil q m = (q m 1 + q m+1 )/2. Da er enten Q = P eller så gjelder det samme som over. 5

2e. Telling av antall beregninger For å telle antall kjerneoperasjoner under utførelsen av de ulike implementasjonene kan vi erstatte kallene på * med en multiplikator med en intern kall-teller. Multiplikatoren må være en prosedyre som har en lokal teller, initielt = 0, i sin umiddelbare omgivelse, tar et valgritt antall argumenter og virker slik: Hvis den kalles uten argument, setter den telleren til 0 og returnerer den verdien telleren hadde før nullstillingen, og ellers øker den telleren med 1 og returnerer produktet av sine argumenter. Skriv ovennevnte konstruktor, bruk denne til å lage en prosedyren mul, erstatt alle kall på * med kall på mul, og kall mul med 0 som argument etter hvert kall på de ulike implementasjonene. 2f. For spesielt interesserte En implementasjon av algoritme 4 viser at f(n) 2(2n 3) g(n) = = (9) f(n 1) n og dermed at 2(2n 3) f(n 1) f(1) = 1, f(n) =, n > 1 (10) n som vi kan skrive om til: 2(2 2 3) 2(2 3 3)... 2(2 n 3) 2 n 1 1 3... (2n 3) f(n) = = osv. (11) 2 3... n n! til vi står igjen med et relativt enkelt uttrykk på fomen n( (n))! = (12) (n!) De som har moro av det, kan prøve å gjennomføre omskriving, og finne og, og/eller finne andre omskrivninger som gir andre forenklinger. 6