Diszkrét matematika 8. előadás Sapientia Egyetem, Műszaki és Humántudományok Tanszék Marosvásárhely, Románia mgyongyi@ms.sapientia.ro 2016, őszi félév
Miről volt szó az elmúlt előadáson? a Fibonacci számsorozat a Fibonacci számrendszer beolvasási lehetőségek: a split és join függvények prímszámok
Miről lesz szó? Prímszámok, prímtesztelő algoritmusok osztási próba módszere (trial division) Eratosztenész szitája kongruenciák moduláris hatványozás maradékosztályok, maradékrendszerek a kis Fermat-tétel a kis-fermat tételen alapuló prímteszt az Euler függvény
Algoritmusok Pythonban Prímszámok: azok az 1-nél nagyobb egész számok, amelyek nem oszthatóak, csak 1-el és önmagukkal. Rossz hatékonyságú algoritmus: meghatározzuk egy szám osztóinak számát, ha az egyenlő kettővel akkor prímszám, másképp nem. Osztási próba módszere (trial division): sorra próbáljuk a páratlan számokkal való oszthatóságot. Az első osztónál leáll az algoritmus, azzal a kimenettel, hogy a szám nem prímszám. Ha a tesztelő szám négyzetgyökéig nem találunk osztót, akkor a szám prímszám. Eratosztenész szitája: kizárásos módszerrel adott n-ig meghatározza a prímszámok listáját Miller-Rabin prímteszt: egy adott páratlan számról biztosan megtudja állapítani, hogy az összetett, az azonban csak nagyon nagy valószínűséggel fogadható el, hogy a szám prím.
Eratosztenész szitája Eratosztenész szitájával határozzuk meg 100-ig a prímszámokat: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
Eratosztenész szitája Kivettük az 1-et és a 2-vel osztható számokat, a 2 marad: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
Eratosztenész szitája Kivettük a 3-mal osztható számokat is, a 3 marad: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
Eratosztenész szitája Kivettük az 5-tel osztható számokat is, az 5 marad: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
Eratosztenész szitája Kivettük a 7-tel osztható számokat is, a 7 marad: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
Eratosztenész szitája Összesen marad 25, 1-nél nagyobb szám, ezek a 100-nál kisebb prímszámok: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
Eratosztenész szitája Írassuk ki n-ig a prímszámokat: def erat(n): L = [True] * n L[0] = L[1] = False for i in range (2, n): if L[i] == True: print i, for j in range(i*i, n, i): L[j] = False
Eratosztenész szitája Hozzunk létre egy listát, amely tartalmazza n-ig a prímszámokat. def eratl(n): L = [True] * n L[0] = L[1] = False Lp = [] for i in range (2, n): if L[i] == True: Lp += [i] for j in range (i*i, n, i): L[j] = False return Lp
Eratosztenész szitája Hozzunk létre egy listát, amely tartalmazza n-ig a prímszámokat, csak a páratlan számok felett végezzük a vizsgálódást: def eratl_(n): L = [True] * n L[0] = L[1] = False Lp = [2] for i in range (3, n, 2): if L[i] == True: Lp += [i] for j in range (i*i, n, i): L[j] = False return Lp
Kongruenciák a számelmélet alapjait képezik, amelyet Gauss dolgozott ki, a 19. században, ax b (mod m) típusú egyenletek megoldásából indulunk ki, megjelenik a mindennapi életben: az órák (mod 12) vagy (mod 24) szerint, az év (mod 7) szerint működik, stb., alkalmazási terület: adatbiztonság, kódelmélet, Legyen m egy pozitív egész szám. Azt mondjuk, hogy a kongruens b-vel modulo m szerint, ha m (a b). Ezt a b (mod m)-el jelöljük. Ellenkező esetben azt mondjuk, hogy a inkongruens b-vel modulo m szerint. átalakítva egyenletté: a b (mod m) akkor és csakis akkor, ha létezik egy k egész szám, úgy hogy: a = b + km. Példák: 21 3 (mod 9), mert 9 (21 3), hasonlóan: 4 5 (mod 9) és 79 7 (mod 9) 14 5 (mod 12), mert 12 (14 5) = 9 21 3 (mod 9) 21 = 3 + 2 9
Kongruenciák Alaptulajdonságok reflexív: ha a egy egész szám, akkor a a (mod m), szimmetrikus: ha a, b egész számok és a b (mod m), akkor b a (mod m), tranzitív: ha a, b, c egész számok és a b (mod m), b c (mod m), akkor a c (mod m), Aritmetikai műveletekkel kapcsolatos tulajdonságok: legyenek a, b, c, m egész számok, ahol m > 0 és a b (mod m). Ekkor fennállnak a következők: a + c b + c (mod m), a c b c (mod m), a c b c (mod m), Az osztás műveletére nem adhatunk analóg tulajdonságot.
Kongruenciák Az osztással kapcsolatos tulajdonság: Példák: Legyenek a, b, c, m egész számok, ahol m > 0, d = lnko(c, m) és a c b c (mod m). Ekkor fennáll: a b (mod m/d). Legyen 14 8 (mod 6) A kongruenciát nem tudjuk végigosztani 2-vel, mert nem igaz az, hogy 7 4 (mod 6). A kongruenciát végigtudjuk osztani úgy 2-vel, hogy osztjuk a modulust is 2-vel, mert igaz, hogy lnko(2, 6) = 2, azaz fennáll: 7 4 (mod 3) Legyen 42 77 (mod 5) A kongruenciát végig tudjuk osztani 7-tel, úgy hogy osztjuk a modulust 1-el, mert igaz, hogy lnko(7, 5) = 1, azaz fennáll: 6 11 (mod 5)
Kongruenciák Az osztással kapcsolatos tulajdonság: Példák: Legyen 50 20 (mod 15) A kongruenciát nem tudjuk végigosztani 10-zel, mert nem igaz az, hogy 5 2 (mod 15). A kongruenciát végig tudjuk osztani úgy 10-zel, hogy osztjuk a modulust is 5-tel, mert igaz, hogy lnko(10, 15) = 5, azaz fennáll: 5 2 (mod 3) A kongruenciát végig tudjuk osztani úgy 5-tel, hogy osztjuk a modulust is 5-tel, mert igaz, hogy lnko(5, 15) = 5, azaz fennáll: 10 4 (mod 3)
Kongruenciák További tulajdonságok: legyenek a, b, c, d, m egész számok, ahol m > 0, a b (mod m) és c d (mod m). Ekkor fennállnak a következők: a + c b + d (mod m), a c b d (mod m), a c b d (mod m), a n b n (mod m), ahol n pozitív egész szám.
Moduláris hatványozás Mindenegyes négyzetre emelés után meghatározzuk az osztási maradékot és ezzel az értékkel dolgozunk tovább. Határozzuk meg 3 43 (mod 100) értékét: 3 3 (mod 100) 3 2 9 (mod 100) 3 4 81 (mod 100) 3 8 61 (mod 100) 3 16 21 (mod 100) 3 32 41 (mod 100) 3 43 = 3 32 3 8 3 2 3 1 = 41 61 9 3 = 27 (mod 100)
Moduláris hatványozás def modpow (x, n, m): res = 1 while n!= 0: if n % 2 == 1: res = (res * x) % m x = (x * x ) % m n = n/2 return res
Maradékosztályok, maradékrendszerek a (mod n) szerinti osztási maradékok alapján a számokat különböző halmazokba csoportosíthatjuk (mod n) szerinti maradékosztályok 10 5 0 5 10... (mod 5) 9 4 1 6 11... (mod 5) 8 3 2 7 12... (mod 5) 7 2 3 8 13... (mod 5) 6 1 4 9 14... (mod 5) a-nak (mod m) szerint a legkisebb nem negatív osztási maradéka r, ha fennáll: a = q n + r, ahol 0 r m 1 teljes maradékrendszer: az a 1, a 2,..., a m számok teljes maradékrendszert alkotnak m szerint, ha páronként inkongruensek (mod m) szerint 0, 1, 2,..., m 1 teljes maradékrendszert alkotnak (mod m) szerint,
Maradékosztályok, maradékrendszerek Példák redukált maradékrendszer: a teljes maradékrendszer azon a i elemei amelyekre fennáll: lnko(a i, m) = 1. (mod 6) szerint 1, 3, 5 redukált maradékrendszert alkotnak, (mod 6) szerint 0, 1, 2, 3, 4, 5 teljes maradékrendszert alkotnak,
A kis Fermat-tétel 1. tétel legjelentősebb számelméleti eredmény nem ugyanaz, mint a nagy Fermat-tétel (x n + y n = z n ) Ha x egy prímszám és a egy pozitív egész szám, úgy hogy 1 a x 1, akkor a x 1 1 (mod x). Példa: legyen x = 11, a = 3, ekkor fennáll: 3 10 = 59049 1 (mod 11) másfelől feĺırhatók a következők: 1 a = 1 3 3 (mod 11) 6 a = 6 3 7 (mod 11) 2 a = 2 3 6 (mod 11) 7 a = 7 3 10 (mod 11) 3 a = 3 3 9 (mod 11) 8 a = 8 3 2 (mod 11) 4 a = 4 3 1 (mod 11) 9 a = 9 3 5 (mod 11) 5 a = 4 3 4 (mod 11) 10 a = 10 3 8 (mod 11) a fentiek alapján hogyan bizonyítjuk a tételt?
A kis Fermat-tétel Ha egy x számra nem teljesül a fenti feltétel, akkor az egyértelműen összetett szám. Ha egy x számra teljesül a fenti feltétel, akkor az nem egyértelműen prímszám: vannak olyan összetett számok amelyekre létezik olyan a szám, hogy 1 a x 1 és a x 1 1 (mod x), ezeket a számokat a alapú Fermat-féle álprímeknek hívjuk. Pl. 2-es alapú Fermat-féle álprím: 341, mert 2 340 1 (mod 341), ugyanakkor 341 = 11 31. Carmichael-számok: olyan összetett számok amelyek esetében, minden a-ra, ahol lnko(a, n) = 1 és 1 a x 1 fennáll a x 1 1 (mod x). A legkisebb Carmichael-szám: 561 = 3 11 17. A Carmichael-számok száma végtelen. Feladat: ellenőrizzük, hogy 561 Carmichael szám. A kis-fermat tétel az első kiindulási pont a véletlenszűen működő prímtesztelő algoritmusokhoz.
A kis-fermat tételen alapuló prímteszt Az algoritmus bemenete x, egy páratlan szám és egy t biztonsági paraméter. A t értékében azt adjuk meg, hogy hány a számot generáljon véletlenszerűen az algoritmus. A kimenet True ha az x szám prímszám, figyelembe véve a t biztonsági paramétert, vagy False, ha a szám összetett. from random import randint from fractions import gcd def fermatt(x, t): for i in range(0, t): while True: a = randint(2, x - 1) if gcd(a, x) == 1: break #a gcd legnagyobb közös osztót számol, beépített függvény y = pow(a, x - 1, x) #a pow moduláris hatványértéket számol, beépített függvény if y!= 1: return False return True
A kis-fermat tételen alapuló prímteszt Mi lesz az eredménye a következő függvényhívásoknak, mennyi idő szükséges a válaszhoz? >>> fermatt(561, 20) >>> fermatt(1615681, 20) >>> fermatt(1909001, 20) >>> fermatt(34857835975336692110070624231469883701559255636955113356 35708220200578192260458040143794181564548691304944895249930873708038 99356093770083239637007231768763806910240626478591473518028403152264 77238188282392855265632094297346142144217678505229299089264625307610 6034309993844531740085767636273327758260088939811, 10) Milyen számok 1909001, 1615681? Charmichael számok 1909001 = 41 101 461 1615681 = 23 199 353
Az Euler-függvény 1. értelmezés Legyen n pozitív egész szám, ekkor az Euler-függvény meghatározza azokat a pozitív egész számokat, amelyek nem nagyobbak mint n és relatív prímek n-nel. φ(n)-nel jelöljük. Példa az Euler-függvény értékeire, ha 1 n 12: n 1 2 3 4 5 6 7 8 9 10 11 12 φ(n) 1 1 2 2 4 2 6 4 6 4 10 4