Egyesíthető prioritási sor Értékhalmaz: EPriSor = S E, E-n értelmezett a lineáris rendezési reláció. Műveletek: S,S 1,S 2 : EPriSor, x : E {Igaz} Letesit(S, ) {S = /0} {S = S} Megszuntet(S) {} {S = S} Uresit(S) {S = /0} {S = S} SorBa(S,x) {S = Pre(S) {x}} {S /0} SorBol(S,x) {x = min(pre(s)) Pre(S) = S {x}} {S = {a 1,...,a n }} Elemszam(S) {Elemszam = n} {S /0} Elso(S,x) {x = min(pre(s)) Pre(S) = S} {S /0} Torol(S) {S = Pre(S) \ {min(pre(s))}} {S 1 = S 1,S 2 = S 2 } Egyesit(S 1,S 2,S) {S = Pre(S 1 ) Pre(S 2 ) S 1 = /0 S 2 = /0}} Módosítható EPriSort vizsgálunk, amelyben használjuk a KulcsotCsokkent(S,x,k) műveletet, ami x kulcsát a k értékre csökkenti, ha k < kulcs(x), és az AltTorol(S,x) műveletet, amely az x elemet törli az egyesíthető prioritási sorból. Mindkét műveletnél feltesszük, hogy x-et egy rá mutató pointer adja meg. Fibonacci kupac Definíció: A Fibonacci-kupac fák egy olyan S = {F 1,...,F k,} sorozata, ahol minden F i fa kupac. A fák gyökérelemeit egy kétirányú láncban tároljuk, a Fibonacci kupacot egy a minimális elemére mutató min(s) mutatóval adjuk meg. Az egyes fákat egy olyan adatszerkezetben tároljuk, ahol egy pont fiai kétirányú láncban vannak eltárolva. Tehát egy fapont a Fibonacci kupacban a következő mutatókkal rendelkezik: apa, Efiu, bal, jobb. Továbbá hozzárendelünk a pontokhoz két további értéket fokszam(x) x fiainak számát adja meg, megjelol(x) egy boolean érték, ami akkor igaz, ha x már vesztette el fiát azóta, hogy a jelenlegi apja fia lett. A maximális fokszám felső korlátja Lemma. Legyen x az S Fibonacci-kupac tetszőleges pontja, amelynek fokszáma k. Jelölje az y 1,y 2,...,y k sorozat x fiait abban az időrendi sorrendben, ahogyan az x-hez kapcsolódtak. Ekkor f okszam(y 1 ) 0 és f okszam(y i ) i 2 i = 2,...,k-ra. Bizonyítás: f okszam(y 1 ) 0 nyilvánvaló. Legyen i 2 és vegyük észre, hogy amikor y i -t x-hez kapcsoltuk annak fiaként, akkor már az y 1,...,y i 1 pontok x fiai voltak, így f okszam(x) = i 1 teljesült. Továbbá az y i pontot csak akkor kapcsoltuk x-hez, ha f okszam(x) = f okszam(y i ), tehát f okszam(y i ) = i 1 is teljesült. Azóta y i legfeljebb egy fiát veszthette el, mert egyébként x-ből kivágták volna. Tehát f okszam(y i ) i 2. Definíció: A Fibonacci sorozat a következőképpen adható meg: F 0 = 0, F 1 = 1 és F k = F k 1 + F k 2, ha k 2. Teljes indukcióval könnyen látható, hogy minden k 0 esetén F k+2 = 1+ k i=0 F i. Lemma Legyen x az S Fibonacci-kupac tetszőleges pontja, amelynek fokszáma k. Jelölje meret(x) az x-gyökerű részfa pontjainak számát. Ekkor meret(x) F k+2. 1
Bizonyítás: Jelölje s k a minimumát a meret(z) értékeknek, ahol fokszam(z)=k. Nyilvánvaló, hogy s 0 = 1, s 1 = 2, s 2 = 3, továbbá s k értéke legfeljebb meret(x) lehet, és k-szerint monoton nő. Legyen most is az y 1,y 2,...,y k x fiainak sorozata abban az időrendi sorrendben, ahogyan x-hez kapcsolódtak. Ekkor meret(x) s k = k i=2 s f okszam(y i ) k i=2 s i 2. Innen k-szerinti teljes indukcióval következik, hogy s k F k+2 minden k nemnegatív egészre. n). Következmény: Egy n pontot tartalmazó Fibonacci-kupac tetszőleges pontjának D(n) maximális fokszáma O(lg Bizonyítás: Teljes indukcióval könnyen látható, hogy F k+2 Φ k, ahol Φ = (1+ 5)/2. Legyen x egy n pontot tartalmazó Fibonacci-kupac tetszőleges pontja, és legyen f okszam(x) = k. A fenti lemma állítása szerint n meret(x) Φ k. Φ alapú logaritmusát véve mindkét oldalnak kapjuk, hogy k log Φ n. Így a pontok D(n) maximális fokszáma O(logn). Adatszerkezet diszjunkt halmazokra Értékhalmaz: UnioHolvan = {H 1,...,H k } ahol H i E, i = 1,...,k és ha i j, akkor H i H j = /0. Műveletek: S :UnioHolvan, x,y: Elemtip, n1,n2: NevTip {Igaz} Letesit(S) {S = /0} {S = S} Megszuntet(S) {Igaz} {S = S} Uresit(S) {S = /0} {S = {H 1,...,H k } x H i } Holvan(S,x) {= y (x H i y H i )} {S = {H 1,...,H k } x / H i } Holvan(S,x) {= x S = Pre(S) {x}} {S = {H 1,...,H k } n 1 H i n 2 H j } Unio(S,n 1,n 2 ) {S = Pre(S) \ H i \ H j {H i H j }} {S = {H 1,...,H k } Elemszam(S) { S S = Pre(S)} {S = {H 1,...,H k } ReszElemszam(S,x) { H i x H i S = Pre(S)} {S = S} Iterator(S) {} {S = {H 1,...,H k } ( i)(x H i )} ReszIterator(S,x) {} Osszefuggo komponensek(g=(v,e)) for (u,v) in E If Holvan(u)!=Holvan(v) Then Egyesit(u,v) Összefüggő komponensek Megjegyzés: UnioHolvan adattípust használhatunk a Kruskal algoritmus hatékony megvalósítása során is. Tegyük fel, hogy az élek egy S prioritási sorban vannak eltárolva súly szerint, a megoldást megadó éleket a Megold halmazban tároljuk. Ekkor a következő algoritmusrészlet adja meg a minimális feszítőfát. 2
while (S.Elemszam()>0) SorBol(S,el) Fa1=H.Holvan(el.ki) Fa2=H.Holvan(el.be) if (Fa1!=Fa2) Unio(Fa1, Fa2) Bovit(Megold,el) Egyszerű megvalósítások A diszjunkt részhalmazok ábrázolhatók olyan Rep : {1,...,n} {1,...,n} függvénnyel, amely minden halmazelemhez hozzárendeli a halmaz reprezentáns elemét, azaz bármely x, y {1,..., n}-re Rep(x) = Rep(y) akkor és csak akkor, ha x és y ugyanazon részhalmazhoz tartozik. Ekkor a HOLVAN művelet konstans időben megvalósítható, az UNIO azonban az egyik részhalmaz elemszámával arányos idejű lesz. Egy másik lehetséges adatszerkezet a megvalósításhoz a kétdimenziós lánc, ahol a láncok fejelemei a halmazok reprezentánsai. Ekkor az UNIO művelet konstans időben megvalósítható, a HOLVAN művelet azonban csak O(n) időben. Tehát egymásnak ellentmondó követelményeket kellene kielégíteni, amelyik adatszerkezet jó a HOLVAN művelethez az nem jó az UNIO-hoz. Halmazerdő Ábrázoljuk a részhalmazokat fával, a fa gyökere a halmaz reprezentáns eleme, minden pontra egy mutató adja meg az apját. Ekkor az UNIO konstans időben megvalósítható. A HOLVAN futási idejének felső korlátja a fa magassága, tehát arra kell törekedni, hogy fa magassága ne legyen nagy. Két heurisztikát használunk ennek elérésére, ezek alkalmazásával a HOLVAN művelet amortizált költsége O(log n), ami gyakorlati szempontból konstans. Egyesítés a nagyobbikhoz: Az UNIO művelet mindig a nagyobb elemszámú részhalmaz gyökeréhez kapcsolja a kisebb elemszámú részhalmaz gyökerét. Úttömörítés: Minden HOLVAN művelet során a fának mindazon pontjait, amelyen a keresés áthalad a gyökérhez kapcsoljuk. Euklideszi algoritmus Lemma: Ha d a és d b akkor d s(ax+by) minden s, x és y egészre. Lemma Ha a b, akkor a b vagy b = 0, tehát ha a b és b a, akkor a = b. Lemma Ha a és b valamelyike nem 0, akkor lnko(a,b) az {ax+by : x,y Z} halmaz legkisebb pozitív eleme. Bizonyítás: Legyen s = ax+by a legkisebb pozitív szám a {ax+by : x,y Z} halmazban és q = a/s. Ekkor a mod s = a q s = a(1 qx)+b( qy). Másrészt 0 a mod s < s, amiből a mod s = 0, mivel s minimális. Tehát s a, és hasonlóan s b, így s lnko(a,b). Ugyanakkor lnko(a, b) s, mivel lnko(a,b) osztja a és b mindegyikét és s lineáris kombinációja a,b-nek. Tehát s = lnko(a,b). Lemma Tetszőleges nemnegatív egész a és pozitív egész b számokra lnko(a,b) = lnko(b,a mod b). Bizonyítás Ekkor a mod b = a a/b b, így lnko(a,b) a mod b, így lnko(a,b) lnko(b,a mod b) Hasonlóan adódik, hogy lnko(b, a mod b) lnko(a, b). 3
EUKLIDESZ(a,b) if b = 0 then Euklidesz:=a else Euklidesz:= Euklidesz(b,a mod b) Lemma. Ha a > b 1 és az EUKLIDESZ(a,b) futása k iterációt végez, akkor a F k+2 és b F k+1. Bizonyítás: Teljes indukcióval. Tétel (Lame) Minden k-ra, ha a > b 1 és b F k+1, akkor EUKLIDESZ(a,b) k-nál kevesebb iterációt végez. Következmény Tehát EUKLIDESZ(a,b) futási ideje O(logb). Bővített Euklideszi algoritmus A feladat olyan x és y együtthatók kiszámítása, amelyekre d = lnko(a,b) = ax+by BŐVÍTETT-EUKLIDESZ(A,B) if b = 0 then return (a,1,0) else (d,x,y ):=BŐVÍTETT-EUKLIDESZ(b,a mod b) (d,x,y):=(d,y,x -[a/b]y ) return (d,x,y) Ha b = 0, akkor x = 1 és y = 0 valóban megoldás, mert a = ax+by. Ha b 0, akkor előbb a (d,x,y ) hármast számítjuk ki, ahol d = lnko(b,a mod b) és d = bx +(a mod b)y, ahogy az Euklideszi algoritmusnál, itt is d = d. Ezt felhasználva d = bx +(a a/b b)y = ay + b(x a/b y ). Moduláris hatványozás A feladat a b kiterjesztése. mod n hatékony kiszámítása. A megoldás lényegében az ismételt négyzetreemelés módszerének MODULÁRIS-HATVÁNYOZÓ(a,b,n) c:=0 d:=1 legyen b(k),b(k-1),...,b(1),b(0) b bináris alakja for i:=k downto 0 do begin c:=2*c d:=d*d mod n if b(i)=1 then c:=c+1; d:=(d*a) mod n return d Lemma A for ciklus iterációjára teljesülnek: A c változó értéke megegyezik b bináris ábrázolásából a b(k),b(k 1),...,b(i+1) kezdőszeletével. d = a c mod n 4
Titkosírások, titkosítások A titkosítandó szöveget vagy üzenetet nyílt szövegnek nevezzük. Maga a titkosító eljárás egy algoritmus, amely a nyílt szöveget egy másik szöveggé alakítja. Az utóbbi szöveget nevezzük titkosított szövegnek. A fogadó fél a titkosított szöveget dekódolja a nyílt szöveggé. Ezt egy kulcs segítségével teheti meg, amelyet csak a küldő és a megcélzott fogadók, a címzettek ismernek. Általában ismert lehet a titkosítás algoritmusa, de nem ismert a kulcsot. Enélkül pedig a nem érintettek, nem tudják hatékonyan dekódolni azz üzenetet. Már az ókorban is használtak titkosított üzeneteket. Általában egyszerű titkosítási eljárásokat használtak, amelyek a behelyettesítő módszeren alapultak. A behelyettesítéses módszer esetén a nyílt szöveg minden betűjét egy másikkal helyettesítik. A számítógépek megjelenésével megnőtt a számítási kapacítás, és új bonyolultabb titkosítási eljárások alakultak ki. Lényeges előrelépés a nyilvános kulcsú titkosítás felfedezése, mely lehetővé teszi, hogy a kulcsban történő megegyezés nélkül is kommunikáljanak a felek. Nyílt kulcsú titkosítás Tegyük fel, hogy Bob titkosítottan szeretne elküldeni Aliznak az M üzenetet. A nyilvános kulcsú titkosítás esetén Aliznak van egy S A titkos és egy P A nyilvános kulcsa, továbbá van egy K és D függvénypár (a kódoló és dekódoló függvények), amelyekre teljesül, hogy D(S A,K(P A,M)) = M. Tehát adott P A nyilvános kulcsra a P A (M) = K(P A,M) függvénynek az S A titkos kulcsra vett S A (C) = D(S A,C) függvény az inverze. (Általában megköveteljük azt is, hogy S A (C) a P A (M) függvénynek is inverze legyen.) A nyilvános kulcsú titkosítás protokolljában Bob az M üzenetét kódolja, majd a K(P A,M) üzenetet elküldi. Ezt követően Aliz a titkos kóddal újra meghatározza a D(S A,K(P A,M)) = M értéket. A digitális aláírás protokolljában, Bob egy M üzenetet akar aláírni, hogy igazolja valóban az általa küldött üzenet. Ekkor elküldi M-el együtt a D(S B,M) üzenetet is. Alíz az üzenetek érkezése után ellenőrzi a K(P B,D(S B,M)) = M egyenlőséget. RSA algoritmus 1. Vegyünk véletlenszerűen két különböző nagy prímszámot, p-t és q-t. 2. Legyen n = pq. 3. Vegyünk egy olyan kis páratlan e számot, amely relatív prím φ(n) = (p 1)(q 1)-hez. 4. Keressünk egy olyan d számot, amelyre ed = 1 mod φ(n). 5. Az RSA nyilvános kulcs a P = (e,n) pár lesz. 6. Az RSA titkos kulcs az S = (d,n) pár lesz. Ebben a sémában az elküldhető üzenetek halmaza Z n = {0,1,...,n 1}. A kódolás a P = (e,n) nyilvános kulccsal: A dekódolás a titkos kulccsal: P(M) = M e mod n. S(C) = C d mod n. 5