Przeanalizujmy działanie algorytmu Euklidesa w wersji z odejmowaniem. Oto jego realizacja w języku Python:

Linia 1. def NWD podkreślnik odejmowanie otwórz nawias okrągły x przecinek y zamknij nawias okrągły dwukropek. Linia 2. while x wykrzyknik znak równości y dwukropek. Linia 3. if x zamknij nawias ostrokątny y dwukropek. Linia 4. x minus znak równości y. Linia 5. else dwukropek. Linia 6. y minus znak równości x. Linia 8. return x.

Wyznaczmy przykładowe NWD, używając powyżej zdefiniowanej funkcji:

Linia 1. NWD podkreślnik odejmowanie otwórz nawias okrągły 720424 przecinek 4 zamknij nawias okrągły. Linia 2. 4. Linia 3. NWD podkreślnik odejmowanie otwórz nawias okrągły 9203523424 przecinek 23 zamknij nawias okrągły. Linia 4. 1.

Spróbujmy wykorzystać tę metodę w przypadku dużych liczb. W języku Python istnieje ograniczenie maksymalnej wartości typu int. Możemy to sprawdzić, wywołując odpowiednie właściwości modułów sys oraz platform:

Linia 1. import sys. Linia 2. print otwórz nawias okrągły sys kropka maxsize zamknij nawias okrągły. Linia 3. 9223372036854775807. Linia 4. import platform. Linia 5. print otwórz nawias okrągły platform kropka uname otwórz nawias okrągły zamknij nawias okrągły zamknij nawias okrągły. Linia 6. uname podkreślnik result otwórz nawias okrągły system znak równości apostrof Linux apostrof przecinek node znak równości apostrof zorin minus desktop apostrof przecinek release znak równości apostrof 5 kropka 0 kropka 0 minus 31 minus generic apostrof przecinek. Linia 7. version znak równości apostrof kratka 33 tylda 18 kropka 04 kropka 1 minus Ubuntu SMP Tue Oct 1 10 dwukropek 20 dwukropek 39 UTC 2019 apostrof przecinek. Linia 8. machine znak równości apostrof x86 podkreślnik 64 apostrof przecinek processor znak równości apostrof x86 podkreślnik 64 apostrof zamknij nawias okrągły.

Zatem największą liczbą całkowitą, którą możemy podać w 64‑bitowym systemie Linux, jest:

9223372036854775807

Oto wersja programu, która liczy, ile operacji odejmowania należy wykonać podczas wyznaczania NWD:

Linia 1. def NWD podkreślnik odejmowanie podkreślnik zliczanie otwórz nawias okrągły x przecinek y zamknij nawias okrągły dwukropek. Linia 2. odejmowania znak równości 0. Linia 3. while x wykrzyknik znak równości y dwukropek. Linia 4. if x zamknij nawias ostrokątny y dwukropek. Linia 5. x minus znak równości y. Linia 6. else dwukropek. Linia 7. y minus znak równości x. Linia 8. odejmowania plus znak równości 1. Linia 10. print otwórz nawias okrągły apostrof NWD apostrof przecinek x przecinek apostrof średnik liczba odejmowań apostrof przecinek odejmowania zamknij nawias okrągły.

Wyznaczmy NWD dla liczb o wiele mniejszych niż maksymalna wartość int zapisana w 64‑bitowym systemie Linux:

Linia 1. NWD podkreślnik odejmowanie podkreślnik zliczanie otwórz nawias okrągły 920354 przecinek 22 zamknij nawias okrągły. Linia 2. NWD 2 średnik liczba odejmowań 41839. Linia 3. kratka. Linia 4. NWD podkreślnik odejmowanie podkreślnik zliczanie otwórz nawias okrągły 9203523424 przecinek 22 zamknij nawias okrągły. Linia 5. NWD 2 średnik liczba odejmowań 418341979. Linia 7. NWD podkreślnik odejmowanie podkreślnik zliczanie otwórz nawias okrągły 927566801 przecinek 22 zamknij nawias okrągły. Linia 8. NWD 1 średnik liczba odejmowań 42162136.

Niewykluczone, że obliczenia zajmą ponad minutę. W przypadku bardzo dużych liczb program uruchomiony na szybkim komputerze mógłby pracować nawet kilkadziesiąt minut (ze względu na dużą liczbę operacji odejmowania). Przedstawiamy obraz z Monitora systemu – pokazuje on, że nawet proste obliczenia potrafią obciążać procesor:

RC1z2TvxYr5sZ1
Źródło: Contentplus.pl sp. z o.o., licencja: CC BY-SA 3.0.
1
Polecenie 1

Możemy zmierzyć czas niezbędny do obliczenia NWD. Spróbujmy napisać funkcję NWD_odejmowanie_zliczanie_czas(x, y), która oprócz liczby odejmowań poda czas niezbędny do ich wykonania.

Specyfikacja problemu:

Dane:

  • x, y – liczby całkowite

Wynik:

  • NWD – liczba całkowita, największy wspólny dzielnik liczb xy

  • odejmowania – liczba całkowita, liczba wykonanych operacji

  • t – czas trwania programu; liczba rzeczywista

R6QnFro3RAMwl
Wymyśl pytanie na kartkówkę związane z tematem materiału.

Na szczęście proces wyznaczania NWD da się zoptymalizowaćoptymalizacjazoptymalizować. Przeanalizujmy zmodyfikowaną wersję algorytmu, tzw. obliczanie NWD metodą dzielenia z resztą.

Oto implementacja algorytmu w języku Python:

Linia 1. def NWD podkreślnik modulo otwórz nawias okrągły x przecinek y zamknij nawias okrągły dwukropek. Linia 2. while y zamknij nawias ostrokątny 0 dwukropek. Linia 3. modulo znak równości x procent y. Linia 4. x znak równości y. Linia 5. y znak równości modulo. Linia 6. return x.

Wersja programu, która zlicza wykonane operacje, może wyglądać następująco:

Linia 1. def NWD podkreślnik modulo podkreślnik zliczanie otwórz nawias okrągły x przecinek y zamknij nawias okrągły dwukropek. Linia 2. dzielenia znak równości 0. Linia 3. while y zamknij nawias ostrokątny 0 dwukropek. Linia 4. modulo znak równości x procent y. Linia 5. x znak równości y. Linia 6. y znak równości modulo. Linia 7. dzielenia plus znak równości 1. Linia 9. print otwórz nawias okrągły apostrof NWD apostrof przecinek x przecinek apostrof średnik liczba dzieleń apostrof przecinek dzielenia zamknij nawias okrągły.

Wyznaczmy NWD dla dużych argumentów funkcji. Okaże się, że liczba wykonywanych operacji jest bardzo mała:

Linia 1. NWD podkreślnik modulo podkreślnik zliczanie otwórz nawias okrągły 927566801 przecinek 22 zamknij nawias okrągły. Linia 2. NWD 1 średnik liczba dzieleń 3.
1
Polecenie 2

Możemy obliczyć czas niezbędny do wyznaczenia NWD. Zdefiniujmy funkcję NWD_modulo_zliczanie_czas(x, y), która oprócz liczby operacji zmierzy także czas ich wykonania.

Specyfikacja problemu:

Dane:

  • x, y – liczby całkowite

Wynik:

  • NWD – liczba całkowita, największy wspólny dzielnik liczb xy

  • dzielenia – liczba całkowita, liczba wykonanych operacji

  • t – czas trwania programu; liczba rzeczywista

RNwx1csJkIKTW
Wymyśl pytanie na kartkówkę związane z tematem materiału.
Dla zainteresowanych

Możemy obliczyć NWD dla więcej niż dwóch liczb.

Obliczenie NWD dla trzech liczb odbywa się w dwóch etapach. Najpierw wyznaczamy NWD dla liczb pierwszej i drugiej oraz NWD liczb drugiej i trzeciej. Następnie obliczamy NWD dla otrzymanych wyników. Przedstawmy tę zasadę za pomocą pseudokodu:

Linia 1. obliczenie NWD otwórz nawias okrągły a przecinek b przecinek c zamknij nawias okrągły dwukropek. Linia 3. do zmiennej tymczasowej x przypisz NWD otwórz nawias okrągły a przecinek b zamknij nawias okrągły. Linia 4. do zmiennej tymczasowej y przypisz NWD otwórz nawias okrągły b przecinek c zamknij nawias okrągły. Linia 6. wynikiem będzie NWD otwórz nawias okrągły x przecinek y zamknij nawias okrągły. Linia 8. kratka inny sposób rozwiązania problemu dwukropek. Linia 9. NWD otwórz nawias okrągły a przecinek b przecinek c zamknij nawias okrągły znak równości NWD otwórz nawias okrągły NWD otwórz nawias okrągły a przecinek b zamknij nawias okrągły przecinek c zamknij nawias okrągły.
Problem 1

Algorytm Euklidesa wykorzystujący odejmowanie opiera swoje działanie o spostrzeżenie, że największy wspólny dzielnik jest równy największemu wspólnemu dzielnikowi mniejszej liczby i różnicy liczb większej oraz mniejszej.

Napisz program, który obliczy największy wspólny dzielnik dwóch liczb całkowitych dodatnich. Zaimplementuj algorytm Euklidesa, wykorzystując:

  • odejmowanie,

  • resztę z dzielenia.

Specyfikacja problemu:

Dane:

  • a, b – liczby całkowite

Wynik:

  • NWD – liczba całkowita, największy wspólny dzielnik liczby ab

R1GE0flVxkqol
Wymyśl pytanie na kartkówkę związane z tematem materiału.
Polecenie 3

Porównaj swoje rozwiązanie z przedstawionym w filmie.

RbNtfLMrgEPh1
Film nawiązujący do treści materiału: Algorytm Euklidesa zastosowanie różnych pętli.

Słownik

modulo
modulo

operacja wyznaczania reszty z dzielenia dwóch liczb; działanie takie oznaczane jest w Pythonie operatorem %

optymalizacja
optymalizacja

upraszczanie procesu, poszukiwanie najlepszego rozwiązania z punktu widzenia pewnego kryterium, np. liczby wykonywanych operacji przez procesor czy czasu niezbędnego do przeprowadzonych działań lub ilości zajmowanej pamięci