Dodekaéder Hamilton köre
A Hamilton probléma Egy gráf Hamilton körén egy olyan kört értünk, ami minden egyes csúcspontot érint. Az ilyen kört tartalmazó gráfok hamiltoniak. Egy gráf Hamilton gráf-e: HAM={<G>: G Hamilton gráf} HAM(G)={G: $p:p G útja, p Hamilton kör} HAM nyelvre naiv eldöntő algoritmus: vesszük a G gráf csúcsainak összes permutációját, és ellenőrizzük, hogy (Hamilton) kör-e. Ha n=|G|, a csúcsok száma (csúcsmátrix) m=W(SQR(n)), a permutációk száma=m!, a futási idő: W(m!)=W(SQR(n)!)=W(2SQR(n)) a futásidő legalább exponenciális… Bebizonyítható, hogy a Hamilton probléma NP teljes…
Ellenőrző algoritmusok Tfh. A feladat egy adott G gráf egy P útjáról eldönteni, hogy Hamilton kör-e. ellenőrizzük, hogy a P tényleg a G csúcspontjainak egy permutációja, és a pontok tényleg szomszédosak-e. Az időigénye bizonyíthatóan: O(n2). Def: Ellenőrző algoritmus: olyan kétbemenetű A(x,y) algoritmus, amely kiegészül egy további paraméterrel, a tanúval. A bizonyítja az x szót, ha létezik olyan y tanú, hogy A(x,y)=1. L={xÎ{0,1}*:$yÎ{0,1}* A(x,y)=1}
Ellenőrző algoritmusok Pl: HAM(G,p)={G: p G útja, p Hamilton kör} Pl: Miller-Rabin prímgenerálás: a kívánt tartományban meghívjuk a prímtesztet Munka ellenőrző algoritmusokkal: Megsejtjük (egy sejtés halmazt előállítunk) a tanút Meghívjuk az ellenőrző algoritmust
Számelméleti algoritmusok Szép, de haszontalan? Hasznosítás a titkosítási algoritmusokban Hatékonyság: igen nagy számoklg(n): a szám méretepolinomiális algoritmus: ha a futási idő lg(n1), lg(n2),…-ben polinomiális. Feltételezésünk: az elemi számtani műveletek (gépi méretű adatokkal) egységnyi idő alatt futnak le. Nagyon nagy számokkal: bitműveletekre le kell bontani Szorzás/osztás: Q(b2), összeadás/kivonás: Q(b) (bár létezik gyorsabb megoldás is)
Számelméleti alapfogalmak Egész számok és természetes számok Oszthatóság: d|a (d osztja a-t)== létezik olyan egész szám, amelyre k*d=a. Másképp: a a d többese/többszöröse. Nem oszthatóság. Ha d|a és d>=0, akkor d az a osztója. 1 és a az a triviális osztói. A többi osztóit az a tényezőinek vagy faktorainak nevezzük. Prímszámok: azok, amelyek nem bonthatók tényezőkre. A többiek: összetett számok.
(Legnagyobb) közös osztó Def: Ha d|a és d|b, akkor azt mondjuk, hogy a d szám az a és b közös osztója. Pl: 30 osztói: 1,2,3,5,6,10,15, 24 és 30 közös osztói: 1,2,3,6 d|a és d|bd|(a+b) és d|(a-b) d|a és d|bd|(a*x+b*y) Legnagyobb közös osztó: lnko(a,b). lnko(0,0)=0 lnko(a,b)=lnko(b,a) --- szimmetria lnko(a,b)=lnko(-a,b) lnko(a,b)=lnko(|a|,|b|) lnko(a,0)=|a| lnko(a,k*a)=|a|, bármely k egészre
Tétel: Ha a és b egészek, legalább egyikük<>0 lnko(a,b)=min({ax+by:x,y egészek}). Biz: Legyen s=min({ax+by}), és q=[a/s]. Ekkor a mod s=a-[a/s]*s=a-q*(ax+by)=a*(1-qx)+b*(-qy) a mod s szintén a és b lineáris kombinációja. Mivel 0<=a mod s<s, csak a mod s=0 lehet, hiszen s a legkisebb ilyen>=0 kombináció volt. Ezért s|a, és hasonlóan s|b. Ha s közös osztója a-nak és b-nek, akkor lnko(a,b)>=s. Másrészt: lnko(a,b)|s és s>0, tehát lnko(a,b)<=s. A kettőből együtt: lnko(a,b)=s, vagyis s az a és b legnagyobb közös osztója. Ha d|a és d|b, akkor d|lnko(a,b)
Relatív prímek Def: az a és b számokat relatív prímeknek nevezzük, ha lnko(a,b)=1 Def: az a1, a2,…, an számokat páronként relatív prímeknek nevezzük, ha minden i¹j esetén lnko(ai,aj)=1 Tétel: ha az a, b és p számokra lnko(a,p)=1 és lnko(b,p)=1 (két egész szám relprím egy p-hez)lnko(ab,p)=1 (akkor a szorzatuk is az) Biz: HF
Törzstényezőkre bontás (prímfaktorizáció) Tétel: Ha p prím, a és b pedig olyan egészek, hogy p|ab, akkor p|a vagy p|b. Tétel: Egy egész szám pontosan egyféleképpen írható fel: a= p1e1*p2e2*…*pnen alakban, ahol p1<p2<…<pn prímek, az ei-k pedig pozitív egészek. Példa: 24=23*3, 6000= 24*3*53 Tétel: A prímfaktorizáció nem végezhető el (lg(n)-re nézve) polinomiális időben. Pl: 200 decimális jegyű szám felbontása a gyakorlatban lehetetlen…
Legnagyobb közös osztó keresése Naív algoritmus: - a= p1e1*p2e2*…*pnen - b= p1f1*p2f2*…*pnfn az összes prímre, esetleg ei=0 - lnko(a,b)= p1min(e1,f1)*p2min(e2,f2)*…*pnmin(en,fn) a nem polinomiális (exponenciális) futamidő miatt nem használható… Tétel (a legnagyobb közös osztó rekurziós tétele): a és b természetes számokra: lnko(a,b)=lnko(b,a mod b). Biz: Az egyenlőség két oldala kölcsönösen osztja egymásta két oldal egyenlő…
Az euklideszi algoritmus euklidesz(A,0,A). euklidesz(A,B,LNKO):- A<B, euklidesz(B,A,LNKO). euklidesz(A,B,LNKO):- B>0, A>=B, R is A mod B, euklidesz(B,R,LNKO). Tétel: Az euklideszi algoritmus futási ideje polinomiális. (Biz: A=k*B+R 0<=R<B<=A A>=B+R és B>R miatt B+R>2*R. R<B/2 BR<AR<AB/2. vagyis az AB szorzat a rekurzív hívások között legalább feleződik! legfeljebb log(AB) az iterációk száma. Mivel egy iteráció polinomiális időben végrehajtható állítás. ) Megjegyzés: Az euklideszi algoritmust sokan a következőképpen definiálják: euklidesz(A,B,LNKO):- B>0, A>=B, R is A - B, euklidesz(B,R,LNKO). Ez a megoldás korrekt, de nem polinomiális!!!
Fibonacci számok A következő sorozat: F0=0, F1=1, Fk+1+ Fk = Fk+2 . Pl. 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233,… Aranymetszés: f=(1+sqr(5))/2=1.61803 Konjugáltja: f’=(1-sqr(5))/2 = -0.6183 Tétel: Fi=(fi-f’i )/sqr(5) --- teljes indukcióval bizonyítható a Fibonacci számok exponenciálisan nőnek.
Az euklideszi algoritmus időszükséglete Tétel: Ha A>B>=0, és az euklidesz(A, B, LNKO) rekurziós mélysége k>=1, akkor A>=Fk+2, és B>=Fk+1. Biz: 1. Ha k=1, akkor B>=1=F2, valamint A>B miatt A>=2=F3. 2. Tfh. A tétel igaz k-1 rekurziós szintig. Belátjuk, hogy igaz marad a k. szinten is. Az euklidesz(A,B,_) k rekurziós szinten van, meghívja az euklidesz(B,A mod B)-t k-1 szinten, az indukciós feltevés miatt B>=Fk+1 és (A mod B)>=Fk. Másrészt B+R=B+(A-A/B*B)<=A A>=B+(A mod B)>= Fk+1+ Fk= Fk+2
Az euklideszi algoritmus kiterjesztése Feladat: d=lnko(a,b)=ax+by egyenlőségben x,y,d meghatározása… euklidesz(A,0,A,1,0). euklidesz(A,B,LNKO,X,Y):- A<B, euklidesz(B,A,LNKO,Y,X). euklidesz(A,B,LNKO,X,Y):- B>0, A>=B, R is A mod B, euklidesz(B,R,LNKO,X1,X), Y is X1-A//B*Y .
Prímtesztek Prímeket találni könnyű – prímtényezőkre bontani nehéz Tétel: A nagy prímszámtétel: nµlim (p(n)/(n/ln(n)))=1, ahol p(n) a prímek eloszlásfüggvénye, az n-nél nem nagyobb prímek száma. Pl. n=109 esetben p(n)=50847534, n/ln(n)=48254942, az eltérés 6%-nál kisebb Egy n véletlen egész 1/ln(n) vlsz-gel prím is. Vagyis n közelében ln(n) egész közül vlsz. van prím is. Vagyis pl. egy 100 jegyű prímhez csak ln(10100)»230 számot kellene ellenőrizni…
Álprímek tesztelése Fermat tétele: Ha p prím, akkor ap-1º1 (mod p) minden aÎZp-re. A tétel megfordítása majdnem igaz… Azt mondjuk, hogy az n szám a alapú álprím, ha an-1º1 (mod n). Ál2prím(N) if modHatvány(2,n-1,n)=1 then return „Összetett” else return „Álprím” Hibaszázalék: 10000-ig 22 téves szám van. 100 bit esetén hibaesély<1/1013!!
Miller-Rabin vlsz.-i prímteszt Nem tökéletes, az előző javítása. Több, véletlen bázisértéket választ ki. Ellenőrzi, ha a nemtriviális négyzetgyöke 1-nek mod n. Carmichael számok: amelyek minden bázisértékre álprímek, de nem prímek… ÖsszTanú: a az n összetettségének tanúja: MillerRabin(n,s) -- n prím, s db. értékkel tesztelve for j=1 to s a=random(1,n-1) if ÖsszTanú(a,n) then return FALSE else return TRUE
Miller Rabin hibaaránya Lényegesen kisebb a hibaarány, mint az Ál2Prím esetén Nem függ a szám nagyságától…
ÖsszTanú(a,n) bk,bk-1,…,b0 az n bináris alakja d=1 for i=k to 0. x=d ÖsszTanú(a,n) bk,bk-1,…,b0 az n bináris alakja d=1 for i=k to 0 x=d d=(d*d) mod n if d=1 and x<>1 and x<>n-1 then return TRUE if bi=1 then d=(d*a) mod n next i if d<>1 then return TRUE else return FALSE