Wprowadzenie do algorytmiki Pojecie algorytmu Powszechnie przyjmuje się, że algorytm jest opisem krok po kroku rozwiązania postawionego problemu lub sposób osiągnięcia jakiegoś celu. Wywodzi się z matematyki i informatyki, ale ostatnio stał się również popularnym synonimem przepisu lub instrukcji postępowania. W literaturze fachowej termin algorytm jest w różny sposób określany lub wyjaśniany. Poniżej przedstawione zostały przykłady definicji tego terminu. S. Węgrzyn algorytm definiuje w następujący sposób: Przez algorytm będziemy rozumieć( ) skończony ciąg operacji wraz z ściśle sprecyzowanym porządkiem ich wykonywania, które po realizacji dają rozwiązanie dowolnego zadania z określonej klasy 1. L. Banachowski i A. Kreczmar przyjmują, że: Algorytmem nazywa się najczęściej przepis postępowania, który ma prowadzić w sposób autonomiczny do rozwiązania określonego zadania. Ten przepis postępowania powinien być na tyle precyzyjny, aby posługiwanie się nim polegało tylko na automatycznym wykonywaniu instrukcji tego zapisu. Zakłada się przy tym, że pewne pierwotne instrukcje tego przepisu są wykonalne, to znaczy, że są one zdefiniowane i w algorytmie nie musi się ich definiować, ale można ich używać 2. Algorytm również określa się, jako dokładny przepis określanego zagadnienia, najczęściej przedstawiany w postaci skończonej sekwencji elementarnych (na danym poziomie) operacji, które należy wykonać 3. Cechy algorytmu poprawność, co oznacza, że dla każdego poprawnego zestawu danych, po wykonaniu skończonej liczby kroków otrzymujemy poprawny wynik; skończoność, co oznacza, że realizowany ciąg operacji powinien mieć swój koniec; określoność, co oznacza, że zarówno operacje, jak i porządek ich wykonywania powinny być ściśle określone, nie zostawiając miejsca na dowolną interpretację użytkownika; ogólność, co oznacza, ze ich stosowanie nie ogranicza się do jednego, pojedynczego, szczegółowego przypadku, ale odnosi się do pewnej klasy zadań; efektywność, co jest najtrudniejsze do zdefiniowania, a oznacza, że algorytm powinien prowadzić do rozwiązania możliwie prostą drogą; uniwersalność, co oznacza, że służy do rozwiązania pewnej grupy zadań, a nie tylko jednego zadania: np. algorytm który jest przepisem na rozwiązanie równania postaci 1 Węgrzyn S., Podstawy informatyki, PWN, Warszawa 1985. 2 Banachowski L., Kreczmar A., Elementy analizy algorytmów, WNT, Warszawa 1982. 3 Święcicki K., Walat A., Szkolny słownik informatyki, BGW, Warszawa 1987. str. 1
ax + b = 0 dla dowolnych współczynników a i b, a nie jednego konkretnego równania, np. 2x + 3 = 0. Sposoby zapisu algorytmu Algorytmy można przedstawić w następujący sposób: w języku naturalnym, za pomocą schematów blokowych, za pomocą drzewa, w języku formalnym, w języku programowania. Zestaw instrukcji umownego strukturalnego języka programowania W programowaniu strukturalnym korzysta się z pewnych prostych konstrukcji, z których można zbudować poprawny program. W tym celu wprowadzamy zestaw podstawowych instrukcji umownego języka programowania zwanego także pseudojęzykiem, który w dalszej części zostanie zastosowany do stworzenia przykładów algorytmów. W dużym stopniu będą one przypominały programy. Z tego powodu rozwiązania tych problemów nie będą nazywały się algorytmami, ale programami, mimo iż nie będą one zrozumiałe przez komputer. 1) Instrukcja przypisania: Z:=W; 2) Instrukcje wejścia/wyjścia: Podaj(x); Pisz(x); 3) Instrukcja złożona: POCZĄTEK Instrukcja1; Instrukcja2; Instrukcja3;. KONIEC; 4) Instrukcja warunkowa (decyzyjna). a) instrukcja warunkowa prosta: JEŚLI warunek TO instrukcja; b) instrukcja warunkowa złożona: JEŚLI warunek TO instrukcja1 W PRZECIWNYM RAZIE instrucja2; 5) Instrukcje iteracyjne. a) Instrukcja POWTARZAJ: POWTARZAJ instrukcję AŻ warunek; str. 2
b) Instrukcja DOPÓKI: DOPÓKI warunek WYKONUJ instrukcję; Operatory relacji Operator Znaczenie = równe <> nierówne (różne) < mniejsze > większe <= mniejsze lub równe >= większe lub równe Operatory logiczne Operator Znaczenie ang. Znaczenie NIE NOT zaprzeczenie I AND i LUB OR lub Metody przedstawiania algorytmów schematy blokowe Podstawowym i łatwym sposobem przedstawiania algorytmów (na podstawie którego opracowuje się później program) jest schemat blokowy, który jest traktowany jako algorytm problemu. Jest graficznym przedstawieniem zbioru instrukcji i wzajemnych powiązań między nimi, które określają kolejność wykonywanych instrukcji. Schemat blokowy jest zbudowany z figur geometrycznych zwanych skrzynkami oraz połączeń między skrzynkami. Oto podstawowe zestaw skrzynek stosowanych do budowy schematów blokowych: 1) Skrzynki graniczne START/STOP mają kształt owalu; wskazują początek i koniec wykonywania schematu blokowego. Ze skrzynki START wychodzi tylko jedno połączenie, natomiast skrzynka STOP nie ma połączenia wychodzącego. START STOP str. 3
2) Skrzynka operacyjna jest prostokątem, w którym znajdują się instrukcje. Ze skrzynki operacyjnej wychodzi tylko jedno połączenie. instrukcja 3) Skrzynka warunkowa (decyzyjna) jest rombem, w którym umieszcza się warunek decyzyjny o dalszej kolejności wykonywania operacji. Ze skrzynki wychodzą dwa połączenia: jedno oznaczone przez T (TAK), a drugie oznaczone przez N (NIE). W N T 4) Skrzynka wprowadzania i wyprowadzania informacji jest równoległobokiem, którym umieszcza się dane lub wyniki. Ze skrzynki wychodzi jedno połączenie. WE / WY Przykłady algorytmów Przykład 1. Suma dwóch liczb rzeczywistych (algorytm sekwencyjny liniowy). Specyfikacja problemu: Dane wejściowe: a, b liczby rzeczywiste dla których wyznaczamy sumę. Wynik: S liczba rzeczywista równa sumie liczb a i b. Lista kroków: str. 4
K01: Czytaj a, b; K02: S:= a + b; K03: Pisz S; K04: Zakończ algorytm. Schemat blokowy W powyższym przykładzie kolejne instrukcje wykonywane są w porządku, w jakim zostały wprowadzone. Mówimy, że takie algorytmy i programy posiadają strukturę sekwencyjną (liniową). Przykład 2. Max(a,b) (algorytm z rozgałęzieniami). Specyfikacja problemu: Dane wejściowe: a, b liczby rzeczywiste dla których wyznaczamy liczbę większą. Wynik: max liczba rzeczywista równa liczbie większej z danych a, b. Lista kroków: K01: Czytaj a, b; K02: Jeśli a > b, to max:= a w przeciwnym razie max:= b; K05: Pisz max; K06: Zakończ algorytm. Schemat blokowy str. 5
W powyższym algorytmie wykonanie instrukcji: max:=a; i max:=b; uzależniona jest od wyniku warunku a > b. Jeśli warunek będzie spełniony to wykonana zostanie instrukcja pierwsza, w przeciwnym razie instrukcja druga, a więc dalsze wykonanie algorytmu może być zrealizowane na dwa sposoby (drogi realizacji rozgałęziają się). Jest to przykład algorytmu z rozgałęzieniami. Przykład 3. Liczba pierwsza. (algorytm z pętlą). Algorytm badania, czy dowolna liczba naturalna n > 1 jest liczbą pierwszą, tzn., czy jest podzielna tylko przez 1 i samą siebie. Specyfikacja problemu: Dane wejściowe: n dowolna liczba naturalna większa od 1. Wynik: informacja czy podana liczba n jest liczbą pierwszą, czy też nie jest liczbą pierwszą. Zmienne pomocnicze: i - pełni rolę zmiennej sterującej pętlą i wartością kolejnych liczb naturalnych mniejszych lub równych połowie liczby n, i należy do zbioru liczb naturalnych. Lista kroków: K01: Czytaj n; K02: i:= 2; K03: Dla i n/2: Jeśli (n mod i) = 0, to Pisz (Liczba nie jest pierwsza); K05; str. 6
K04: Pisz (Liczba jest pierwsza); K05: Zakończ algorytm. Schemat blokowy Powyższy algorytm zawiera blok instrukcji który jest wielokrotnie powtarzany. Liczba tych powtórzeń nie zawsze jest dokładnie określona i przeważnie zależy od postawionych warunków. Wielokrotne powtarzanie instrukcji umożliwiają instrukcje iteracyjne nazywane krótko pętlami. Przykłady algorytmów klasycznych Przykład 1. Algorytm Euklidesa. Algorytm znajdowania największego wspólnego dzielnika (NWD) dwóch różnych liczb naturalnych. Nie wymaga rozkładania liczb na czynniki pierwsze. Ten algorytm jest jednym z najstarszych przepisów - schematów obliczeń. Jest on pomysłowy i szybko daje wynik. Specyfikacja problemu: Dane wejściowe: a, b liczby naturalne dla których wyznaczamy NWD. Wynik: NWD liczba naturalna równa największemu wspólnemu dzielnikowi liczb a i b. Lista kroków: K01: Czytaj a, b; str. 7
K02: Dopóki a b: wykonuj krok K03; K03: Jeżeli a > b, to a:= a b w przeciwnym razie b:= b a; K04: NWD:= a; K05: Zakończ algorytm. Przykład. Obliczmy tym sposobem NWD dla liczb 24 i 15. 1) 24-15 = 9 Od większej liczby odejmujemy mniejszą. Liczby 24 i 15 przechodzą w 15 i 9. Ponieważ nie są one równe, wykonujemy dalej odejmowanie 2) 15-9 = 6 Teraz otrzymujemy parę 9 i 6, która dalej nie składa się z liczb sobie równych, więc kontynuujemy odejmowanie. 3) 9-6 = 3 Para 6 i 3 - odejmujemy dalej 4) 6-3 = 3 Para 3 i 3 - otrzymaliśmy równość, więc liczba 3 jest największym wspólnym podzielnikiem liczb 24 i 15. Schemat blokowy Po odczytaniu wartości liczb a i b rozpoczynamy pętlę, która przerwie się, gdy w wyniku działania algorytmu liczba a będzie równa liczbie b. W takim przypadku dowolna z tych liczb jest największym wspólnym dzielnikiem pierwotnych wartości i wyprowadzamy ją. W przeciwnym wypadku jedna z liczb a lub b jest większa od drugiej. Odejmujemy więc liczbę mniejszą od większej i kontynuujemy pętlę, aż do zrównania wartości a i b. str. 8
START Czytaj(a,b); a b N T T a < b N Pisz(a); STOP b:= b - a; a:= a - b; Przykład 2. Liczba dokonała. Algorytm znajdowania liczby naturalnej, która jest sumą wszystkich swoich dzielników (mniejszych od niej). Najmniejszą liczbą doskonałą jest 6, ponieważ 6 = 1*2*3=1+2+3. Specyfikacja problemu: Dane wejściowe: n liczba naturalna. Wynik: informacja czy podana liczba n jest liczbą doskonałą, czy też nie jest liczbą doskonałą. Zmienne pomocnicze: i - pełni rolę zmiennej sterującej pętlą i wartością kolejnych liczb naturalnych mniejszych lub równych połowie liczby n, i należy do zbioru liczb naturalnych. Lista kroków: str. 9
K01: Czytaj n; K02: suma:=0; i:=1; K03: Dla i n/2: Jeśli (n mod i) = 0, to suma:= suma + i; i:= i + 1; w przeciwnym razie K4; K04: Jeśli n = suma, to Pisz (Liczba jest doskonała); w przeciwnym raz Pisz (Liczba nie jest doskonała); K05: Zakończ algorytm. Schemat blokowy Przykład 2. Max(a,b,c) (algorytm z rozgałęzieniami). Specyfikacja problemu: str. 10
Dane wejściowe: a, b, c liczby rzeczywiste dla których wyznaczamy liczbę większą. Wynik: max liczba rzeczywista równa liczbie większej z danych a, b, c. Lista kroków: K01: Czytaj a, b, c; K02: max:= a; K03: Jeśli max < b, to max:= b; K04: Jeśli max < c, to max:= c; K05: Pisz max; K06: Zakończ algorytm. Schemat blokowy str. 11
Literatura: [1] Nowakowski Z., Sikorski W., Informatyka bez tajemnic cz. III, MICOM, Warszawa 1996. [2] Kingsley-Hughes A., Kingsley-Hughes K., Od podstaw programowanie, Helion, 2006. [3] Suraj Z., Rumak T., Algorytmiczne rozwiązywanie zadań i problemów, WO FOSZE, Rzeszów, 1995. str. 12