Wykład 4 Różne algorytmy - obliczenia 1. Obliczanie wartości wielomianu 2. Szybkie potęgowanie 3. Algorytm Euklidesa, liczby pierwsze, faktoryzacja liczby naturalnej 2017-11-24 Algorytmy i struktury danych W4 1
Obliczanie wartości wielomianu Postać ogólna wielomianu n go stopnia: w n x a 0 x n a 1 x n1... a n1 x a n (4.1) Po wyłączeniu przed nawias zmiennej x z prawie wszystkich składników wyrażenia otrzymuje się: w n n1 n2 a 0x a1x... an 1 x an Po kolejnych takich wyłączeniach przed nawias zmiennej x wyrażenie (4.1) przyjmie postać: w n x a0 x a1x a2 x an 1 x an (4.2) Jest to tzw. schemat Hornera - najszybszy sposób obliczania wartości wielomianu. 2017-11-24 Algorytmy i struktury danych W4 2
Obliczenie wartości y wielomianu n go stopnia wg powyższego schematu dla zadanej wartości zmiennej niezależnej x przebiega zatem wg następującego algorytmu: Dane: n - stopień wielomianu, a 0, a 1,..., a n - współczynniki, x - argument Wynik: Wartość wielomianu (4.1) 1 0 Zmiennej y przypisz wartość współczynnika a 0 przy najwyższej potędze argumentu. 2 0 Dla kolejnych wartości i = 1, 2,..., n obliczaj y := yx + a i Jest to algorytm typu iteracyjnego. Jego schemat blokowy pokazano na rys.4.1. 2017-11-24 Algorytmy i struktury danych W4 3
Rys.4.1. Schemat blokowy algorytmu Hornera w wersji iteracyjnej 2017-11-24 Algorytmy i struktury danych W4 5
Wyrażenie (4.1) można zapisać również w postaci rekurencyjnej jako: w n n 1x x an ( x) w (4.3) Wartość wielomianu n go stopnia obliczamy wówczas według reguły: w x w n a x 0 n 0 n (4.4) 1 x an n 1 Warunkiem zakończenia jest osiągnięcie wartości 0 przez zmniejszaną w każdej kolejnej rekurencji wartość n. Schemat blokowy tej wersji rekurencyjnej schematu Hornera przedstawia rysunek 4.2. 2017-11-24 Algorytmy i struktury danych W4 6
Rys.4.2. Schemat blokowy algorytmu Hornera w wersji rekurencyjnej 2017-11-24 Algorytmy i struktury danych W4 7
Szybkie potęgowanie Jak obliczyć np. wartość x 6. Wykonywanie kolejnych mnożeń x -x -x -x -x -x to pięć działań. Liczbę działań można zmniejszyć korzystając z równości 6 = 2 * 3; najpierw podnieść x do kwadratu, a następnie wynik - do trzeciej potęgi. Zamiast pięciu mnożeń, należy wykonać tylko trzy. Jeśli mielibyśmy podnieść x do potęgi 16, to wtedy wystarczyłoby wykonać tylko cztery mnożenia, zamiast piętnastu! Jeżeli na dodatek użyjemy binarnej postaci wykładnika potęgi 6 = (110) 2 i skorzystamy ze schematu Homera, to otrzymamy: x 6 x 1* 2 1* 2 2 2 x x 2017-11-24 Algorytmy i struktury danych W4 8
Każdą liczbę naturalną można przedstawić w postaci binarnej opisany sposób podnoszenia do potęgi ma charakter uniwersalny można go użyć dla dowolnego naturalnego wykłanika potęgi. Zasada tzw. binarnego potęgowania od lewej do prawej: najbardziej znaczący bit w rozwinięciu binarnym wykładnika - jest zawsze równy 1 odpowiada rozpoczęciu obliczeń od przyjęcia podstawy potęgi liczby za jej początkową wartość, każda następna pozycja w rozwinięciu odpowiada podniesieniu częściowego wyniku do kwadratu i pomnożeniu przez x, jeżeli bit rozwinięcia na tej pozycji jest równy 1, w przeciwnym przypadku mnożenia nie wykonujemy. 2017-11-24 Algorytmy i struktury danych W4 9
Kolejne kroki binarnego algorytmu potęgowania od-lewej-do-prawej: Dane: Liczba naturalna m (wykładnik potęgi) w postaci binarnej (m n m n-1...m 1 m 0 ) 2 i dowolna liczba x podstawa potegi. Wynik: Wartość y := x m. 1 o. y : = x. Ustalenie początkowej wartości potęgi. 2 o. Dla i = n l, n - 2,..., l, 0 - wykonuj: jeśli m i = 1, to y : = y*y*x, przeciwnym przypadku y : = y*y. Schemat blokowy tego algorytmu pokazuje rys. 4.3. 2017-11-24 Algorytmy i struktury danych W4 10
Rys.4.3. Szybkie potęgowanie metodą od lewej do prawej 2017-11-24 Algorytmy i struktury danych W4 11
Ile mnożeń należy wykonać, aby obliczyć x m? Wszystkie działania są wykonywane w kroku 2 o, dla kolejnych bitów w binarnym rozwinięciu wykładnika, z wyjątkiem bitu najbardziej znaczącego. Na każdej pozycji, bez względu na wartość bitu, wykonuje się mnożenie y*y, oraz, jeśli bit wynosi 1, to również dodatkowe mnożenie przez x. Liczba mnożeń w całym algorytmie jest równa liczbie wszystkich bitów w binarnej reprezentacji wykładnika, minus jeden, plus liczba jedynek w tej reprezentacji, również minus jeden, gdyż najbardziej znaczącej jedynce odpowiada początkowa wartość y = x i nie wykonuje się żadnego mnożenia. 2017-11-24 Algorytmy i struktury danych W4 12
Algorytm potęgowania binarnego metodą od lewej do prawej ma pewną wadę. Rozwinięcie binarne liczby tworzy się od najmniej znaczącego bitu, czyli od prawej do lewej. Liczby naturalne są pamiętane w komputerze w postaci binarnej, dana jest zatem binarna reprezentacja wykładnika. Aby jednak z niej skorzystać, należy "dotrzeć" do poszczególnych bitów. Najłatwiej to zrobić, stosując algorytm, który tworzy na bieżąco taką właśnie reprezentację bit po bicie. Jak? Inny algorytm potęgowania też korzysta binarnej reprezentacji wykładnika, ale tworzy ją w trakcie obliczania potęgi, w takiej kolejności jak przy konwersji liczby z systemu dziesiętnego na dwójkowy czyli od prawej do lewej (kolejno od bitu najmniej znaczącego do najbardziej znaczącego). 2017-11-24 Algorytmy i struktury danych W4 13
Opis binarnego algorytmu potęgowania od prawej do lewej ma postać: Dane: Liczba naturalna m wykładnik i dowolna liczba x - podstawa. Wynik: Wartość potęgi y := x m, 1 o Ustalenie początkowych wartości potęgi i zmiennych: y := 1, z := x, p := m. 2 o q := p mod 2 - czy p jest parzyste? (operator mod oblicza resztę z dzielenia; w C/C++, C# operator %) 3 o p:=p div 2. Jeżeli q = 1, to przejdź do 4 o, w przeciwnym przypadku idź do 6 o (operator div oblicza część całkowitą ilorazu) 4 o y:=y *z. 5 o Jeżeli p = 0, to zakończ obliczenia - wynikiem jest bieżąca wartość y. 6 o z : = z * z. i wróć do 2 o. Rysunek 4.4 przedstawia schemat blokowy opisanego wyżej algorytmu. 2017-11-24 Algorytmy i struktury danych W4 14
Rys.4.4. Algorytm szybkiego potęgowania metodą od prawej do lewej 2017-11-24 Algorytmy i struktury danych W4 15
Istnieje też, rekurencyjna wersja algorytmu szybkiego obliczania potęgi x m. Wykorzystano w niej następującą definicję m. tej potęgi liczby x: x m x m x 2 m1 2 x m 1 2 m parzyste 2 m nieparzyst e x Rekurencyjnie obliczana będzie wartość kwadratu liczby x dla kolejno malejących wartości wykładnika. Warunkiem zakończenia obliczeń jest osiągnięcie przez zmienną m wartości 1. Schemat blokowy tej wersji algorytmu pokazano na rys.4.5. 2017-11-24 Algorytmy i struktury danych W4 16
Rys. 4.5. Wersja rekurencyjna algorytmu potęgowania od prawej do lewej 2017-11-24 Algorytmy i struktury danych W4 17
Algorytm Euklidesa, liczby pierwsze Algorytm Euklidesa został odkryty jako jeden z najwcześniejszych, jeszcze w starożytności, właśnie przez Euklidesa. Największym wspólnym dzielnikiem dwóch nieujemnych liczb całkowitych n i m jest taka największa liczba całkowita k, przez którą dzielą się bez reszty liczby n oraz m. Liczbę k będziemy dalej oznaczać jako wartość funkcji NWD(n, m), a jej wartość pozwala wyznaczyć algorytm Euklidesa. Załóżmy dalej, że n m. Po podzieleniu n przez m otrzymamy: n = qm + r, gdzie 0 r < m (4.5) W równaniu tym q jest całkowitą wartością ilorazu (największa liczba całkowita, nie większa niż n/m), a r - resztą z dzielenia. 2017-11-24 Algorytmy i struktury danych W4 18
Jeżeli r = 0, to NWD(n, m) = m - mniejsza z dwóch danych liczb jest ich największym wspólnym dzielnikiem, a jeżeli r 0, to wyrażenie (4.5) można zapisać w postaci r = n - qm co oznacza, że każda liczba dzieląca n i m dzieli całe wyrażenie po prawej stronie, dzieli również r. Największy wspólny dzielnik n i m dzieli również resztę r: NWD(n, m) = NWD(m, r) gdzie NWD(0, q) = q. Działania algorytmu Euklidesa przebiegają wg następującego schematu: Dane: Dwie liczby naturalne n i m (n m). Wynik: NWD(n, m) - największy wspólny dzielnik n i m 1 o Jeżeli m = 0, to n jest szukanym dzielnikiem. 2 o Oblicz r := n mod m i podstaw n := m, m := r. Wróć do 1 o Schemat blokowy przedstawia rys.4.6. 2017-11-24 Algorytmy i struktury danych W4 19
Rys.4.6. Algorytm Euklidesa znajdowania największego wspólnego podzielnika 2017-11-24 Algorytmy i struktury danych W4 20
Rekurencyjna wersja algorytmu obliczania największego wspólnego podzielnika dwóch liczb naturalnych wynika ze stwierdzenia, że: NWD n, m NWD n m, n mod m m m 0 0 Schemat blokowy rekurencyjnej wersji algorytmu Euklidesa przedstawia rys.4.7. Rys.4.7. Rekurencyjna wersja Algorytmu Euklidesa 2017-11-24 Algorytmy i struktury danych W4 21
Wykonując działania na ułamkach musimy znaleźć wartość najmniejszej wspólnej wielokrotności (NWW) dwóch liczb naturalnych n oraz m. Związek pomiędzy wartością NWW(n, m) oraz NWD(n, m) przedstawia wzór: NWW n, m mn NWD n, m a obliczenia przebiegają wg schematu: Dane: Liczby naturalne n, m (n m) Wynik: Najmniejsza wspólna wielokrotność NWW(n, m) 1 o Oblicz NWD(n, m) wg algorytmu Euklidesa 2 o Oblicz NWW(n, m) jako równe m*(n div NWD(n, m)) 2017-11-24 Algorytmy i struktury danych W4 22
Liczba naturalna jest pierwsza, jeśli dzieli się tylko przez 1 i przez samą siebie. Liczbę naturalną, która nie jest pierwszą, nazywa się liczbą złożoną. Liczba złożona ma dzielniki, które są różne od 1 i od niej samej na przykład, 24 nie jest liczbą pierwszą, gdyż jest podzielna przez liczby: 2, 3, 4, 6, 8 i 12. Czynnikiem liczby złożonej jest jej dzielnik, który jest liczbą pierwszą. Czynnikami liczby 24 są tylko liczby 2 i 3, gdyż pozostałe jej dzielniki nie są liczbami pierwszymi. Rozkładem liczby na czynniki (pierwsze) lub jej faktoryzacją nazywa się przedstawienie liczby w postaci iloczynu jej czynników pierwszych z uwzględnieniem ich krotności. Liczba 24 ma rozkład na czynniki 2 * 2 * 2 * 3 = 2 3 * 3. 2017-11-24 Algorytmy i struktury danych W4 23
Najczęściej działania z liczbami pierwszymi sprowadzają się do rozwiązania jednego z dwóch problemów: Należy sprawdzić, czy dana liczba naturalna n jest liczbą pierwszą, a jeżeli nie jest, to podać jej rozkład na czynniki pierwsze. Znaleźć wszystkie liczby pierwsze w zadanym przedziale [m, n]. Algorytm sprawdzania, czy dana liczba naturalna n > 1 jest liczbą pierwszą przebiega według następującego schematu: Dane: Liczba naturalna n > 1 Wynik: Wartość prawda jeżeli n jest liczbą pierwszą i fałsz w przeciwnym przypadku. 1 o Przyjmij m = 2 2 o Oblicz r := n mod m, jeżeli r = 0, to n nie jest liczbą pierwszą. Zakończ z wartością fałsz, w przeciwnym przypadku przejdź do 3 o 3 o Podstaw n := n div m m 4 o Sprawdź czy jeżeli tak, to zwiększ m o 1 i wróć do 2 o, w przeciwnym przypadku zakończ z wartością prawda. Schemat blokowy przedstawia rys.4.8 n 2017-11-24 Algorytmy i struktury danych W4 24
Rys.4.8. Sprawdzanie czy n jest liczbą pierwszą (sqrt(n) to funkcja, która oblicza pierwiastek kwadratowy z liczby n 2017-11-24 Algorytmy i struktury danych W4 25
Algorytm faktoryzacji liczby naturalnej n czyli przedstawienia jej w postaci n = p 1 p 2 p k gdzie p 1 p 2 p k są kolejnymi liczbami pierwszymi składa się z następujących kroków: Dane: Liczba naturalna n oraz ciąg jej możliwych dzielników: 2 = d 0 < d 1 < d 2 <..., który zawiera wszystkie liczby pierwsze mniejsze lub równe oraz liczbę, która nie jest mniejsza od. n Ponieważ znajdowanie ciągu kolejnych liczb pierwszych jest pracochłonne, w algorytmie stosujemy ciąg dzielników, który oprócz liczb pierwszych może zawierać jeszcze inne liczby. Wynik: Rozkład liczby n na czynniki lub informacja, że n jest liczbą pierwszą. 2017-11-24 Algorytmy i struktury danych W4 26
1 o Ustal początkowe wartości indeksów czynników i dzielników k := 0, i := 0; 2 o Jeśli n = 1, to zakończ działania. 3 o Dzielenie przez kolejny dzielnik: q : = n div d i, r: = n mod d i. 4 o Jeśli r 0, to przejdź do 6 o. 5 o Znaleziono kolejny czynnik: k := k + 1, p k := d t ; n := q. Wróć do 2 o. 6 o Jeśli q > d i, to przypisz i := i + 1 i przejdź do 3 o. 7 o n jest ostatnim dzielnikiem - przypisz k := k + 1 oraz p k := n i zakończ pracę. 2017-11-24 Algorytmy i struktury danych W4 27
Rysunek 4.9 przedstawia schemat blokowy zmodyfikowanej wersji przedstawionego wyżej algorytmu faktoryzacji zadanej liczby naturalnej. W rozwiązaniu tym nie podaje się początkowych wartości możliwych dzielników liczby n. Kolejne dzielniki liczby pierwsze dla każdego kolejnego ilorazu generuje funkcja Czynnik. Funkcja Pierwsza sprawdza, czy podana jako jej argument liczba jest pierwsza (zwraca wartość prawda), czy nie (zwraca fałsz). Kolejno wyznaczone czynniki pierwsze zapisuje się w tablicy C. 2017-11-24 Algorytmy i struktury danych W4 28
Rys.4.9. Algorytm faktoryzacji liczby naturalnej 2017-11-24 Algorytmy i struktury danych W4 29