Szybkie potęgowanie

Szybkie potęgowanie - teoria

Algorytm szybkiego potęgowania (ang. Exponentiation by Squaring) pozwala na obliczenie wartości potęgi w czasie znacznie krótszym niż tradycyjne podejście, które polega na mnożeniu liczby przez siebie n razy. Standardowa metoda, czyli wielokrotne mnożenie, działa w czasie O(n), natomiast szybkie potęgowanie obniża złożoność czasową do O(log n).

Kluczowa idea
Algorytm opiera się na podziale problemu i wykorzystaniu faktu, że:

  • Dla liczby parzystej n, potęgę można przekształcić w:
    an =(an/2 )2
    co oznacza, że wystarczy policzyć a podniesione do połowy potęgi, a wynik podnieść do kwadratu.

  • Dla liczby nieparzystej n, potęgowanie możemy uprościć w następujący sposób:
    a n =a⋅an−1
    gdzie a^{n-1} jest liczbą parzystą, którą można dalej przekształcić zgodnie z zasadą powyżej.

Sposób działania algorytmu

Algorytm działa rekurencyjnie lub iteracyjnie, dzieląc problem na mniejsze części aż do osiągnięcia podstawy, którą jest n = 0 (bo każda liczba podniesiona do potęgi 0 równa się 1). Dla każdej kolejnej połowy problemu wynik jest odpowiednio przekształcany i mnożony.

Rekurencyjny opis algorytmu

Zdefiniuj potęgę:

  • Jeśli n = 0, wynik to 1 (bo każda liczba podniesiona do potęgi 0 równa się 1).

  • Jeśli n jest parzyste, oblicz a^{n/2}, a następnie podnieś ten wynik do kwadratu.

  • Jeśli n jest nieparzyste, oblicz a^{n-1}, a następnie pomnóż przez a.

Przykład działania

Rozważmy obliczenie 35.

  • Krok 1: 5 jest nieparzyste, więc:
    35 =3⋅34

  • Krok 2: 4 jest parzyste, więc:
    34 =(32 )2

  • Krok 3: Obliczamy 32=9 i podnosimy do kwadratu:
    3 4 =92 =81

  • Krok 4: Wracamy do 35:
    35 =3⋅81= 243

Dzięki tej metodzie zamiast wykonywać 5 mnożeń, wykonujemy tylko 3 mnożenia.

Iteracyjna wersja algorytmu

Algorytm można zapisać w formie iteracyjnej, gdzie potęgę oblicza się w pętli, bez użycia rekurencji. Używamy zmiennej wynik, która jest stopniowo mnożona przez bazę, jeśli n jest nieparzyste, a następnie kwadrat bazy, gdy n jest parzyste. Wartość n dzielimy przez 2 przy każdym kroku.

Zalety algorytmu:

  • Zastosowanie w obliczeniach na dużych liczbach (np. kryptografia).

  • Szybkość, szczególnie w porównaniu z tradycyjnym podejściem mnożenia.

Szybkie potęgowanie jest przydatne tam, gdzie wymagane jest szybkie liczenie potęg w dużych systemach numerycznych, np. w kryptografii, grafice komputerowej, czy algorytmach numerycznych.

Pseudokod - Szybkie potęgowanie iteracyjne

Iteracyjne potęgowanie działa w pętli, dopóki wykładnik n jest większy od 0. W każdym kroku wykonuje kwadratowanie bazy, dzieli wykładnik przez 2, a jeśli wykładnik jest nieparzysty, mnoży wynik przez bazę.

Funkcja algorytmu szybkiego potęgowania iteracyjnego:

Wejście:

  • a - baza (liczba, którą podnosimy do potęgi)

  • n - wykładnik (potęga)

Wyjście:

  • wynik - wynik potęgowania (a^n)

Zmienne pomocnicze:

  • wynik - zmienna przechowująca wynik potęgowania

  • a - zmienna baza, która będzie modyfikowana w czasie pętli

  • n - zmienna wykładnik, która będzie zmniejszana o połowę

Lista kroków:

K1:   wynik ← 1   (Inicjalizacja wyniku jako 1)
K2:   Dopóki n > 0  
      wykonuj kroki od K3 do K6
K3:   Jeśli n % 2 = 1  
      to wynik ← wynik * a   (Jeśli wykładnik nieparzysty, pomnóż wynik przez bazę)
K4:   a ← a * a   (Kwadratowanie bazy)
K5:   n ← n / 2   (Dzielimy wykładnik przez 2)
K6:   Zakończ pętlę
K7:   Zwróć wynik   (Zwracamy końcowy wynik)

Wynik działania programu:

Podaj baze (a): 3
Podaj wykladnik (n): 5
3^5 = 243

Pseudokod - Szybkie potęgowanie rekurencyjne

Rekurencyjne potęgowanie używa podziału problemu na mniejsze części: jeśli wykładnik jest parzysty, problem dzieli się na połowę, jeśli jest nieparzysty, zmniejsza wykładnik o 1 i mnoży przez bazę.

Funkcja algorytmu szybkiego potęgowania rekurencyjnego

Wejście:

  • a - baza (liczba, którą podnosimy do potęgi)

  • n - wykładnik (potęga)

Wyjście:

  • wynik - wynik potęgowania (a^n)

Lista kroków:

K1:   Jeśli n = 0  
      zwróć 1   (Każda liczba do potęgi 0 to 1)
K2:   Jeśli n % 2 = 0  
      to wynik ← SzybkiePotRekurencyjne(a * a, n / 2)   (Dzielimy wykładnik przez 2, kwadratujemy bazę)
K3:   Jeśli n % 2 = 1  
      to wynik ← a * SzybkiePotRekurencyjne(a, n - 1)   (Jeśli wykładnik nieparzysty, pomnóż przez bazę i zmniejsz wykładnik o 1)
K4:   Zwróć wynik   (Zwracamy końcowy wynik)

Wynik działania programu:

Podaj baze (a): 3
Podaj wykladnik (n): 5
3^5 = 243