Presentasjon lastes. Vennligst vent

Presentasjon lastes. Vennligst vent

1 INFO231: Programutvikling F11: Rekursjon 11. mars 2003 INFO231 – Programutvikling Rekursjon.

Liknende presentasjoner


Presentasjon om: "1 INFO231: Programutvikling F11: Rekursjon 11. mars 2003 INFO231 – Programutvikling Rekursjon."— Utskrift av presentasjonen:

1 1 INFO231: Programutvikling F11: Rekursjon 11. mars 2003 INFO231 – Programutvikling Rekursjon

2 2 INFO231: Programutvikling F11: Rekursjon 11. mars 2003 Rekursivt eksempel N, positivt heltall sum(N) = summen av alle heltall mellom 1 og N Rekursiv definisjon: sum(1) = 1 sum(5) = 5 + sum(4) Base tilfellet er 1

3 3 INFO231: Programutvikling F11: Rekursjon 11. mars 2003 int sum(int n) { //finner summen av heltall mellom 1 og n int resultat; if (n==1) resultat=1; else resultat=n+sum(n-1); return resultat; }

4 4 INFO231: Programutvikling F11: Rekursjon 11. mars 2003 Rekursiv programmering main sum sum(3) sum(1) sum(2) result = 1 result = 3 result = 6

5 5 INFO231: Programutvikling F11: Rekursjon 11. mars 2003 Rekursiv programmering En metode i Java kan kalle seg selv; en slik metode er kalt en rekursiv metode Koden til en rekursiv metode må inneholde både base tilfellet og det rekursive tilfellet Hvert kall til metoden setter opp et nytt eksekveringsmiljø, med nye parametere og lokale variable Når metoden er ferdig, returnerer kontrollen til metoden som kalte den (dette kan være et tidligere kall på samme metoden)

6 6 INFO231: Programutvikling F11: Rekursjon 11. mars 2003 Uendelig rekursjon Alle rekursive definisjoner må ha en IKKE- rekursiv del Ellers kan vi ikke stoppe den rekursive stien Den ikke-rekursive delen er ofte kalt base tilfellet

7 7 INFO231: Programutvikling F11: Rekursjon 11. mars 2003 Rekursiv tankegang Finn en måte å løse et overordnet problem ved å –bryte det ned i delproblem, slik at et av del-problemene kan løses med samme metode som løser det overordnede problemet –løsningene på delproblemene kombineres så for å gi løsningen på det overordnede problemet

8 8 INFO231: Programutvikling F11: Rekursjon 11. mars 2003 Generalisering Vi bryter et problem ned i mindre og mindre problem –Et delproblem løses ved å kalle metoden rekursivt til delproblemet er så enkelt at det kan løses direkte –På hvert trinn blir løsningene på delproblemene kombinert for å gi løsningen på det overordnede problemet

9 9 INFO231: Programutvikling F11: Rekursjon 11. mars 2003 Å legge sammen kvadrat av tall fra m til n, hvor m <= n sumSquares(m,n) = m 2 + (m +1) 2 +... + n 2 sumSquares(2,4) = 2 2 + 3 2 + 4 2 = 4 + 9 + 16 = 29

10 10 INFO231: Programutvikling F11: Rekursjon 11. mars 2003 Å legge sammen tall iterativt Legg sammen kvadratene for tall fra m til n, hvor m <= n int sumSquares(int m,int n) { int i, sum; sum = 0; for (i = m; i <= n; i++) sum += i*i; return sum; }

11 11 INFO231: Programutvikling F11: Rekursjon 11. mars 2003 Rekursivt alternativ int sumSquares(int m,int n) { if (m < n) { return m*m + sumSquares(m+1,n); } else { return m*m; } } Rekursivt kall Basis-tilfelle

12 12 INFO231: Programutvikling F11: Rekursjon 11. mars 2003 En annen måte å løse problemet på int sumSquares(int m,int n) { if (m < n) { return sumSquares(m,n-1)+ n*n; } else { return n*n; } } Hva er annerledes?

13 13 INFO231: Programutvikling F11: Rekursjon 11. mars 2003 Del problemet i to like deler int sumSquares(int m,int n) { int middle; if (m == n) { // basistilfelle return n*n; } else { middle = (m+n)/2; return sumSquares(m,middle) + sumSquares(middle+1,n); }

14 14 INFO231: Programutvikling F11: Rekursjon 11. mars 2003 Strategi for “del i to like” Finn sum av kvadrat i venstre halvdel og legg dem til sum av kvadrat i høyre halvdel 5 10 7 8 m middlemiddle +1n Finn middle ved heltallsdivisjon — bruk heltallsverdi og kast rest Fortsett til hver del består av ett tall

15 15 INFO231: Programutvikling F11: Rekursjon 11. mars 2003 Kalltre for deling i to-strategien bruker kalltre for å vite hvor kontroll skal tilbakeføres etter at en metode er utført sumSquares(5,10) sumSquares(8,10)sumSquares(5,7) sumSquares(10,10)sumSquares(8,9)sumSquares(7,7)sumSquares(5,6) sumSquares(9,9)sumSquares(8,8)sumSquares(6,6)sumSquares(5,5)

16 16 INFO231: Programutvikling F11: Rekursjon 11. mars 2003 Generell tilnærming Rekursive program kaller seg selv for å finne en løsning på et problem De gjør det for å –finne løsning på problem som er mindre eller enklere enn et overordnete problem –subproblem kan løses direkte (basistilfellet) eller rekursivt ved å foreta rekursive kall –løsning på subproblemet kombineres med løsninger på andre subproblem for å få løsning på det overordnede problem

17 17 INFO231: Programutvikling F11: Rekursjon 11. mars 2003 Å tenke rekursivt Still deg følgende spørsmål: –Hvordan kan problemet deles i mindre problem som kan løses med samme metode? –Når problemene blir små nok, hvordan løses de direkte uten videre nedbrytening, dvs. hvordan løses de uten rekursive kall? –Hvis løsningen på subproblemene er klar, hvordan kan de kombineres slik at de gir løsningen på hovedproblemet? Tenk på typiske eksempel!

18 18 INFO231: Programutvikling F11: Rekursjon 11. mars 2003 Rekursiv programmering Bruk rekursjon fornuftig Bruk det ikke for å beregne summen av tallene mellom 1 og N

19 19 INFO231: Programutvikling F11: Rekursjon 11. mars 2003 Tårnet av Hanoi Tårnet av Hanoi er et a puslespill bygget opp av tre vertikale pinner og flere ringer som vi kan legge på pinnene Ringene er av forskjellige størrelser. I starten er alle ringene plassert på samme pinne med største ringen nederst og så reduseres størrelsen på ringene gradvis oppover, med den minste ringen på topp. Målet er å flytte alle ringene fra en pinne til en annen ved å følge følgende regler: –Bare en ring kan flyttes om gangen –Vi kan ikke flytte en større ring over en som er mindre ring.

20 20 INFO231: Programutvikling F11: Rekursjon 11. mars 2003 Tårnet av Hanoi Iterativ løsning blir veldig kompleks Rekursiv løsning er mye kortere og mer elegant

21 21 INFO231: Programutvikling F11: Rekursjon 11. mars 2003 //******************************************************************** // SolveTowers.java Author: Lewis and Loftus // // Demonstrates recursion. //******************************************************************** import TowersOfHanoi; public class SolveTowers { //----------------------------------------------------------------- // Creates a TowersOfHanoi puzzle and solves it. //----------------------------------------------------------------- public static void main (String[] args) { TowersOfHanoi towers = new TowersOfHanoi (4); towers.solve(); }

22 22 INFO231: Programutvikling F11: Rekursjon 11. mars 2003 public class TowersOfHanoi{ private int totalDisks; public TowersOfHanoi (int disks){ totalDisks = disks; } public void solve (){ moveTower (totalDisks, 1, 3, 2); } private void moveTower (int numDisks, int start, int end, int temp){ if (numDisks == 1) moveOneDisk (start, end); else{ moveTower (numDisks-1, start, temp, end); moveOneDisk (start, end); moveTower (numDisks-1, temp, end, start); }

23 23 INFO231: Programutvikling F11: Rekursjon 11. mars 2003 //---------------------------------------------- // Prints instructions to move one disk from the // specified start tower to the specified end tower. //----------------------------------------------- private void moveOneDisk (int start, int end) { System.out.println ("Move one disk from ” + start + " to " + end); }

24 24 INFO231: Programutvikling F11: Rekursjon 11. mars 2003 private void solveHanoi (int n, Stack a, Stack b, Stack c) { if (n > 0) { solveHanoi(n-1, a, c, b); // move one disk Object disk = a.getLast(); a.removeLast(); b.addLast(disk); // then repaint repaint(); …. solveHanoi(n-1, c, b, a); }

25 25 INFO231: Programutvikling F11: Rekursjon 11. mars 2003 Traversering av en labyrint Bruk av rekursjon for å finne en sti gjennom en labyrint Fra hver lokasjon kan vi søke i hver retning Rekursjon holder orden på stien gjennom labyrinten Base tilfellet er et ikke-gyldig steg eller at vi har kommet ut av labyrinten på rett plass

26 26 INFO231: Programutvikling F11: Rekursjon 11. mars 2003 111x11xxX1111 1X111X1111xX1 XXxx1X101X1xx 111X111x1X111 1X1xxxX111xx1 1X111111x1111 1xxxxxxXxxxxX 1111111111111 ---x11xxX1111 1X---X---1xX1 XXxx-X-X-x1xx ---x---X-X111 -X-xxxX--1xx1 -X------x1111 -xxxxxxXxxxxx -------------

27 27 INFO231: Programutvikling F11: Rekursjon 11. mars 2003 public class Maze{ private final int TRIED = 3; private final int PATH = 7; private int[][]grid={{1,1,1,0,1,1,0,0,0,1,1,1,1}, {1,0,1,1,1,0,1,1,1,1,0,0,1}, {0,0,0,0,1,0,1,0,1,0,1,0,0}, {1,1,1,0,1,1,1,0,1,0,1,1,1}, {1,0,1,0,0,0,0,1,1,1,0,0,1}, {1,0,1,1,1,1,1,1,0,1,1,1,1}, {1,0,0,0,0,0,0,0,0,0,0,0,0}, {1,1,1,1,1,1,1,1,1,1,1,1,1}};

28 28 INFO231: Programutvikling F11: Rekursjon 11. mars 2003 public boolean traverse (int row, int column){ boolean done = false; if (valid (row, column)){ grid[row][column] = TRIED; //this cell is tried if (row==grid.length-1 && column==grid[0].length-1) done = true; // the maze is solved else{ done = traverse (row+1, column); //down if (!done) done = traverse (row, column+1); //right if (!done) done = traverse (row-1, column); //up if (!done) done = traverse (row, column-1); //left } if (done) // location is part of the final path grid[row][column] = PATH; } return done; }

29 29 INFO231: Programutvikling F11: Rekursjon 11. mars 2003 private boolean valid (int row, int column){ boolean result = false; // check if cell is in the bounds of the matrix if (row >= 0 && row < grid.length && column >= 0 && column < grid[row].length) //is cell not blocked and not previously tried if (grid[row][column] == 1) result = true; return result; } public String toString (){ String result = "\n"; for (int row=0; row < grid.length; row++){ for (int column=0;column<grid[row].length;column++) result += grid[row][column] + ""; result += "\n"; } return result; }

30 30 INFO231: Programutvikling F11: Rekursjon 11. mars 2003 import Maze; public class MazeSearch{ public static void main (String[] args){ Maze labyrinth = new Maze(); System.out.println (labyrinth); if (labyrinth.traverse (0, 0)) System.out.println (”Successfully traversed!"); else System.out.println (”No possible path."); System.out.println (labyrinth); }

31 31 INFO231: Programutvikling F11: Rekursjon 11. mars 2003 Bilder Ønsker å repeterer bilder gjentatte ganger i en mosaikk. Lage et bilde som minner om bildet vi får når vi ser i to speil som refleketerer hverandre. Base tilfellet er nådd når arealet på bildene har nådd en gitt størrelse.

32 32 INFO231: Programutvikling F11: Rekursjon 11. mars 2003 import java.applet.Applet; import java.awt.*; public class MirroredPictures extends Applet{ private final int APPLET_WIDTH = 320; private final int APPLET_HEIGHT = 320; private final int MIN = 20; //smallest picture size private Image world, everest, goat; public void init(){ world=getImage(getDocumentBase(),"world.gif"); everest=getImage(getDocumentBase(),"everest.gif"); goat=getImage(getDocumentBase(),"goat.gif"); setSize (APPLET_WIDTH, APPLET_HEIGHT); }

33 33 INFO231: Programutvikling F11: Rekursjon 11. mars 2003 public void drawPictures (int size, Graphics page){ page.drawImage(everest,0,size/2,size/2,size/2,this); page.drawImage(goat,size/2,0,size/2,size/2,this); page.drawImage(world,size/2,size/2,size/2,size/2,this); if (size > MIN) drawPictures (size/2, page); } public void paint (Graphics page){ drawPictures (APPLET_WIDTH, page); }

34 34 INFO231: Programutvikling F11: Rekursjon 11. mars 2003 Problem - uendelig rekursjon Som uendelig løkke i et iterativt program Programmet kaller seg selv uten å nå basistilfellet som stopper rekursjonen 2 muligheter: –det finnes ikke noe basistilfelle –basistilfellet treffes aldri Det siste tilfellet kan inntre pga at mengden verdier som programmet kalles med, er større enn det var utformet for Det kan altså skyldes dårlig dokumentasjon

35 35 INFO231: Programutvikling F11: Rekursjon 11. mars 2003 Oppsummering rekursjon er viktig og hyppig en rekursiv løsning kombinerer løsning av delproblem for å løse totalproblemet delproblem løses ved –rekursive kall –løsning av et basistilfelle rekursive løsninger på problem kan være enkle og elegante - eks.: Tower of Hanoi

36 36 INFO231: Programutvikling F11: Rekursjon 11. mars 2003 Eksamensoppgave H-01 public int rek(int x) { if (x > 0) x = x + rek (x – 2); else x = 0; return x; } Hvilket resultat gir int y = rek(6); ????

37 37 INFO231: Programutvikling F11: Rekursjon 11. mars 2003 Kompleksitet Hvordan sammenligne to implementasjoner av samme ADT –Ta tiden og sammenligne? Algoritmer sammenlignes etter kompleksiteten Analyse av en algoritme –Teknikk for å karakterisere utførelsen (hastigheten) av en algoritme uavhengig av plattform, kompilator, og språk.

38 38 INFO231: Programutvikling F11: Rekursjon 11. mars 2003 Kompleksitet Algoritmer sammenlignes etter kompleksiteten til algoritmene Kompleksiteten av en algoritme karakteriserer kjøretiden av algoritmen ettersom input verdiene vokser Ignore konstanter i kompleksiteten –Eks. Søk i en liste »hver sammenligning er konstant »maks n sammenligninger, hvor n er størrelsen på listen Notasjon kompleksitet (kjøretid,utførelsetid) –Big-Oh notasjon »O(1) »O(n) »O(n^2) »O(log n)

39 39 INFO231: Programutvikling F11: Rekursjon 11. mars 2003 Kompleksitet Konstant tid public class Card { private int s; private int r; Card (int is, int ir) { s = is; r = ir; } public int suit() { return s; } public int rank() { return r; } public Color color () { if ((suit() == diamond) || (suit() == heart)) return Color.red; else return Color.black; }

40 40 INFO231: Programutvikling F11: Rekursjon 11. mars 2003 Løkke void bubbleSort (int [ ] v){ …… // move large values to the top for (int j = 0; j < i; j++) { if (v[j] > v[j+1]) { // ikke sortert double temp = v[j]; // bytt om v[j] = v[j + 1]; v[j + 1] = temp; } … Kompleksitet ? 1 4 3 8 2 8 4 v temp.. 0 1 2 3 4 i-1

41 41 INFO231: Programutvikling F11: Rekursjon 11. mars 2003 Løkke fortsettelse int binarySearch(int [] data, int testValue){ int low=0; int high=data.length; int mid=0; while (low<high){ mid=(low+high)/2; if (data[mid]< testValue) low=mid+1; else high=mid; } return low; } 1 2 3 4 5 data testValue 6 7 8 9 10 0 1 2 3 4 7

42 42 INFO231: Programutvikling F11: Rekursjon 11. mars 2003 1 2 3 4 5 data testValue 6 7 8 9 10 0 1 2 3 4 9 7 5 6 7 8 mid low high 1 2 3 4 5 data 6 7 8 9 10 0 1 2 3 4 9 5 6 7 8 low high 1 2 3 4 5 data 6 7 8 9 10 0 1 2 3 4 9 5 6 7 8 mid low high 1 2 3 4 5 data 6 7 8 9 10 0 1 2 3 4 9 5 6 7 8 mid low high

43 43 INFO231: Programutvikling F11: Rekursjon 11. mars 2003 Logaritmer Kompleksitet binarySearch? –deler søkemengden i to for hver iterasjon log funksjon –log (n) av x: tilnærmet lik antall ganger x kan bli delt opp i n –log (2) av x: tilnærmet lik antall ganger x kan bli delt i to log funksjoner er som oftest brukt med base 2 i ved bestemmelse av kompleksitet Verste tilfelle kontra beste tilfelle Bruk kjøretid, benchmark når bigOh er lik

44 44 INFO231: Programutvikling F11: Rekursjon 11. mars 2003 Kompleksitet Kompleksitet til et funksjonskall –kompleksiteten til funksjonen Kompleksitet av en algorime –summere kompleksiteten til hver del i algoritmen »(n^2+n), den største verdien dominerer (n^2) Viktig med raske algoritmer –Eksempel: Søk etter DNA »i tabell O(m*n^2), matrise O(m*nlogn), Hash (m*n) Bruk kjøretid, benchmark når bigOh er lik


Laste ned ppt "1 INFO231: Programutvikling F11: Rekursjon 11. mars 2003 INFO231 – Programutvikling Rekursjon."

Liknende presentasjoner


Annonser fra Google