Liczby pierwsze - test pierwszości

Wprowadzenie

Liczba pierwsza to liczba naturalna większa od 1, która ma dokładnie dwa dzielniki: 1 i samą siebie. Liczby pierwsze są fundamentalnym pojęciem w matematyce i mają kluczowe zastosowania w informatyce.

Testy pierwszości są wykorzystywane w:

  • Kryptografii (RSA, generowanie kluczy)
  • Funkcjach haszujących (wybór rozmiarów tablic)
  • Generatorach liczb pseudolosowych
  • Algorytmach faktoryzacji
  • Teorii kodowania
  • Testowaniu oprogramowania

Przykłady liczb pierwszych: 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31...

Liczby złożone: liczby mające więcej niż 2 dzielniki (4, 6, 8, 9, 10...)


Podstawowa definicja

Matematyczna definicja

Liczba n > 1 jest pierwsza ⟺ nie istnieje liczba d taka, że:

2 ≤ d < n  oraz  n mod d = 0

Innymi słowy: n nie dzieli się przez żadną liczbę oprócz 1 i n.


Algorytmy sprawdzania pierwszości

1. Metoda naiwna (trial division)

Algorytm:

Sprawdź wszystkie potencjalne dzielniki od 2 do n-1:
  Jeśli n dzieli się przez jakiś dzielnik → liczba złożona
  Jeśli nie znaleziono dzielnika → liczba pierwsza

Implementacja:

Wyjście:

=== Test pierwszości (metoda naiwna) ===

   1 → złożona
   2 → PIERWSZA
   3 → PIERWSZA
   4 → złożona
   5 → PIERWSZA
  10 → złożona
  11 → PIERWSZA
  15 → złożona
  17 → PIERWSZA
  20 → złożona
  23 → PIERWSZA
  25 → złożona
  29 → PIERWSZA
  30 → złożona
  97 → PIERWSZA
 100 → złożona

Złożoność: O(n) - bardzo wolne dla dużych liczb!


2. Optymalizacja: sprawdzanie do √n

Obserwacja: Jeśli n jest złożona, to ma dzielnik ≤ √n

Dlaczego?

Jeśli n = a × b  i  a > √n  to  b < √n

Czyli wystarczy sprawdzić dzielniki do √n!

Implementacja:

Wyjście:

=== Test pierwszości (√n) ===

Liczba     √n (limit)      Wynik
----------------------------------------
2          2               PIERWSZA
97         10              PIERWSZA
100        11              złożona
101        11              PIERWSZA
1009       32              złożona
1013       32              PIERWSZA
10007      101             złożona
10009      101             PIERWSZA

Poprawa wydajności: z O(n) na O(√n) - masywna optymalizacja!


3. Dalsze optymalizacje

Wyjście:

=== Test pierwszości (zoptymalizowany) ===

Liczba: 1000000007
Wynik: PIERWSZA
Czas: 0.0124 ms

4. Test Miller-Rabin (probabilistyczny)

Algorytm probabilistyczny - bardzo szybki dla dużych liczb, ale może dać błędną odpowiedź z małym prawdopodobieństwem.

Wyjście:

=== Test Miller-Rabin (probabilistyczny) ===

     1000000007 → PIERWSZA  ✓
     1000000009 → PIERWSZA  ✓
     1000000010 → złożona   ✓
      982451653 → PIERWSZA  ✓
      982451654 → złożona   ✓

Miller-Rabin jest bardzo szybki i praktycznie zawsze poprawny (prawdopodobieństwo błędu < 10⁻³⁰ dla k=10).


Porównanie algorytmów

Wyjście (przykładowe):

=== Benchmark testów pierwszości ===

Liczba          Typ                  Algorytm             Czas (ms)
----------------------------------------------------------------------
97              mała pierwsza        √n optimized           0.0008
97              mała pierwsza        Miller-Rabin           0.0042
10007           średnia pierwsza     √n optimized           0.0089
10007           średnia pierwsza     Miller-Rabin           0.0055
1000000007      duża pierwsza        √n optimized           0.2145
1000000007      duża pierwsza        Miller-Rabin           0.0063
1000000000      duża złożona         √n optimized           0.0004
1000000000      duża złożona         Miller-Rabin           0.0051

Praktyczne zastosowania

1. Generowanie liczby pierwszej w zakresie

Wyjście:

=== Znajdowanie następnej liczby pierwszej ===

Początek:       1 → Następna pierwsza: 2
Początek:      10 → Następna pierwsza: 11
Początek:     100 → Następna pierwsza: 101
Początek:    1000 → Następna pierwsza: 1009
Początek:   10000 → Następna pierwsza: 10007
Początek:  100000 → Następna pierwsza: 100003

2. Policzenie liczb pierwszych do N

Wyjście:

=== Liczba pierwszych do N ===

N          Liczba pierwszych    Gęstość
---------------------------------------------
10         4                    40.00%
100        25                   25.00%
1000       168                  16.80%
10000      1229                 12.29%

3. Sprawdzanie liczb bliźniaczych

Liczby bliźniacze: pary liczb pierwszych różniących się o 2 (np. 3 i 5, 11 i 13, 17 i 19).

Wyjście:

=== Liczby pierwsze bliźniacze ===

Liczby bliźniacze do 100:

(3, 5)
(5, 7)
(11, 13)
(17, 19)
(29, 31)
(41, 43)
(59, 61)
(71, 73)

Znaleziono 8 par

Złożoność obliczeniowa

Porównanie algorytmów

Algorytm Złożoność czasowa Złożoność pamięciowa Typ
Naiwny O(n) O(1) Deterministyczny
√n optimized O(√n) O(1) Deterministyczny
Miller-Rabin O(k × log³ n) O(1) Probabilistyczny
AKS O(log⁶ n) O(log n) Deterministyczny

gdzie: - n = liczba testowana - k = liczba iteracji Miller-Rabin


Podsumowanie

Kluczowe algorytmy

Algorytm Kiedy używać Zalety Wady
√n optimized Małe/średnie liczby (< 10⁹) Prosty, deterministyczny Wolny dla dużych n
Miller-Rabin Duże liczby (> 10⁹) Bardzo szybki Probabilistyczny
Sito Eratostenesa Wiele liczb do N Szybkie dla zakresu Wymaga pamięci O(n)

Kluczowe fakty

Liczba pierwsza: ma tylko 2 dzielniki (1 i siebie) ✅ 2 jest jedyną parzystą liczbą pierwszą ✅ Każda liczba złożona ma dzielnik ≤ √n ✅ Gęstość liczb pierwszych maleje (twierdzenie o liczbach pierwszych) ✅ Miller-Rabin praktycznie zawsze poprawny dla k ≥ 10

Zastosowania

Kryptografia: generowanie kluczy RSA ✅ Funkcje hash: rozmiary tablic ✅ Generatory liczb losowychTeoria kodowaniaFaktoryzacja


Co dalej?

Po opanowaniu testów pierwszości, następne kroki to:

  1. Lekcja 66: Sito Eratostenesa
  2. Efektywne generowanie wielu liczb pierwszych
  3. Optymalizacje pamięciowe

  4. Lekcja 67: Algorytm Euklidesa - NWD

  5. Największy wspólny dzielnik
  6. Liczby względnie pierwsze

  7. Lekcja 69: Rozkład na czynniki pierwsze

  8. Faktoryzacja liczb
  9. Zastosowania

Zadania praktyczne

Zadanie 1: Generator liczb pierwszych

Napisz funkcję generującą N kolejnych liczb pierwszych.

Zadanie 2: Liczby Mersenne'a

Sprawdź które z liczb postaci 2ⁿ - 1 są pierwsze dla n ≤ 20.

Zadanie 3: Test Fermata

Zaimplementuj test pierwszości Fermata i porównaj z Miller-Rabin.

Zadanie 4: Rozwiń

Znajdź największą lukę między kolejnymi liczbami pierwszymi do 1,000,000.


Następna lekcja: Sito Eratostenesa - efektywne generowanie liczb pierwszych