Feladat: A ‘Backtrack’ rekurzív
átiratának elkészítése.
Alábbiakban a backtrack
iskolapéldáját demonstráló program egy jellemző részletét adjuk meg iteratívan.
Mielőtt elemezné, lássa működés közben: VEZERDEMO.EXE.
Program
N_Vezer{Iteratív backtrack};
Const MaxN = 10;
Type
MIndex= -1..MaxN+1;
Hol
= Array [1..MaxN] of Index;
Var
Vezer:Hol; i:MIndex; N,j,hova:Index; lehet:Boolean;
{$I Vezer.inc}
Function Uti(vx1,vy1, vx2,vy2: Index):
Boolean;
Begin
Uti:=(vy1=vy2) or
(Abs(vy1-vy2)=vx1-vx2)
End; {Uti}
Function RosszEset(x,y: Index):
Boolean;
Var
j: Index;
Begin
j:=1;
While (j<=x-1) and not uti(x,y,
j,Vezer[j]) do Inc(j);
RosszEset:=j<=x-1
End;
Procedure VanJoEset(i: Index; Var talan: Boolean; Var ide: Index);
Begin
ide:=Vezer[i]+1;
While (ide<=N) and
RosszEset(i,ide) do Inc(ide);
talan:=ide<=N;
End;
Procedure BackTrack;
Begin
i:=1;
For j:=1 to N do
Vezer[j]:=0;
While i in [1..N] do
Begin
VanJoEset(i,lehet,hova);
If lehet then
Begin
Vezer[i]:=hova; Inc(i);
End
else
Begin
Vezer[i]:=0; Dec(i);
End;
End;
If i>0 then VanMegoldas(N)
else NincsMegoldas(N);
End;
Begin
Inicializalas(N);
BackTrack;
End.
Az unos-untig használt sablon a következő (’Keresés’) tétel átalakítása alapján könnyen megérthető:
Iteratív |
Rekurzív |
Eljárás Keres(Konstans
x:TSorozat;
i:=1 |
A ciklust jobbrekurzióvá alakíthatjuk, miután különválasztottuk (egy önálló eljárásba) az „előkétől” és az „utókától”. Az eredeti eljárás paraméterei közül elegendő azokat „átvinni” a rekurzív eljárás paraméterei közé, amelyektől a ciklus valójában függ. Gondoskodni kell arról, hogy az utóka is a megfelelő információt megkapja. Erre sok mód lehet. Most a legkézenfekvőbbet választjuk: legyen a rekurzív tevékenység egy index értékű függvény. Eljárás Keres(Konstans
x:TSorozat; i:=1 A ciklus jobbrekurzívvá alakítása: Függvény KeresR(Konstans
i:Egész, |