De presentatie wordt gedownload. Even geduld aub

De presentatie wordt gedownload. Even geduld aub

Recursieve Datastructuren

Verwante presentaties


Presentatie over: "Recursieve Datastructuren"— Transcript van de presentatie:

1 Recursieve Datastructuren
Inductie !! Om recursie te begrijpen moeten we eerste recursie begrijpen. Het beschrijven van een begrip in termen van zichzelf Klassiek voorbeeld: Recursieve methode faculteit int faculteit( int n ) { if ( n == 1 ) { return 1; } else { return n * faculteit( n-1 ); } Base Case

2 Recursieve Datastructuren
Recursie als problem solver Torens van Hanoi Kennis van het probleem Mooie code. public void move( int n, Toren a, Toren b, Toren c ) { if ( n > 0 ) { // there is some to move move ( n - 1, a, c, b ); // move all but one to c b.add( a.remove() ); // move last tot b move ( n - 1, c, b, a ); // move all from c to b } // else done } A C B

3 Recursieve Datastructuren
Torens van Hanoi: aantal benodigde stappen H voor N stenen geeft rij H0 = 0, H1 = 1, H2 = 3, H3 = (0,1,3,7….) Recurente betrekking H0 = 0 Hn = 2 * Hn voor n > 0 Zie ook faculteit: (zie ook code) f0 = 1 fn = n * fac( n-1 ) Of Fibonacci (oefening)

4 Recursieve Datastructuren
Fibonacci Het ‘konijnenrijtje’ gaf de oplossing voor een probleempje dat Fibonacci in 1202 formuleerde: Een boer koopt op de markt in Pisa twee jonge konijnen: een mannetje en een vrouwtje. De eerste maand brengt dit stel nog geen kleintjes voort, maar na de tweede maand worden de eerste twee konijnen geboren: een mannetje en een vrouwtje. Gedurende de daaropvolgende maanden brengt dit eerste stel konijnen steeds twee konijnen van verschillend geslacht ter wereld. Maar ook de nakomelingen van dit stel gaan, nadat ze een maand oud zijn, zich voortplanten en brengen elke maand een stel konijnen ter wereld. Het Fibonaccirijtje geeft aan hoeveel konijnenparen de boer in de opeenvolgende maanden heeft, als er vanuit wordt gegaan dat geen enkel stel doodgaat

5 Recursieve Datastructuren
Fractals (Mandelbrot) Berekendn door recursie bv Koch’s sneeuwvlok: // deel van de vlok public void drawLine( Graphics g, int x0, int y0, int x1, int y1, int level) { //System.out.println("Draw ("+ ++count +") at depth "+level); g.drawLine( x0,y0, x1,y1 ); if ( level > 0 ) { int xa = x0 + (x1-x0)/3; int ya = y0 + (y1-y0)/3; int xb = x1 - (x1-x0)/3; int yb = y1 - (y1-y0)/3; int xc = x0 + (x1-x0)/2 - (y1 - y0)/3; int yc = y0 + (y1-y0)/2 + (x1 - x0)/3; drawLine(g, x0,y0, xa,ya, level-1); drawLine(g, xa,ya, xc,yc, level-1 ); drawLine(g, xc,yc, xb,yb, level-1 ); drawLine(g, xb,yb, x1,y1, level-1 ); } Koch’s sneeuwvlok “Mandelbrot”

6 Recursieve Datastructuren
Recursieve Objecten Aanroep zelfde methode, ander object van zelfde type Gebruikt bij lijsten, bomen en grafen. Recursieve lijst (met Sentinel) RecList RecList RecList Sentinel public int size() { int size = 0; if (! isSentinel() ) { size = 1 + next.size(); } return size; “E” “B” “G”

7 Recursieve Datastructuren
Recursieve lijst: add(“F”) Plaats object in sentinel, nieuwe sentinal RecList RecList RecList RecList “F” “E” “B” “G” RecList RecList RecList RecList RecList “E” “B” “G” “F”

8 Recursieve Datastructuren
Recursieve lijst: addAfter(“B”, “F”) Plaats object in sentinel, nieuwe sentinal RecList RecList RecList RecList “E” “B” “F” “G” RecList RecList RecList RecList RecList “E” “B” “G” “F”

9 Recursieve Datastructuren
Recursieve lijst: remove(“B”) Verwijder volgende RecList ipv huidige RecList RecList RecList RecList “E” “B” “G” RecList RecList RecList RecList “E” “B” “G”

10 Recursieve Datastructuren
Recursieve Boom (TreeMap) Gesorteerd met (Comparabel)key en value Zoeksnelheid : 2log n ipv n/2 public int size() { int size = 0; if ( ! isSentinel() ) { size = 1 + left.size() + right.size(); } return size; public V get( K aKey) { V found = null; int compare = key.compareTo( aKey ); if ( compare == 0 ) { found = value; } else if ( compare > 0 ) { left.get( aKey ); } else { right.get( aKey ); return found; “G” “D” “S” “A” “K” “U”

11 Recursieve Datastructuren
Recursieve Boom (TreeMap) Key moet Comparable (methode compareTo) zijn, kun je afdwingen met Generics ! public class TreeMap<K extends Comparable<K>, V> {…} TreeMap<String, Iets> tree put(“E”, iets); put(“Z”, ietsAnders); tree “G” left right “D” “S” “A” “K” “U” “E” “Z”

12 Recursieve Datastructuren
Recursieve Boom (TreeMap) remove(“S”) -> opzoeken -> gat opvullen met left.largest -> largest removen tree tree “G” “G” left right left right “D” “S” “D” “L” “A” “E” “K” “U” “A” “E” “K” “U” right.smallest() “L” left.largest() Wordt sentinel

13 Recursieve Datastructuren
Recursieve Boom als lijst Inorder: ((A)D(E))G((K(L))S(U)) Preorder: G(D(A)(E))(S(K(L))(U)) Postorder: ((A)(E)D)(((L)K)(U)S)G tree “G” left right “D” “S” “A” “E” “K” “U” “L”

14 Recursieve Datastructuren
Recursieve Boom groeit scheef ! Sneller zoeken bij balans ofwel minder hoogte Balanseren na put en remove ! Weight Balanced (duur) Swimlane RD.1: WBSTree Implementeren Testen Meten tov java.util.TreeMap AVL (todo?) RedBlack (todo?) tree “G” left right “D” “S” “A” “E” “K” “U” “L”

15 Recursieve Datastructuren
Torens van Hanoi in H stappen Verplaats een voor een de stenen van pilaar 1 naar pilaar 3m, eventueel via pilaar 2. Er mag telkens maar èèn steen tegelijk verplaatst worden en nooit een grotere op een kleinere steen. Hoeveel stappen heb je nodig: mbv recurrente betrekking: H0 = 0 Hn = 2*Hn-1+1 voor n > 0 Vermoeden: Hn = 2n -1: bewijs mbv volledige inductie public void move( int n, T a, T b, T c ) { if ( n > 0 ) { // there is some to move move ( n - 1, a, c, b ); // all but one to c b.add( a.remove() ); // move last tot b move ( n - 1, c, b, a ); // all from c to b } // else done }

16 Recursieve Datastructuren
Torens van Hanoi in H stappen Recurrente betrekking: H0 = 0 Hn = 2*Hn-1+1 voor n ≥ 0 Vermoeden: Hn = 2n -1: bewijs mbv volledige inductie Voor n = 0 geldt: H0 = 0 en = 1 – 1 = 0 Stel: Hn = 2n – 1 voor k ≥ 0 => Hn+1 = 2*Hn+1 = 2*(2n–1)+1 = 2n+1–2+1 = 2n+1-1 Bewijs: Hn = 2n-1 voor elke n ≥ 0

17 Recursieve Datastructuren
Wiskundig Intermezzo Rijen, Reeksen Rekenkundige rij: is van de vorm: a0 = a an = an-1 + v voor n > 0 Voorbeeld: a0 = 2, v = 3 an = an voor n > 0 Dit is de rij 2, 5, 8, 11, 14, 17, … met expliciete definitie: an = 2 + n*3 voor n = 0, 1, 2, … Merk op: bij een rekenkundige rij is het verschil tussen twee opeenvolgende getallen constant

18 Recursieve Datastructuren
Wiskundig Intermezzo Rijen, Reeksen Rekenkundige reeks: is de som van de termen van een rekenkundige rij: … = ? … = ? Oplossing van Gauss: … … … + 101 100 = … = 100 * 101/2 = 5050 i= 1 n Algemeen: (a+iv) = a+(a+v)+(a+2v)+…+(a+nv) = ½ (2a+nv)(n+1) i=0

19 Recursieve Datastructuren
Wiskundig Intermezzo Rijen, Reeksen Meetkundige rij is in de vorm: a0 = a an = r* an-1 voor n > 0 (r heet ‘reden’) Voorbeeld: a0 = 2 an = 3*an-1 voor n > 0 (reden = 3) Dit is de rij: 2, 6, 18, 54, 162 …. met expliciete definitie: an = 2*3n voor n = 0,1,2 …. Bij een meetkundige rij is het quotiënt van de twee opeenvolgende getallen constant !

20 Recursieve Datastructuren
Wiskundig Intermezzo Rijen, Reeksen Meetkundige reeks is de som van de termen van een meetkundige rij Sn = a+ar+ar2+ar arn Er geldt Sn = a+ar+ar2+ar3+...arn r*Sn = ar+ar2+ar3+...arn+arn+1 - Sn –r*Sn= a arn+1 ofwel: (1-r)*Sn = a*(1 - rn+1) Dus als r ≠ 1 => Sn = a*(1 - rn+1) / (1- r) n a*ri = a*(1-rn+1) / (1 – r) i=0

21 Recursieve Datastructuren
Grafen het probleem van Köngsberg Leonard Euler gebruikte een graaf (1736).

22 Recursieve Datastructuren
Grafen Graaf: Knopen(vertices) verbonden met buurknopen door zijden(edges) Toepassing: Routeplanners Computer netwerken Informatiesystemen Proplem solving (doolhof, project planning, pathfinding…. etc Verbindingsmatrix (r->c)

23 Recursieve Datastructuren
Grafen, varianten Enkelvoudige graaf Meervoudige graaf (E/M) Gerichte graaf (E/M, G) Gewogen graaf EIN MAS AMS RTM

24 Recursieve Datastructuren
Grafen, doorzoeken Depth first Voor elke buur bezoek buur bezoek diens buren Breath first Elke buur in queue Voor elke buur in queue bezoek buur diens buren in queue

25 Recursieve Datastructuren
Grafen, Depth first Start bij knoop 1 bezoek ( knoop ) { doe iets markeer knoop als bezocht // cycle detection (sync) voor elke buurknoop { als buurknoop niet bezocht bezoek (buurknoop ) }

26 Recursieve Datastructuren
Grafen, Breath first Start bij knoop 1 maak wachtrij plaats startknoop in wachtrij zolang knopen in wachtrij { haal knoop uit wachtrij doe iets met knoop voor elke buurknoop { als buurknoop niet bezocht plaats buurknoop in wachtrij markeer buurknoop als geplaatst }

27 Recursieve Datastructuren
Virtuele Grafen, Kannengiet probleem Definieer toestand (2 kannen) bv (8,5) Vanuit ene toestand (0,0) naar andere (8,0) Elke toestand is een knoop Buurknopen conform spelregels Let op cycles Vind ik het kortste pad ?? Demo …..

28 Recursieve Datastructuren
Virtuele Grafen, Kannengiet probleem Definieer toestand (2 kannen) bv (8,5) Vanuit ene toestand (0,0) naar andere (8,0) public class Situation { private int largeVolume; private int smallVolume; public Situation( int aLargeVolume, int aSmallVolume ) { largeVolume = aLargeVolume; smallVolume = aSmallVolume; } public int getLargeVolume() { return largeVolume; public int getSmallVolume() { return smallVolume; public boolean equals( Object other ) { assert other instanceof Situation: “Must be Situation"; Situation situation = (Situation)other; return largeVolume == situation.largeVolume && smallVolume == situation.smallVolume; public String toString() { return "("+largeVolume+","+smallVolume+")";

29 Recursieve Datastructuren
Virtuele Grafen, Kannengiet probleem Probeer alle toestanden Depth first public boolean solve() { List<Situation> visited = new ArrayList<Situation>(); Situation start = new Situation( 0, 0 ); return solve( start, visited ); } public boolean solve( Situation situation, List<Situation> visited ) { boolean finished = isFinished( situation ); visited.add( situation ); // mark visited if ( finished ) { System.out.println("Finished : "+ situation); } else { List<Situation> neighbours = getPosibilities( situation ); for ( Situation neighbour: neighbours ) { if ( ! visited.contains( neighbour ) ) { finished = solve( neighbour, visited ); if ( finished ){ break; System.out.println( "->"+situation ); // shortest path? return finished;

30 Recursieve Datastructuren
public List<Situation> getPosibilities( Situation from ) { int largeVolume = from.getLargeVolume(); int smallVolume = from.getSmallVolume(); List<Situation> situations = new ArrayList<Situation>(); // make large empty situations.add( new Situation( 0, smallVolume ) ); // make small empty situations.add( new Situation( largeVolume, 0 ) ); // make large full situations.add( new Situation( LARGE, smallVolume ) ); // make small full situations.add( new Situation( largeVolume, SMALL ) ); // pour large to small if ( largeVolume < SMALL-smallVolume ) { situations.add( new Situation( 0, smallVolume+largeVolume ) ); } else { situations.add( new Situation( largeVolume-(SMALL-smallVolume), SMALL ) ); } // pour small to large if ( smallVolume < LARGE-largeVolume ) { situations.add( new Situation( largeVolume+smallVolume, 0 ) ); situations.add( new Situation( LARGE, smallVolume-(LARGE-largeVolume) ) ); return situations; Virtuele Grafen, Kannengiet probleem Achterhaal de buren !

31 Recursieve Datastructuren
Grafen en problem solving, Oefening: maak gewogen, gerichte graaf (deadline 22 dec) te gebruiken in Swimlane RDS.2 Puzzeldoolhof Deadline 12 januari


Download ppt "Recursieve Datastructuren"

Verwante presentaties


Ads door Google