2. Játék (Hanoi tornyok)
Adott három oszlop. Az első oszlopon található n darab
korong, oly módón, hogy az alsó átmérője mindig nagyobb a
rajta levő korongon. Helyezzük át a korongokat a harmadikk
oszlopra a második oszlop segítségével, oly módon, hogy
mindig az alsó korong legyen nagyobb átmérőjű.
http://www.youtube.com/watch?v=aGlt2G-DC8c
N=3 esetén
a. b. c.
3. Példák
1. Az aranyhal és a három kívánság: az első (valami...), a
első
második (valami...), a harmadik: „teljesítsd még három
kívánságomat”.
kívánságomat”.
2. A matematikában, egy fogalmat rekurzív módon
definiálunk, ha a definíción belül felhasználjuk magát a
definiálandó fogalmat.
fogalmat.
Például, a faktoriális rekurzív definícióját egy adott n szám
esetében, a matematikus így fejezi ki:
1, ha n = 0
n!=
n ⋅(n − 1)! ha n ∈ N*
,
4. Rekurzió, Definició
• Egy értéket vagy egy állapotot úgy definiálunk,
hogy definiáljuk a kezdőállapotot, majd általában
egy állapotot az előző véges számú állapot
segítségével határozzunk meg.
Koch
http://hu.wikipedia.org/wiki/Rekurzió
http://hu.wikipedia.org/wiki/Koch-görbe
5. A rekurzió célja
• A feladat visszavezetése egy még egyszerűbb
feladatra egészen addig amíg a feladat olyan
egyszerű nem lesz, hogy már megoldható.
• Más szóval: a feladat megfogalmazása mindig
ugyanaz, így az alprogram önmagát hívja de
egyre egyszerűbb argumentummal
• Előnye: az elegancia. Néhány sorban könnyen
érthető kódot írhatunk
• Hátránya: Akkor is használjuk ha kevéssé
hatékony, sőt pazarló
6. A programozásban a rekurzió alprogramok
formájában jelenik meg, éspedig olyan
függvényeket, illetve eljárásokat nevezünk
rekurzívaknak, amelyek meghívják önmagukat.
önmagukat.
Tehát, egy alprogramot akkor nevezünk
rekurzívnak, ha meghívja önmagát.
Típusai:
1. Közvetlen:
2. Közvetett:
7. Közvetlen rekurzió
(1) (2) (n)
P ....
P P P ⇒ Stack
overflow
a P eljárás a P eljárás a P eljárás n.
első második meghívása
meghívása
•A P rekurzív eljárás végrehajtása következtében a
P ismételten válik aktívvá.
•Minden aktiválás eredményeként a verembe kerül
valamennyi, a hívást jelölő adat.
adat.
•Mivel a verem mérete véges, bizonyos számú aktiválás
véges, szá
után bekövetkezhet a túlcsordulás és a program
hibaüzenettel (Stack overflow) kilép.
(Stack overflow)
8. Mivel ezt a hibát feltétlenül el kell kerülnünk, a P
eljárást csak egy bizonyos feltétel ellenében
szabad újra meg újra meghívni. Legyen F az a
meghívni.
feltétel, amelynek igaz értéke esetén a P eljárás
meghívhatja önmagát. Az önmeghívás
legegyszerűbb
legegyszerűbb alakja:
if F then P
F = true F = true
(1) (2) (3) (4) (5)
P if F then P if F then P if F then P (6)
(11) (9) (8) (7) {itt F =false}
(10)
a P eljárás első a P eljárás a P eljárás
aktíválása második harmadik
aktíválása aktíválása
9. Feladatok
• Írjuk meg a n!-t kiszámító rekurzív alprogramot.
• http://w3.enternet.hu/furedi/page2nd.html#fl_rekurzio
var n:Byte; Leállási feltétel
kezdőállapot
Function Fakt(n:Byte):longint;
Fakt(n:Byte):longint;
begin
if n=0 then Fakt:=1
else Fakt:=n*Fakt(n-1);
Fakt:=n*Fakt(n-1);
előző véges
end; számú állapot
Begin
Write('n='); ReadLn(n);
WriteLn(n,'!=',Fakt(n));
WriteLn(n,'!=',Fakt(n));
ReadLn
End.
11. Lépések száma (explicit
meghatározás)
Korongok száma Lépések száma Szabály
1 1 21-1
2 3 22-1
3 7 23-1
4 15 24-1
5 31 25-1
n ???? 2n-1
64 korong esetén, ha egy korong mozgatása 1
másodpercbe telik , akkor a korongok áthelyezése 264-1
másodperc, ami 590,000,000,000 évnek felel meg
12. n korongot helyezzünk át az
Hanoi tornyok
első oszlopról a második
segítségével a harmadikra.
Megállási feltétel
Procedure Hanoi(n,a,b,c:integer);
Begin n-1 korongot helyezzünk át
if n>0 then begin az első oszlopról a
harmadik segítségével a
Hanoi(n-1,a,c,b); másodikra.
Writeln(n,'. korongot ',a,'. rúdról ',c,'. rúdra!');
Hanoi(n-1,b,a,c);
end; n-1 korongot helyezzünk át
az második oszlopról az
End; első segítségével a
harmadikra.
Var n:integer;
begin
write('a korongok szama:');
readln(n);
hanoi(n,1,2,3);
end.