Rekursion C#-version



Relaterede dokumenter
Algoritmer og invarianter

Algoritmeskabeloner: Sweep- og søgealgoritmer C#-version

Divide-and-Conquer algoritmer

28 Algoritmedesign. Noter. PS1 -- Algoritmedesign

Divide-and-Conquer algoritmer

Abstrakte datatyper C#-version

Rekursion og dynamisk programmering

Forelæsning Uge 4 Mandag

Divide-and-Conquer algoritmer

Dynamisk programmering

BRP Sortering og søgning. Hægtede lister

Divide-and-Conquer algoritmer

Forelæsning 17, tirsdag 2. november 1999 Søgning efter en given værdi i en tabel. Programmering 1999

Dynamisk programmering

Programmering 1999 KVL Side 5-4. Klassen Time: metoder. Metoder i objektet giver mulighed for at ændre tilstanden, eller kigge på tilstanden.

Dynamisk programmering

Induktive og rekursive definitioner

Procedurer og funktioner - iteration og rekursion

Kursusarbejde 3 Grundlæggende Programmering

22 Hobe. Noter. PS1 -- Hobe. Binære hobe. Minimum-hob og maximum-hob. Den abstrakte datatype minimum-hob. Opbygning af hobe. Operationen siv-ned.

14 Algoritmeanalyse. Noter. Algoritmebegrebet. Hvad er algoritmeanalyse? Problemstørrelse og køretid. Køretid for forskellige kontrolstrukturer.

DRONNINGER (QUEENS) Opgave 1

Programmering og Problemløsning, 2017

Anvendelse af del og hersk princippet involverer altså problemopdelning og løsningskombination.

Sortering af information er en fundamental og central opgave.

Sortering. Eksempel: De n tal i sorteret orden

Skriftlig eksamen i Datalogi

Mandags Chancen. En optimal spilstrategi. Erik Vestergaard

Talrækker. Aktivitet Emne Klassetrin Side

Søgning og Sortering. Philip Bille

Søgning og Sortering. Søgning og Sortering. Søgning. Linæer søgning

Forelæsning Uge 4 Mandag

Programmering i C. Lektion november 2008

Forelæsning Uge 4 Torsdag

Anvendelse af metoder - Programmering

AAU, Programmering i Java Intern skriftlig prøve 18. maj 2007

Sortering. De n tal i sorteret orden. Eksempel: Kommentarer:

Skriftlig eksamen i Datalogi

DM507 Algoritmer og datastrukturer

Programmering i C. Lektion september 2009

Forelæsning Uge 3 Torsdag

Skriftlig Eksamen Algoritmer og Datastrukturer (DM507)

DANMARKS TEKNISKE UNIVERSITET

Sortering. Eksempel: De n tal i sorteret orden

Datastrukturer (recap)

Opfølgning på Dygtig Skildpadde (Michael) To algoritmeskabeloner

Forelæsning Uge 4 Torsdag

18 Multivejstræer og B-træer.

Skriftlig Eksamen Algoritmer og Datastrukturer (DM507)

DM507 Algoritmer og datastrukturer

Skriftlig eksamen i Datalogi

Søgning og Sortering. Søgning Linæer søgning Binær søgning Sortering Indsættelsessortering Flettesortering. Philip Bille

Programmering. Det rent og skært nødvendige, det elementært nødvendige! Morten Dam Jørgensen

DM507 Algoritmer og datastrukturer

Sortering af information er en fundamental og central opgave.

Martin Olsen. DM507 Projekt Del I. 19. marts 2012 FOTO: Colourbox

Datastrukturer (recap)

It og informationssøgning Forelæsning 5 4. oktober 2006 Nils Andersen. Tilfældige tal. Statistisk test. Sæt og associationslister.

BRP Kursusintroduktion og Java-oversigt

3 Algebraisk Specifikation af Abstrakte Datatyper.

Danmarks Tekniske Universitet

Programmering for begyndere Lektion 2. Opsamling mm

Forelæsning Uge 4 Mandag

Algoritmeanalyse. Øvre grænse for algoritme. Øvre grænse for problem. Nedre grænse for problem. Identificer essentiel(le) operation(er)

Kursusarbejde 2 Grundlæggende Programmering

Forelæsning Uge 3 Torsdag

Projekt - Visual Basic for Applications N på stribe

Skriftlig Eksamen DM507 Algoritmer og Datastrukturer

Introduktion til funktioner, moduler og scopes i Python

Et SML-program til at finde rødder i en kontinuert funktion

BRP Tal. Om computer-repræsentation og -manipulation. Logaritmer

Danmarks Tekniske Universitet

Danmarks Tekniske Universitet

Forelæsning Uge 3 Torsdag

Danmarks Tekniske Universitet

DM507 Algoritmer og datastrukturer

Grådige algoritmer. Et algoritme-konstruktionsprincip ( paradigme ) for optimeringsproblemer.

Kursus i OOP og Java. Kursus i Objektorienteret programmering i Java

Løsning af møntproblemet

DM502. Peter Schneider-Kamp

University of Southern Denmark Syddansk Universitet. DM502 Forelæsning 10

Danmarks Tekniske Universitet

Studiepraktik. Thomas Bøgholm Mikkel Hansen Jacob Elefsen

Danmarks Tekniske Universitet

Grafer og graf-gennemløb

Målet for disse slides er at diskutere nogle metoder til at gemme og hente data effektivt.

Invarianter. Invariant: Et forhold, som vedligeholdes af algoritmen gennem (dele af) dens udførelse. Udgør ofte kernen af ideen bag algoritmen.

Danmarks Tekniske Universitet

Videregående Programmering for Diplom-E Noter

[arbejdsgiver] sådan gør du... [søg i CV er]

Algorithms and Architectures I Rasmus Løvenstein Olsen (RLO) Mm2: Rekursive algoritmer og rekurrens - October 12, 2010

Algorithms and Architectures I Rasmus Løvenstein Olsen (RLO), Jimmy Jessen Nielsen (JJE) Mm2: Rekursive algoritmer og rekurrens - October 10, 2008

Skriftlig Eksamen Algoritmer og Datastrukturer (dads)

Kursusarbejde 1 Grundlæggende Programmering. Arne Jørgensen, klasse dm032-1a

Programmering og Problemløsning, 2017

Grundlæggende køretidsanalyse af algoritmer

Hvad er Objekter - Programmering

Hanne Niels Edith Harald Carsten Jørgen Henrik.

Et generelt algoritme-konstruktionsprincip ( paradigme ) for optimeringsproblemer. Ideen er simpel:

Kædebrøker. b 0 f.eks. 3 b 0 + a 1. f.eks b 1 7. a 1. b 1 + a f.eks f.eks. 3 + b 1 + a Notation: a 2 b 2 + an.

Transkript:

Note til Programmeringsteknologi Akademiuddannn i Informationsteknologi Rekursion C#-version Finn Nordbjerg 1

Rekursion Rekursionsbegrebet bygger på, at man beskriver noget ved "sig selv". Fx. kan tallet n! ("n-fakultet") defineres ved følgende formel: n! = 1 for n = 0; n! = n*(n-1)*(n-2)*...*2*1 for n 1 altså produktet af alle hele tal fra n og ned til 1. Tallet n! kan imidlertid også defineres på en anden måde, som er baseret på det forhold, at der gælder (1) n! = 1 for n = 0 (2) n! = n*(n-1)! for n > 1 En sådan definition kaldes rekursiv og er karakteriseret ved, at begrebet selv anvendes i definitionen. (1) kaldes definitionens basisdel og (2) dens rekursionsdel. Denne definition kan implementeres direkte ved følgende metode: public long FakRek( int n) {//PRE n>=0 if(n == 0) return 1; //basisdel return n*fakrek(n-1); //rekursionsdel I programmering anvendes betegnn rekursiv om metoder, som kalder sig selv. Ved rekursion forstås altså, at en problemløsningsmetode beskrives ved en basisdel, og at et givet skridt defineres udfra resultatet af et eller flere af de foregående skridt. Bemærk, at der skal altid være en basisdel og rekursionsdelen skal formuleres, så basisdelen altid nås til sidst. Ellers har man lavet sig en ikke-terminerende algoritme. Øv 1 Lav en ikke-rekursiv (dvs. iterativ) metode til beregning af n!. Øv 2 Lav et testprogram, som afprøver de to løsninger. Som for fakultetsberegning kan rekursive algoritmer altid omformes til en iterativ (overvej!!!), men for en lang række problemer er iterative løsninger meget mere komplekse og uoverskuelige. 2

Prisen for at anvende rekursive metoder (man får jo intet gratis) er et ekstra lagerforbrug, idet hver aktivering af metoden kræver lagring af data (parametre, lokale variable mv.). Disse data skal gemmes til kaldet af sluttes. For fakultetsberegnings vedkommende betyder dette, at der ved beregning af fx 10! skal gemmes oplysninger om 10 aktiveringer af metoden, inden kaldene begynder at returnere. Dette gøres automatisk på den såkaldte rekursionsstak, men lageret optages altså. I det følgende skal et par klassiske eksempler på rekursive løsninger kort beskrives. Tårnene i Hanoi Dette er et eksempel, hvor det er langt lettere at udlede en rekursiv algoritme end en iterativ. I følge sagnet har munkene i en buddhistorden i Hanoi længe været optaget af følgende opgave: Der er tre stænger og 64 skiver af forskellig størr. Hver skive har et hul i midten, så den kan placeres på en af stængerne. I starten var alle 64 skiver placeret på een stang. Skiverne er sorteret efter størr og største skive ligger nederst. Se figur: Kilde Hjælp Mål Opgaven går ud på at flytte tårnet fra denne stang (kilden) til en anden stang (målet). Den tredje stang (hjælp) kan undervejs anvendes til midlertidig opbevaring af skiver. For at gøre opgaven interessant (den siges at være lutrende for sjælen), skal følgende regler overholdes: - der må kun flyttes een skive ad gangen - en større skive må aldrig lægge ovenpå en mindre (For at imødegå dumsmarte løsninger skal det pointeres, at skiverne selvfølgeligt kun må placeres på en af de tre stænger ikke på jorden ved siden af!). Sagnet fortæller endvidere at fuldførn af opgaven vil indvarsle Verdens undergang. Løsningen af denne opgave er ikke indlysende, men lad se: For at flytte tårnet må den nederste skive (den største) flyttes fra kilden til målet. Dette kan ikke lade sig gøre før de 63 skiver, som ligger ovenpå, er flyttet til hjælpestangen, men så er det simpelt. Derefter må de 63 skiver flyttes fra hjælpestangen til målet. Men hvordan skal vi flytte de 63 skiver fra kilden til hjælpestangen? Dette kan gøres ved at flytte 62 skiver fra kilden til målet, derefter flytte den sidste skive til hjælpestangen, og til sidst flytte de 62 skiver tilbage igen. 3

Men hvordan flytter vi 62 skiver? Ved at flytte de 61 øverste. Dette er en rekursiv strategi, hvor vi opdeler vores problem i stadig mindre problemer (at flytte 63 skiver er et mindre problem end at flytte 64 etc.) indtil vi når basisdelen: at flytte én skive. Vi kan altså formulere følgende løsning: - flyt 63 skiver fra kilde til hjælpstang (målet kan bruges som arbejdsplads) - flyt een skive fra kilde til mål - flyt 63 skiver fra hjælpestang til mål (kilden kan bruges som arbejdsplads) På tilsvarende måde kan 63 skiver flyttes ved at flytte 62 skiver og derefter flytte een og så flytte 62 igen etc. etc. Generelt kan løsningen formuleres ved følgende rekursive metode (n er antal skiver i tårnet): public void FlytTaarn(int n,string kilde, string maal, string hjlp) { if (n==1) Console.WriteLine( Flyt skive fra +kilde+ til +maal); { FlytTaarn(n-1,kilde,hjlp,maal); Console.WriteLine( Flyt skive fra +kilde+ til +maal); FlytTaarn(n-1, hjlp, maal, kilde); Til berolig for evt. læsere, der bekymrer sig for Verdens snarlige undergang, kan følgende anføres: Udfør med n=64 resulterer i to kald med n=63, der igen hver resulterer i to kald med n=62 etc. I alt 2 64-1 kald. I hvert kald flyttes een skive. Dvs., at hvis munkene kan flytte een skive i sekundet, aldrig laver fejl og arbejder døgnet rundt året rundt, så vil det tage ca 600 000 000 000 år at flytte tårnet (det kan vises, at der ikke findes nogen hurtigere algoritme), og til den tid skal Verden såmænd nok være gået under alligevel. Det skal understreges, at dette er en meget koncis og elegant løsning på et ikke-trivielt problem. Der findes iterative løsninger, men de er komplekse og vanskelige at udlede (prøv!). Øv 3 Lav et testprogram, som afprøver ovenstående. (Lad være med at teste med 64 skiver!) Binær søgning Binær søgning er et eksempel på en meget elegant løsning på et problem. Normalt udledes algoritmen for binær søgning fra søgeskabelonen (se note om algoritmeskabeloner), men løsningen kan også formuleres rekursivt, hvilket giver en enklere og elegantere, men ikke helt så effektiv løsning. 4

Følgende metode undersøger om et givet element, x, findes i et sorteret array, T. Elementtypen er blot int: public bool BinSearch(int l, int h, int x, int[] T) {//PRE T er sorteret int m; if(l>h) return false; { m = (l+h)/2; if(x==t[m]) return true; if(x>t[m]) return BinSearch(m+1,h,x,T); return BinSearch(l,m-1,x,T); Prøv at ændre metoden, så den returnerer indekset på det søgte element. Øv 4 Lav en ikke-rekursiv formulering af BinSearch. Øv 5 Lav et test program, som afprøver de to udgaver af BinSearch. Øv 6 Ved Fibonacci-tallene forstås en følge af hele positive tal, hvor et givet Fibonaccital findes som summen af de to foregående. Rekursiv definition: Udarbejd (1) Fib(n) = n for n= 0 og n= 1 (2) Fib(n) = Fib(n-1) + Fib(n-2) for n>1 a) en rekursiv funktion til beregning af et givet Fibonaccital, og b) en iterativ funktion til beregning af et givet Fibonaccital. 5

Øv 7 Lav et testprogram, som afprøver de to udgaver af Fib(-). Kan du registrere forskel I deres effektivitet? (Lad vær at teste den rekursive udgave med store tal (dvs. ikke meget over 40). 6