1 / 47

Iteracije in rekurzija

Iteracije in rekurzija. Mehanizmi krmiljenja poteka. Zaporedno izvajanje ( prednost izvedbe izrazov) Izbira (Selection) Iteracije Proceduralna abstrakcija Rekurzija Konkurenčnost Nedeterminizem.

adler
Download Presentation

Iteracije in rekurzija

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Iteracije in rekurzija

  2. Mehanizmi krmiljenja poteka • Zaporedno izvajanje ( prednost izvedbe izrazov) • Izbira (Selection) • Iteracije • Proceduralna abstrakcija • Rekurzija • Konkurenčnost • Nedeterminizem • Ta dva krmilna mehanizma dovolita računalniku ponavljanje izvajanja iste množice operacij • Imperativni jeziki v glavnem temeljijo na iteracijah • Funkcionalni jeziki v glavnem temeljijo na rekurziji.

  3. Kaj je iteracija? Iteracija v računalništvu je ponavljanje procesa v računalniškem programu. Pri tem se neko stanje spreminja. Iteracija pomeni stil programiranja v imperativnih programskih jezikih. V nasprotju s tem ima rekurzija bolj deklarativni pristop. Primer iteracije, opisan v imperativni psevdokodi: var i, a := 0 // initialize a before iteration for i from 1 to 3 { // loop three times a := a + i // increment a by the current value of i } print a // the number 6 is printed

  4. Iteracije • Iteracija ima običajno obliko zanke • •Dve osnovni obliki: • • Iteracija preko oštevilčenih množic. • • Iteracijo krmilimo z logiko (dokler ni izpolnjen nek pogoj) Primeri:

  5. Fibonaccijeva števila tvorijo naslednje zaporedje Definiramo jih lahko tudi rekurzivno:fib(1) = 1 fib(2) = 1 fib(n) = fib(n – 1) + (fib(n – 2)za n > 2 To zaporedje je znano tudi kot problem množečih se zajčkov Primer: Fibonaccijeva števila n 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,... 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, … WEB

  6. Primer: igra življenja • Za vsak prostor, ki je “naseljen”’: • Vsaka celica z enim ali nič sosedi umre zaradi osamljenosti. • Vsaka celica s 4 ali več sosedi umre zaradi prenaseljenosti. • Vsaka celica z 2 ali 3 sosedi preživi. • Za vsak prazen (“nenaseljen” )prostor: • Vsaka celica s tremi sosedi postane naseljena. DEMO

  7. Primer: plenilci in plen V danem področju imamo množico plenilcev (na primer lisic) in množico plenov (na primer zajčkov). Če ni plenilcev, se zajčki preveč razmnožijo. Če ni plena, plenilci stradajo in izumrejo. Ob dani začetni populaciji uporabimo diferenčne enačbe za simulacijo razvoja obeh populacij. Na primer : Ln+1 = Ln+ (c*Zn- d)* Ln; Zn+1= Zn+ (f- g* Ln)*Zn; L so lisice, Z so zajci. c, d,f, g so parametri . Nastavi začetne vrednosti populacij na Z0 inL0

  8. Populacija Lisic in zajcev WEB

  9. Lisice in zajci : koda zajcevPrej = 100; lisicPrej = 100; // zacetna populacija // c,d,f,g so parametri, ki jih moramo nastaviti for (time = tMin; time <= tMax; time += stepSize) { lisic = lisicPrej + (c*zajcevPrej - d)* lisicPrej; zajcev = zajcevPrej + (f- g* lisicPrej) * zajcevPrej; // zajcev oziroma lisic ne more biti manj kot nek minimum if (.lisic<10) lisic = 10; if (zajcev<10) zajcev=10; // priprava na nasledno iteracijo zajcevPrej = zajcev; lisicPrej = lisic; } Demo

  10. Še en primer plenilcev in plena http://darwin.wcupa.edu/beneski/projects/webplots/applets/agent-pred-prey/webx-pp.html

  11. Primeri rekurzije

  12. Rekurzija Do rekurzije pride, če metoda kliče samo sebe, direktno ali indirektno preko verige klicev drugih metod. Metoda, ki kliče samo sebe, je rekurzivna metoda.

  13. Primer: Izpis niza void print(String str, int index){ if (index < str.length()){ System.out.print(str.charAt(index)); print(str, index + 1); } } print("Hello", 0); print("Hello", 1); print("Hello", 2); print("Hello", 3); print("Hello", 4); print("Hello", 5); return return return return return return H e l l o DEMO

  14. Primer s potenco Definicija potence je Xy = 1* X * X *…* X (y krat) Zamislimo si, da bi to morali računati ročno: X = 1* X * X *…* X (y krat)Kaj, če je y velik? Leni pristop: Imejmo asistenta, ki bo izračunal X y-1 in rezultat je = X * Xy-1 Imejmo asistenta, ki bo izračunal X y-2 Imejmo asistenta, ki bo izračunal X y-3 ….. do X0

  15. Rekurzivno računanje potence • Postopek naj bo naslednji: • Za izračun potence x na y • Če je y enak 0, ni kaj množiti, rezultat je 1. • Če je y večji od 0, tedaj • Prosimo asistenta, da izračuna potenco x na y-1. • Rezultat je x krat rezultat asistenta.

  16. Rekurzivna metoda private int potenca(int x, int y) { // y>=0, returns x**y int rezultatAsistenta; if (y==0) return 1; else { rezultatAsistenta = potenca(x,y-1); return x*rezultatAsistenta; } } Korak prekinitve mora biti pred rekurzivnim klicem Preveri, če lahko postopek zaključimo brez rekurzije. Rekurzivni klic Argumenti v rekurzivnem klicu morajo določati nalogo, ki je lažja ali manjša od naloge, ki jo je zahteval klicatelj.

  17. Sledenje klica : int z = factorial(4) Vrne 3*2 = 6 in konča factorial(3)= 3 * factorial(2) Vrne 2*1 =2 In konča factorial(2)= 2 * factorial(1) factorial(1)= 1 * factorial(0) Vrne 1*1 In konča Osnovni primer: factorial(0)= 1 Vrne 1 In konča factorial(4)= 4 * factorial(3) factorial(4) končno lahko izračuna 4*6, vrne 24 in konča WEB

  18. Lastnosti rekurzivnih metod • Vse rekurzivne metode imajo naslednje lastnosti: • Enega ali več osnovnih primerov (najbolj enostavni primer), ki ga uporabimo za prekinitev rekurzije. • Vsak rekurzivni klic mora originalni problem poenostaviti tako, da bo postopoma bližje osnovnemu primeru, dokler se s tem osnovnim primerom ne izenači.

  19. Kako načrtujemo rekurzivne metode • Korak 1. Bodimo leni. • Uporabimo rešitev manjše ali lažje verzije problema in z njeno pomočjo rešimo naš problem. • Ta korak vodi v rekurzivni klic. • Korak 2. Vedeti, kdaj moramo nehati. • Vedeti moramo, kdaj je problem tako enostaven, da ga lahko rešimo direktno. • Ta korak vodi v kodo prekinitve.

  20. Primer: inverzija niza Funkcija vrne niz, v katerem so znaki pomnjeni v obratnem vrstnem redu. If there are no more characters to examine Return the empty string Else Reverse the rest of the string after the current char Return the concatenation of this result and the char at the current position String reverse(String str, int index){ if (index == str.length()) return ""; else{ String rest = reverse(str, index + 1); return rest + str.charAt(index); } }

  21. Inverzija niza String reverse(String str, int index){ if (index == str.length()) return ""; else{ String rest = reverse(str, index + 1); return rest + str.charAt(index); } } H e l l o reverse("Hello", 0); reverse("Hello", 1); reverse("Hello", 2); reverse("Hello", 3); reverse("Hello", 4); reverse("Hello", 5); Return "" Return "o" Return "ol" Return "oll" Return "olle" Return "olleH"

  22. Inverzija niza String reverse(String str, int index){ if (index == str.length()) return ""; else{ String rest = reverse(str, index + 1); return rest + str.charAt(index); } } H e l l o reverse("Hello", 0); reverse("Hello", 1); reverse("Hello", 2); reverse("Hello", 3); reverse("Hello", 4); reverse("Hello", 5); Return "" Return "o" Return "ol" Return "oll" Return "olle" Return "olleH"

  23. Inverzija niza String reverse(String str, int index){ if (index == str.length()) return ""; else{ String rest = reverse(str, index + 1); return rest + str.charAt(index); } } H e l l o reverse("Hello", 0); reverse("Hello", 1); reverse("Hello", 2); reverse("Hello", 3); reverse("Hello", 4); reverse("Hello", 5); Return "" Return "o" Return "ol" Return "oll" Return "olle" Return "olleH"

  24. Inverzija niza String reverse(String str, int index){ if (index == str.length()) return ""; else{ String rest = reverse(str, index + 1); return rest + str.charAt(index); } } H e l l o reverse("Hello", 0); reverse("Hello", 1); reverse("Hello", 2); reverse("Hello", 3); reverse("Hello", 4); reverse("Hello", 5); Return "" Return "o" Return "ol" Return "oll" Return "olle" Return "olleH"

  25. Inverzija niza String reverse(String str, int index){ if (index == str.length()) return ""; else{ String rest = reverse(str, index + 1); return rest + str.charAt(index); } } H e l l o reverse("Hello", 0); reverse("Hello", 1); reverse("Hello", 2); reverse("Hello", 3); reverse("Hello", 4); reverse("Hello", 5); Return "" Return "o" Return "ol" Return "oll" Return "olle" Return "olleH"

  26. Inverzija niza String reverse(String str, int index){ if (index == str.length()) return ""; else{ String rest = reverse(str, index + 1); return rest + str.charAt(index); } } H e l l o reverse("Hello", 0); reverse("Hello", 1); reverse("Hello", 2); reverse("Hello", 3); reverse("Hello", 4); reverse("Hello", 5); Return "" Return "o" Return "ol" Return "oll" Return "olle" Return "olleH"

  27. Inverzija niza String reverse(String str, int index){ if (index == str.length()) return ""; else{ String rest = reverse(str, index + 1); return rest + str.charAt(index); } } H e l l o reverse("Hello", 0); reverse("Hello", 1); reverse("Hello", 2); reverse("Hello", 3); reverse("Hello", 4); reverse("Hello", 5); Return "" Return "o" Return "ol" Return "oll" Return "olle" Return "olleH"

  28. Inverzija niza String reverse(String str, int index){ if (index == str.length()) return ""; else{ String rest = reverse(str, index + 1); return rest + str.charAt(index); } } H e l l o reverse("Hello", 0); reverse("Hello", 1); reverse("Hello", 2); reverse("Hello", 3); reverse("Hello", 4); reverse("Hello", 5); Return "" Return "o" Return "ol" Return "oll" Return "olle" Return "olleH"

  29. Inverzija niza String reverse(String str, int index){ if (index == str.length()) return ""; else{ String rest = reverse(str, index + 1); return rest + str.charAt(index); } } H e l l o reverse("Hello", 0); reverse("Hello", 1); reverse("Hello", 2); reverse("Hello", 3); reverse("Hello", 4); reverse("Hello", 5); Return "" Return "o" Return "ol" Return "oll" Return "olle" Return "olleH"

  30. Inverzija niza String reverse(String str, int index){ if (index == str.length()) return ""; else{ String rest = reverse(str, index + 1); return rest + str.charAt(index); } } H e l l o reverse("Hello", 0); reverse("Hello", 1); reverse("Hello", 2); reverse("Hello", 3); reverse("Hello", 4); reverse("Hello", 5); Return "" Return "o" Return "ol" Return "oll" Return "olle" Return "olleH"

  31. Inverzija niza String reverse(String str, int index){ if (index == str.length()) return ""; else{ String rest = reverse(str, index + 1); return rest + str.charAt(index); } } H e l l o reverse("Hello", 0); reverse("Hello", 1); reverse("Hello", 2); reverse("Hello", 3); reverse("Hello", 4); reverse("Hello", 5); Return "" Return "o" Return "ol" Return "oll" Return "olle" Return "olleH"

  32. Inverzija niza String reverse(String str, int index){ if (index == str.length()) return ""; else{ String rest = reverse(str, index + 1); return rest + str.charAt(index); } } H e l l o reverse("Hello", 0); reverse("Hello", 1); reverse("Hello", 2); reverse("Hello", 3); reverse("Hello", 4); reverse("Hello", 5); Return "" Return "o" Return "ol" Return "oll" Return "olle" Return "olleH"

  33. Rekurzivno štetje kvadratkov v blobu A binary large object, also known as a blob, is a collection of binary data stored as a single entity Kliknemo na nek poln kvadratek. Blobu pripada ta kvadratek in Njegovi vodoravni in navpični sosedi Ter taki sosedi teh sosedov.

  34. Rekurzivno štetje kvadratkov v blobu (2) int getBlobSize(int r, int c) { // Counts the squares in the blob at position (r,c) in thegrid. Squares are only counted // if they are filled and unvisited. If this routine is called for a position that // has been visited, the return value will be zero. if (r < 0 || r >= rows || c < 0 || c >= columns) { // This position is not in the grid, so there isno blob at this position. return 0; } if (filled[r][c] == false || visited[r][c] == true) {// This square is not part of a blob, or else it hasalready been counted, so return zero. return 0; } visited[r][c] = true; // Mark the square as visited so that we won't count it again // during the following recursive calls to this method. int size = 1; // Count the square at this position, then count the the blobs //that are connected to this squarehorizontally or vertically. size += getBlobSize(r-1,c); size += getBlobSize(r+1,c); size += getBlobSize(r,c-1); size += getBlobSize(r,c+1); return size; } // end getBlobSize() DEMO

  35. Hanojski stolpiči • Problem s Hanojskimi stolpiči je klasičen rekurzivni problem, ki temelji na preprosti igri. Imamo tri palice. Na eni je sklad ploščic z različnimi premeri. • Cilj igre: Prestaviti vse ploščice na desno palico ob upoštevanju naslednjih pravil: • Nobena ploščica ne sme biti nikoli na vrhu manjše ploščice. • Naenkrat smemo premikati le po eno ploščico. • Vsako ploščico moramo vedno odložiti na eno od palic, nikoli ob strani. • Premaknemo lahko vedno le ploščico, ki je na vrhu nekega stolpiča. Zgodba pravi, da bi za fizičen premik 64 ploščic iz ene palice na drugo potrebovali toliko časa, da bi prej bil konec sveta. Demo

  36. N ploščic s stolpa 1 na stolp 3 Začetno stanje: Stolp 2 Stolp 3 Stolp 1 Cilj: Stolp 1 Stolp 2 Stolp 3

  37. Nekaj prvih korakov Premik n-1 ploščic Korak 1: Stolp 1 Stolp 2 Stolp 3 Korak 2: Premik 1 ploščice Stolp 3 Stolp 1 Stolp 2 Korak 3: Premik n-1 ploščic Stolp 1 Stolp 2 Stolp 3

  38. Koda v pascalu procedure Hanoi(n: integer; from, to, by: char); Begin if (n=1) then writeln('Move the plate from ', from, ' to ', to) else begin Hanoi(n-1, from, by, to); Hanoi(1, from, to, by); Hanoi(n-1, by, to, from); end; End;

  39. Koda v javi (bolj popolna) public class TowersOfHanoi { public static void main(String[] args) { moveDisks(3, "Tower 1", "Tower 3", "Tower 2"); } public static void moveDisks(int n, String fromTower, String toTower, String auxTower) { if (n == 1) System.out.println("Move disk " + n + " from " + fromTower + " to " + toTower); else { moveDisks(n-1, fromTower, auxTower, toTower); System.out.println("Move disk " + n + " from " + fromTower + " to " + toTower); moveDisks(n-1, auxTower, toTower, fromTower); } } } Move n-1 disks from from to temp, using to as a temporary. Move one disk from from to to. Move n-1 disks from temp to to, using from as a temporary. Demo

  40. Kakšen bi bil izpis Move disk 1 from Tower 1 to Tower 3 Move disk 2 from Tower 1 to Tower 2 Move disk 1 from Tower 3 to Tower 2 Move disk 3 from Tower 1 to Tower 3 Move disk 1 from Tower 2 to Tower 1 Move disk 2 from Tower 2 to Tower 3 Move disk 1 from Tower 1 to Tower 3

  41. Primer s fraktali Demo

  42. Preproga Sierpinski import java.applet.Applet; import java.awt.*; import java.awt.event.*; public class SierpinskiCarpet extends Applet { int level; public void init() { repaint(); } public synchronized void paint(Graphics g){ int i = getSize().width; int j = getSize().height; g.setColor(Color.white); g.fillRect(0, 0, i, j); level = 5; carpet(g, level, 0, 0, i, j); }

  43. Preproga Sierpinski (nadaljevanje) public void carpet(Graphics g, int i, int j, int k, int l, int i1){ if(i == 0) { g.setColor(Color.black); g.fillRect(j, k, l, i1); return; } else { int j1 = l / 3; int k1 = i1 / 3; carpet(g, i - 1, j, k, j1, k1); carpet(g, i - 1, j + j1, k, j1, k1); carpet(g, i - 1, j + 2 * j1, k, j1, k1); carpet(g, i - 1, j, k + k1, j1, k1); carpet(g, i - 1, j + 2 * j1, k + k1, j1, k1); carpet(g, i - 1, j, k + 2 * k1, j1, k1); carpet(g, i - 1, j + j1, k + 2 * k1, j1, k1); carpet(g, i - 1, j + 2 * j1, k + 2 * k1, j1, k1); return; } } }

  44. Iteracija Uporabljamo strukture ponavljanja (for, whilealido…while) Ponavljanje skozi eksplicitno uporabo struktur ponavljanja Konča se, ko pogoj za ponavljanje zanke ne velja več (običajno) ponavljanja krmilimo s števcem Rekurzija Uporabljamo strukture izbiranja(if, if…elsealiswitch) Ponavljanje skozi ponovne klice metod oziroma funkcij Konča se, ko je izpolnjen osnovni primer Ponavljanje krmilimo z deljenjem problema na bolj enostavnega Primerjava iteracija : rekurzija (1) Iterativni in rekurzivni izračun faktoriele n! Demo

  45. Še o rekurziji Terja več režije kot iteracija Je pomnilniško bolj zahtevna od iteracije Rekurzivne probleme lahko rešujemo tudi z iteracijami Pogosto nam za rekurzijo zadošča le nekaj vrstic kode Primerjava iteracija : rekurzija (2) Primeri

  46. Malo za sprostitev Podano je nekaj zaporedij. Ugotoviti moramo naslednje člene zašporedij. Vsak od navedenih problemov ima dva odgovora: eden je jasen, drugi pa bolj skrit. Problem A: 3, 1, 4, 1, 5, … Kateri je naslednji člen zaporedja? Problem B: 2, 3, 5, 8, … Kateri je naslednji člen zaporedja? Problem C: 2, 7, 1, 8, 2, 8, 1, 8, …Katera sta dva naslednja člena zaporedja? Odgovori A: preprosto =1; skrito =9; Odgovori B: preprosto =12; skrito =13; Odgovori C: preprosto =(2, 9); skrito =(2, 8);

  47. Nedeterministični konstrukti Nedeterminstični konstrukti namenoma ne specificirajo izbire med alternativami. •Ta mehanizem je posebno uporaben v konkurenčnih programih

More Related