7. Diamikus rogramozás 7.1. Rekurzió memorizálással. Láttuk, hogy a artíció robléma rekurzív algoritmusa Ω(2 ) eljáráshívást végez. edig a lehetséges részroblémák száma csak 2 (vagy ( + 1)/2, ha csak az k eseteket vesszük.) Eek az az oka, hogy ugyaazo részrobléma megoldása több más részobléma megoldásához kell, és az algoritmus ezeket midig újra kiszámítja. Tehát egyerűe gyorsíthatjuk a számítást, ha mide részrobléma (azaz P2(, k)) megoldását tároljuk egy tömbbe. Ha hivatkozuk egy részrobléma megoldására, akkor először elleőrizzük, hogy kiszámítottuk-e már, és ha ige, akkor kiolvassuk az értéket a táblázatból, egyebkét rekurzíva számítuk, és utáa tároljuk az értéket a táblázatba. A táblázat iicializálásához válasszuk egy olya értéket, amely em lehet egyetle részrobléma megoldása sem. Esetükbe ez lehet a 0. Program ParticoiRM; {A artíció robléma megoldása. Módszer: rekurzió memorizálással} Fuctio P(N:Word):It64; Cost MaxN=500; {a táblázat mérete MaxN*MaxN} T2:array[1..MaxN,1..MaxN] of It64;{a részroblémák táblázata} i,j:word; Fuctio P2(,k:Word):It64; E:It64; Begi{P2} If T2[,k]<>0 The {P2(,k) értékét már kiszámítottuk} P2:=T2[,k] Else Begi {P2(,k) értékét még em számítottuk ki} if ( = 1) Or (k = 1) The {rekurzív számítás} E := 1 Else If <= k The E := 1 + P2(,-1) Else E :=P2(,k-1) + P2(-k,k); T2[,k]:=E; {memorizálás} P2:=E; Ed; Ed{P2}; Begi{P} For i:=1 To N Do {a táblázat iicializálása} For j:=1 To N Do T2[i,j]:=0; P:=P2(,); Ed{P}; Begi{rogram} WriteL(P(100)); Ed{rogram}. Nyilvávaló, hogy az algoritmus futási ideje Θ( 2 ), és a tárigéye is Θ( 2 ) lesz, ha csak 2 méretű táblázatak foglaluk memóriát diamikusa az aktuális araméter függvéyébe. 1
7.2. A artíció robéma megoldása táblázatkitöltéssel. A rekurziót teljese kiküszöbölhetjük táblázatkitöltéssel. Az 1. árá szemléltetett táblázatot haszáljuk a részroblémák megoldásaiak tárolására. Tehát a T 2[, k] táblázatelem tartalmazza a P2(, k) részrobléma megoldását. A táblázat első sora azoal kitölthető, mert P2(, 1) = 1. Olya kitöltési sorredet keresük, hogy mide (, k), k > 1 részrobléma kiszámítása eseté azok a részroblémák, amelyek szükségesek P2(, k) kiszámításához, már korábba kiszámítottak legyeek. Általáosa, rekurzív összefüggéssel defiiált roblémamegoldás eseté egy r (rész)robléma összetevői azok a részroblémák, amelyek megoldásától r megoldása függ. Tehát a táblázatkitöltés alkalmazásához meg kell állaítai a részroblémákak egy olya sorredjét, hogy mide r részrobléma mide összetevője előbb álljo a sorredbe, mit r. A 1. P2(1,k) = 1, P2(,1) = 1, 2. P2(,) = 1 + P2(, 1), 3. P2(,k) = P2(,) ha < k, 4. P2(,k) = P2(,k 1) + P2( k,k) ha k <. k N T2[,k]=P2(,k)? k?? k 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 k N 1. ábra. Táblázat a Partíció robléma megoldásához. rekurzív összefüggések megadják az összetevőket: 1. P2(1, k)-ak és P2(, 1)-ek ics összetevője, 2. P2(, ) összetevője P2(, 1), 3. P2(, k) összetevője P2(, ), ha ( < k), 4. P2(,k) összetevői: P2(,k 1) és P2( k,k), ha (k < ). Tehát a táblázat kitöltése (k-szerit) sorokét balról jobbra haladó lehet. Az algoritmus futási ideje és tárigéye is Θ( 2 ). 2
Program ParticT2; {A artíció robléma megoldása. Módszer: égyzetes táblázatkitöltés} Fuctio P(N:Word):It64; Cost MaxN=500; {a táblázat mérete MaxN*MaxN} T2:array[1..MaxN,1..MaxN] of It64; ki,i,1:word; Begi{P} For i:=1 To N Do T2[i,1]:=1; {az első sor kitöltése} For ki:=2 To N Do Begi {az ki. sor kitöltése } T2[ki,ki]:=T2[ki,ki-1]+1; {P2(,)=P2(,-1)+1 } For i:=ki+1 To Do Begi {P2(i,ki)=T2[i,ki] számítása} 1:=ki; {P2(,k)=P2(,k-1)+P2(-k,k) } If i-ki<ki The 1:=i-ki; {P2(,k)=P2(,), ha k> } T2[i,ki]:=T2[i,ki-1]+T2[i-ki,1];{P2(,k)=P2(,k-1)+P2(-k,k) } Ed{for i}; Ed{for ki}; P:=T2[,]; Ed{P}; Begi{Program} WriteL(P(100)); Ed{Program}. 7.3. A artíció robéma megoldása lieáris táblázatkitöltéssel. Látható, hogy elegedő lee a táblázatak csak két sorát tároli, mert mide (, k) részrobléma összetevői vagy a k-adik, vagy a k 1-edik sorba vaak. Sőt, elég egy sort tároli balról-jobbra (övekvő -szerit) haladó kitöltésél, mert amelyik részroblémát felülírjuk (( k, k)), aak később ée az új értéke kell összetevőkét. Program ParticD; { A artíciószám robléma megoldása. Módszer: diamikus rogramozás lieáris táblázatkitöltés helybe } Fuctio P(N:Word):It64; Cost MaxN=5000 ;(* a táblázat mérete *) T : Array[1..MaxN] Of It64; ki,i : Word; Begi{P} For i:=1 To N Do T[i]:=1; {az első sor kitöltése } For ki:=2 To N Do Begi {az ki. sor kitöltése } T[ki]:=T[ki]+1; {P2(,)=P2(,-1)+1 } For i:=ki+1 To N Do {P2(,k)=P2(,k-1)+P2(-k,k) } T[i]:=T[i] + T[i-ki]; Ed{for ki}; P:=T[N]; Ed{P}; Begi{rogram} WriteL( P(405)=,P(405)); Ed{rogram}. P(405)= 9147679068859117602 3
7.4. A ézváltás robléma. Probléma: Pézváltás Bemeet: P = { 1,..., } ozitív egészek halmaza, és E ozitív egész szám. Kimeet: Olya S P, hogy S = E. Megjegyzés: A ézek tetszőleges címletek lehetek, em csak a szokásos 1, 2, 5 10, 20, stb., és mide éz csak egyszer haszálható a felváltásba. Először azt határozzuk meg, hogy va-e megoldás. A megoldás szerkezetéek elemzése. Tegyük fel, hogy E = i1 +... + ik, i 1 <... < i k egy megoldása a feladatak. Ekkor E ik = i1 +... + ik 1 megoldása lesz aak a feladatak, amelyek bemeete a felváltadó E ik érték, és a felváltáshoz legfeljebb a első i k 1 ( 1,..., ik 1) ézeket haszálhatjuk. Részroblémákra botás. Botsuk részroblémákra a kiidulási roblémát: Mide (X, i)(1 X E, 1 i N) számárra vegyük azt a részroblémát, hogy az X érték felváltható-e legfeljebb az első 1,..., i ézzel. Jelölje V (X,i) az (X,i) részrobléma megoldását, ami logikai érték; V (X, i) = Igaz, ha az X összeg előállítható legfeljebb az első i ézzel, egyébkét Hamis. Összefüggések a részroblémák és megoldásaik között. Nyilvávaló, hogy az alábbi összefüggések teljesülek a részroblémák megoldásaira: 1. V (X,i) = (X = i ), ha i = 1 2. V (X,i) = V (X,i 1) (X > i ) V (X i,i 1) ha i > 1 Rekurzív megoldás. Mivel a megoldás kifejezhető egy V(X,i) logikai értékű függvéyel, ezért a felírt összefüggések alajá azoal tuduk adi egy rekurzív függvéyeljárást, amely a ézváltás robléma megoldását adja. Fuctio V(X,i:Word):Boolea; {Globális:P} {Módszer: Rekurzív megoldás } Begi V:=(X=P[i])Or (i>1) Ad V(X,i-1) Or (i>1) Ad (X>P[i]) Ad V(X-P[i],i-1); Ed{V}; Ez a megoldás azoba ige lassú, legrosszabb esetbe a futási idő Ω(2 ). Megoldás a részroblémák megoldásaiak táblázatos tárolásával. Vegyük egy V T táblázatot, amelybe mide lehetséges részrobléma megoldását tároljuk. Mivel mide részroblémát két érték határoz meg, X és i, ezért téglala alakú táblázat kell. V T [X, i] az (X, i) részrobléma megoldását tartalmazza. A részroblémák kiszámítási sorredje. Olya kiszámítási sorredet kell megállaítai, amelyre teljesül, hogy amikor az (X, i) részroblémát számítjuk, akkor eek összetevőit már korábba kiszámítottuk. Mivel az (X, 1) részroblémákak ics összetevőjük, ezért közvetleül kiszámíthatóak, azaz a táblázat első sorát számíthatjuk először. Ha i > 1, akkor az (X, i) részrobléma összetevői az (X,i 1) és (X i,i 1), ezért az i-edik sor bármely elemét ki tudjuk számítai, ha már kiszámítottuk az i 1-edik sor mide elemét. Tehát a táblázatkitöltés sorredje: sorokét (alulról felfelé), balról-jobbra haladó lehet. Fuctio V(E,N:Word):Boolea; { Pézváltás égyzetes táblázatkitöltéssel } {Globál: P:Pezek} Cost MaxE=100; {a max. felváltadó összeg} MaxN=200; {a ézek max. száma} VT:Array[1..MaxE,1..MaxN] Of Boolea; i,x:word; 4
N i? i-1 1 1 X-P[i] X E 2. ábra. A ézváltás táblázata Begi{VT} For x:=1 To E Do VT[x,1]:=False; {az első sor, azaz V(x,1) számítása} VT[P[1],1]:= P[1]<=E; For i:=2 To N Do {az i-edik sor,azaz V(x,i) számítása} For x:=1 To E Do VT[x,i]:=(P[i]=X) Or VT[x,i-1] Or (x>p[i]) Ad VT[x-P[i],i-1]; V:=VT[E,N]; Ed{V}; Egy megoldás előállítása a megoldás visszafejtésével. Akkor és csak akkor va megoldása a roblémáak, ha a V T táblázat kitöltése utá V T [E,N] értéke igaz. Ekkor az (1-2.) kéletek szerit a legagyobb i idexű i éz, amely szereelhet E előállításába, az a legagyobb idex, amelyre V T [E,i] = True (V T [E,i 1] = False) De ekkor V T [E P[i],i 1] igaz, tehát E i előállítható az első i 1 éz felhaszálásával. Tehát a feti eljárást folytati kell E := E i,i := i 1-re midaddig, amíg E 0 lesz. Procedure PezValt1( E:Word; Cost P:Pezek; N: Word; Db:Word; C :Megoldas); Cost MaxE=300;{a max. felváltható érték} VT:Array[0..MaxE, 0..MaxN] Of Boolea; i,x:iteger; Begi{PezValt1} For X:=1 To E Do VT[X,1]:=False; {az első sor, azaz V(X,1) számítása} VT[P[1],1]:= P[1]<=E; For i:=2 To N Do {az i-edik sor,azaz V(X,i) számítása} For X:=1 To E Do VT[X,i]:=(P[i]=X) Or VT[X,i-1] Or (X>P[i]) Ad VT[X-P[i],i-1]; Db:=0; X:=E; i:=n { egy megoldás előállítása} If Not VT[E,N] The Exit; {ics megoldás} 5
Reeat While (i>0) Ad VT[X,i] Do Dec(i); Ic(Db); C[Db]:=i+1; {i+1 bejegyzése a megoldásba} X:=X-P[i+1]; {X-P[i+1] felváltásával folytatjuk} Util X=0; Ed{PezValt1}; Ha csak arra kell valszoli, hogy létezi-e megoldása a roblémáak, akkor elég a táblázat egy sorát tároli, mert sorokét visszafelé (x-szerit csökkeő sorredbe) haladó kitöltést alkalmazhatuk. Fuctio PezValt1L(E:Word; Cost P:Pezek; N: Word):Boolea; { Lieáris táblázatkitöltéssel } Cost MaxE=60000; T:Array[0..MaxE] Of Boolea; i,x:word; Begi{PezValt1L} For x:=1 To E Do T[x]:=False; T[0]:=True; If P[1]<=E The T[P[1]]:=True; For i:=2 To N Do For x:=e DowTo 1 Do T[x]:=T[x] Or (x>=p[i]) Ad T[x-P[i]]; PezValt1L:=T[E]; Ed{PezValt1L}; 7.5. Az otimális ézváltás robléma. Probléma: Otimális ézváltás Bemeet: P = { 1,..., } ozitív egészek halmaza, és E ozitív egész szám. Kimeet: Olya S P, hogy S = E és S miimális Először is lássuk be, hogy az a mohó stratégia, amely midig a lehető legagyobb ézt választja, em vezet otimális megoldáshoz. Legye E = 8 és a ézek halmaza legye {5,4,4,1,1,1}. A mohó módszer a 8 = 5 + 1 + 1 + 1 megoldást adja, míg az otimális a 8 = 4 + 4. Az otimális megoldás szerkezetéek elemzése. Tegyük fel, hogy E = i1 +... + ik, i 1 <... < i k egy otimális megoldása a feladatak. Ekkor E ik = i1 +... + ik 1 otimális megoldása lesz aak a feladatak, amelyek bemeete a felváltadó E ik érték, és a felváltáshoz legfeljebb a első i k 1 ( 1,..., ik 1) ézeket haszálhatjuk. Ugyais, ha lee kevesebb ézből álló felváltása E ik -ak, akkor E-ek is lee k-ál kevesebb ézből álló felváltása. Részroblémákra és összetevőkre botás. A részroblémák legyeek ugyaazok, mit az előző esetbe. Mide (X,i) (1 X E,1 i N) számárra vegyük azt a részroblémát, hogy legkevesebb háy éz összegekét lehet az X értéket előállítai legfeljebb az első i { 1,..., i } éz felhaszálásával. Ha ics megoldás, akkor legye ez az érték N +1. Jelölje az (X,i) részrobléma otimális megoldásáak értékét Ot(X,i). Defiiáljuk az otimális megoldás értékét X = 0-ra és i = 0-ra is, azaz legye Ot(X,0) = N + 1 és Ot(0,i) = 0. Így Ot(X, i)-re az alábbi rekurzív összefüggés írható fel. A részroblémák otimális megoldásáak kifejezése az összetevők otimális megoldásaival. N + 1 ha i = 0 X > 0 0 ha X = 0 Ot(X,i) = Ot(X,i 1) ha X < i mi(ot(x,i 1),1 + Ot(X i,i 1)) ha X i (1) 6
Procedure OtValto(Cost P :Pezek; E :Word; N:Word; Db:Word; C:Megoldas ); Cost MaxE=300; Ot:Array[0..MaxE] Of 0..MaxN+1; {az ot. mego.értéke} V:Array[0..MaxE,0..MaxN] Of 0..MaxN+1; i,x,ro:word; Begi{OtValto} For x:=1 To E Do Begi {iicializálás} Ot[x]:=N+1; V[x,0]:=N+1 Ed; Ot[0]:=0; For i:=1 To N Do { táblázatkitöltés} For x:=e DowTo 1 Do Begi If (x>=p[i]) The Ro:=Ot[x-P[i]]+1 {x-p[i] ot.felváltása+1} Else Ro:=N+1; If Ro<Ot[x] The Begi {Ot[x]=1+Ot(x,i-1)} Ot[x]:=Ro; {az i. éz szerel x } V[x,i]:=i; {otimális felváltásába} Ed Else {Ot[x]=Ot(x,i-1)} V[x,i]:=V[x,i-1]; {ics jobb, mit i-1-re} Ed{for x}; Db:=0; x:=e; i:=n; If Ot[E]<=N The { va megoldás} Reeat { egy otimális megoldás előállítása} i:=v[x,i]; {i. szereel x ot. felváltásába} Ic(Db); C[Db]:=i; {i bejegyzése a megoldásba} x:=x-p[i]; {x-p[i] ot. felváltását ézzük} Dec(i); { az 1..i-1 ézekkel} Util x=0; Ed{OtValto}; A diamikus rogramozás stratégiája. A diamikus rogramozás, mit robléma-megoldási stratégia az alábbi öt léés végrehajtását jeleti. 1. Az [otimális] megoldás szerkezetéek elemzése. 2. Részroblémákra és összetevőkre botás úgy, hogy: a) Az összetevőktől való függés körmetes legye. b) Mide részrobléma [otimális] megoldása kifejezhető legye (rekurzíva) az összetevők [otimális] megoldásaival. 3. Részroblémák [otimális] megoldásáak kifejezése (rekurzíva) az összetevők [otimális] megoldásaiból. 4. Részroblémák [otimális] megoldásáak kiszámítása alulról-felfelé haladva: a) A részroblémák kiszámítási sorredjéek meghatározása. Olya sorba kell raki a részroblémákat, hogy mide részrobléma mide összetevője (ha va) előbb szereelje a felsorolásba, mit. b) A részroblémák kiszámítása alulról-felfelé haladva, azaz táblázatkitöltéssel. 5. Egy [otimális] megoldás előállítása a 4. léésbe kiszámított (és tárolt) iformációkból. 7.6. Otimális biáris keresőfa előállítása A F = (M, R, Adat) absztrakt adatszerkezetet biáris keresőfáak evezzük, ha 1. F biáris fa, 7
2. Adat : M Elemti és Elemti-o értelmezett egy lieáris redezési reláció, 3. ( x M)( F bal(x) )( q F jobb(x) )(Adat() Adat(x) Adat(q)) A BINKERFAKERES függvéyeljárás egy yilvávaló megoldása a fába keresése feladatak. x a 2 a 1 q a 3 3. ábra. Biáris keresőfa Fuctio BiKerFaKeres(a:Adat; F:BiFA):BiFa; Begi While (F<>Nil) Ad (a<>f^.adat) Do If a<f^.adat The F:=F^.bal Else F:=F^.jobb; BiKerFaKeres:=F; Ed; x 5 k5 x 3 k 3 x 10 k 10 x 1 k 1 x 4 k 4 x 6 k 6 x 2 k 2 x 8 k 8 x 7 k 7 x9 k9 4. ábra. 10 adatot (kulcsot) tartalmazó biáris keresőfa Tegyük fel, hogy ismerjük mide k i kulcs keresési gyakoriságát, ami i (i = 1,...,) Továbbá ismert azo k kulcsok (sikertele) keresési gyakorisága, amelyre k i < k < k i+1, ami q i (,...,), és q 0 a k < k 1 kulcsok keresési gyakorisága. Átlagos keresési idő (költség): V (F) = i d F (x i ) + q i d F (y i ) 8
x 5 k 5 x 3 k 3 x 10 k 10 x 1 k 1 x 4 k 4 x 6 k 6 y 10 y 0 x 2 k 2 y 3 y 4 y 5 x 8 k 8 y 1 y 2 x 7 k 7 x9 k9 y 6 y 7 y 8 y 9 5. ábra. Biáris keresőfa kiegészíteve sikertele keresési otokkal, ahol d F () a ot mélysége az F fába. Probléma: Otimális biáris keresőfa előállítása. Bemeet: P = 1,..., sikeres és Q = q 0,...,q sikertele keresési gyakoriságok. Kimeet: Olya F biáris keresőfa, amelyek a V (F) költsége miimális. Az otimális megoldás szerkezete. Tegyük fel, hogy a k 1,...,k kulcsokat tartalmazó F biáris keresőfa otimális, azaz V (F) miimális. Jelölje x r a fa gyökerét. Ekkor az F 1 = F bal(xr ) fa a k 1,...,k r 1 kulcsokat, az F 2 = F jobb(xr ) fa edig a k r+1,...,k kulcsokat tartalmazza. Mivel k r F 1 F 2 iorder(f 1 ) = k 1,...k r 1 iorder(f 2 ) = k r+1,...,k 6. ábra. Ha az otimális fa gyökerébe a k r kulcs va. d F1 () = d F () + 1 és d F2 () = d F () + 1. 9
V (F) = = = + = + = r 1 r 1 i=r+1 i=r+1 i d F (x i ) + r 1 i d F (x i ) + q i d F (y i ) r 1 i (d F1 (x i ) + 1) + i + i + q i d F (y i ) + r + i (d F2 (x i ) + 1) + i=r+1 i=r+1 q i (d F1 (y i ) + 1) + r q i (d F2 (y i ) + 1) r 1 r 1 q i + i d F1 (x i ) + q i d F1 (y i ) i d F2 (x i ) + i=r q i d F2 (y i ) q i +V (F 1 ) +V (F 2 ) i d F (x i ) + i=r q i d F (y i ) Tehát V (F) = i + q i +V (F 1 ) +V (F 2 ) (2) Az F 1 fa a k 1,...,k r 1 kulcsokat tartalmazó otimális biáris keresőfa a 1,..., r 1 sikeres és q 0,...,q r 1 sikertele keresési gyakoriságokra, az F 2 fa edig k r+1,...,k kulcsokat tartalmazó otimális biáris keresőfa a r+1,..., sikeres és q r,...,q sikertele keresési gyakoriságokra. A bizoyítás a kivágás-és-beillesztés módszerrel végezhető. Ha lee olya F 1 biáris keresőfa a 1,..., r 1 sikeres és q 0,...,q r 1 sikertele keresési gyakoriságokra, hogy V (F 1 ) < V (F 1 ), akkor az F fába F 1 helyett az F 1 részfát véve olya fát kaák a 1,..., sikeres és q 0,...,q sikertele keresési gyakoriságokra, amelyek költsége i + q i + V (F 1 ) + V (F 2 ) < V (F). Ugyaígy bizoyítható, hogy F 2 is otimális fa a k r+1,...,k kulcsokra a r+1,..., sikeres és q r,...,q sikertele keresési gyakoriságokra. Részroblémákra botás. Mide (i, j) idexárra 0 i j tekitsük azt a részroblémát hogy mi az otimális biáris keresőfa az i+1,..., j sikeres és q i,...,q j sikertele keresési gyakoriságokra. Jelölje Ot(i, j) az otimális fa költségét az (i, j) részroblémára. Az otimális megoldás értékéek rekurzív kiszámítása. Vezessük be a j j W(i, j) = u + q u u=i+1 u=i jelölést. Mide (i, j)-re a (2) kélet miatt biztosa létezik olya i < r j, hogy Ot(i, j) = W(i, j) + Ot(i,r 1) + Ot(r, j), csak azt em tudjuk, hogy melyik r-re. Tehát azt az r-et keressük, amelyre a feti összeg miimális lesz. Tehát Ot(i, j) a következő rekurzív összefüggéssel számítható. { qi ha i = j Ot(i, j) = W(i, j) + mi (Ot(i,r 1) + Ot(r, j)) ha i < j (3) i<r j Az összetevők és a kiszámítási sorred meghatározása. Az (i,i) részroblémákak ics összetevőjük, mert Ot(i,i) = q i. Az (i, j), i < j részrobléma összetevői az (i,r 1) és (r, j), r = i + 1,..., j részroblémák. Tehát a táblázatot ki tudjuk töltei átlósa haladva, a m-edik átlóba m = 1,..., azo (i, j)részroblémákat számítjuk, amelyekre j i = m. Kiszámítás alulról-felfelé haladva (táblázatkitöltés). Ahhoz, hogy egy otimális megoldást elő tujuk állítai, mide (i, j) részroblémára tároljuk egy G táblázat G[i, j]-elemébe 10
N q j? qj qi 0 q0 q1 0 i N 7. ábra. Táblázatkitöltési sorred azt az r értéket, amelyre a (3) kéletbe az miimum előáll. Ez az r lesz a k i+1,...,k j kulcsokat tartalmazó otimális biáris keresőfa gyökere. A G[i, j] értékeket felhaszálva a FASIT rekurzív eljárás állítja elő téylegese az algoritmus kimeetét jelető keresőfát. { Globális rogramelemek az OtBKfa eljáráshoz :} Cost MaxN =??? ; { a kulcsok max. száma } Tye Kulcsti =???; { a kulcsok tíusa } Idex = 1..MaxN; Vektor = Array[Idex] Of Real; {a sikeres keresési gyakoriságok} Vektor1 = Array[0..MaxN] Of Real; {a sikertele keresési gyakoriságok} Fa = Array[Idex] Of Record {a biáris keresőfa ábrázolása} bal, jobb : 0..MaxN; kulcs : kulcsti; {egyéb mezők} Ed; Procedure OtBKfa(Cost P : Vektor; Cost Q : Vektor1; N : Idex; Gyoker : Idex; F : Fa ); { P[i]:az i-edik halmazelem keresési gyakorisága } { Q[i]:az i-edik es az i+1-edik almazelem közé eső elemek } { keresési gyakorisága } { Gyoker:az otimális keresőfa gyökérotjáak idexe } { F :az otimális biáris keresőfa} 11
Ot: Array[0..MaxN, 0..MaxN] Of Real; { Ot[i,j] az i+1..j elemeket tartalmazó OBK költsége } W: Array[0..MaxN, 0..MaxN] Of Real; { W[i,j]= Q[i]+Sum(P[k]+Q[k]: k:=i+1..j } G : Array[0..MaxN, 0..MaxN] Of 0..MaxN; {G[i,j] az i+1..j elemeket tartalmazó otimális biáris keresőfa gyökérotjáak idexe } i,j,r,m,otr : Iteger; otv, V : Real; Procedure Fasit(Aa, i, j : Iteger); { Előallítja az i+1..j elemek OB keresőfáját a G értékekből} { Globális: G, F} Begi{Fasit} If Aa <> 0 The Begi F[Aa].bal := G[i, Aa-1]; F[Aa].jobb := G[Aa, j]; Fasit(G[i, Aa-1], i, Aa-1); Fasit(G[Aa, j], Aa, j) Ed Ed{Fasit}; Begi{OtBKfa} For i := 0 To N-1 Do Begi { iicializálás } W[i,i]:=Q[i]; G[i,i]:=0; Ot[i,i]:=Q[i]; Ed; W[N,N]:=Q[N]; G[N,N]:=0; Ot[N,N]:=Q[N]; For m := 1 To N Do {m=j-i} For i := 0 To N-m Do Begi{ Ot(i,j) számítása } j := i+m; W[i,j] := W[i,j-1]+P[j]+Q[j]; otr := j; otv := Ot[i,j-1]+Q[j]{=Ot[j,j]}; For r := i+1 To j-1 Do Begi V := Ot[i,r-1]+Ot[r,j]; If V < otv The Begi otv := V; otr := r Ed Ed{for r}; Ot[i,j] := W[i,j]+otV; G[i,j] := otr Ed{i}; Gyoker := G[0,N]; Fasit(Gyoker, 0, N) Ed{OtBKfa}; A OPTBKFA algoritmus futási ideje Θ( 3 ). Bizoyítás élkül megjegyezzük, hogy a For r := i+1 To j-1 Do Begi ciklusba elegedő lee az r ciklusváltozót G[i,j-1]+1 -től G[i+1,j]-ig futtai, és ezzel az algoritmus futási ideje Θ( 2 ) lee. 12