Algorytm w matematyce oraz informatyce to skończony, uporządkowany zbiór jasno zdefiniowanych czynności, koniecznych do wykonania pewnego zadania, w ograniczonej liczbie kroków. Algorytm ma przeprowadzić system z pewnego stanu początkowego do pożądanego stanu końcowego. Badaniem algorytmów zajmuje się algorytmika. Algorytm może zostać zaimplementowany w postaci programu komputerowego lub innego urządzenia. Kiedy podczas tego procesu programiści popełnią błąd (ang. bug), może to doprowadzić do poważnych konsekwencji np. błędy w implementacji algorytmów bezpieczeństwa mogą ułatwić popełnienie przestępstwa komputerowego.
Jako przykład stosowanego w życiu codziennym algorytmu podaje się często przepis kulinarny. Dla przykładu, aby ugotować bigos należy w określonej kolejności oraz odstępach czasowych (imperatyw czasowy) dodawać właściwe rodzaje kapusty i innych składników. Może istnieć kilka różnych przepisów dających na końcu bardzo podobną potrawę. Przykład ten ma wyłącznie charakter poglądowy, ponieważ język przepisów kulinarnych nie został jasno zdefiniowany. Algorytmy zwykle formułowane są w sposób ścisły w oparciu o język matematyki.
W niektórych krajach, jak USA, algorytmy mogą zostać opatentowane, jeżeli zostaną zaimplementowane w jakimś praktycznym celu. Niektórzy twierdzą, że patentowanie algorytmów spowalnia rozwój informatyki, bo jeden producent może uzyskać monopol, np. na pisanie oprogramowania tworzącego pewne typy plików (np. GIF). Wiele koncernów komputerowych prowadzi między sobą prawnicze spory dotyczące własności do niektórych patentów. Kontrargumentem jest tzw. prawo własności intelektualnej, jaką objęty jest np. utwór muzyczny, będący wytworem intelektu i pracy muzyka, zakładające, że program jest intelektualną własnością twórcy.
Algorytmy komputerowe
Implementacja
Komputery przetwarzają przekazywane im informacje z wykorzystaniem pewnych algorytmów. Program jest algorytmem zapisanym w języku zrozumiałym dla maszyny (
asemblerze). Każdy kod maszynowy da się przełożyć na zestaw instrukcji dla
maszyny Turinga.
Zwykle algorytmy pracują na pewnych danych wejściowych i uzyskują z nich dane wyjściowe. Informacje zapisane w pamięci maszyny traktuje się jako jej stan wewnętrzny. Niektóre algorytmy mają za zadanie wyłącznie przeprowadzanie komputera z jednego stanu wewnętrznego do innego.
Każdy algorytm komputerowy musi być wyrażony w bardzo rygorystycznie zdefiniowanym języku. Ludzie często komunikując się przesyłają między sobą informację wieloznaczne. Komputery mogą reagować tylko na całkowicie jednoznaczne instrukcje. Jeżeli dany algorytm da się wykonać na maszynie o dostępnej mocy obliczeniowej i pamięci oraz akceptowalnym czasie, to mówi się że jest obliczalny.
Poprawne działanie większości algorytmów implementowanych w komputerach opiera się na kolejnej realizacji pewnego zestawu warunków. Jeżeli, któryś z nich nie zostanie spełniony, to program kończy się komunikatem błędu. Czasami podczas implementacji algorytmu ważny warunek zostanie pominięty
Dla przykładu, mamy program dzielący przez siebie dwie liczby. Użytkownik każe mu dzielić przez zero. Aplikacja bez sprawdzenia warunku “dzielnik nierówny zero” zawiesi się w takiej sytuacji.
Algorytm a opisujący go język
Należy zdawać sobie sprawę z różnicy między algorytmem, będącym "niezależnym" od jego implementacji przepisem, a programem, który może zostać zinterpretowany i wykonany przez komputer. Przykładowo, poniższe fragmety programów są realizacją tego samego "algorytmu", sumującego trzy trójki:
Dodawanie w języku C:
wynik=3;
wynik+=3;
wynik+=3;
Ten sam język, ale z pętlą:
wynik=0;
for(int i=0;i<3;i++) wynik+=3;
Język C, zapis proceduralny:
int alg(int n)
{
if(n==3) return 0;
else return 3 + alg(n+1);
}
void main()
{
int wynik = alg(0);
}
Asembler:
move acc, 0 #kopiuje 0 do akumulatora
add acc, 3 #dodaje 3 do akumulatora
add acc, 3
add acc, 3
move EF21A29C, acc #kopiuje zawartość akumulatora do komórki pamięci – adres w hex
Powyższe "programy" napisane są w różnych językach programowania, używających różnych poziomów abstrakcji, przy czym zapis w asemblerze jest na najniższym poziomie abstrakcji, tj. jest najbliżej "prawdziwego", wykonywanego bezpośrednio przez procesor komputera, kodu.
Klasyfikacja
Istnieje wiele różnych sposobów podziału algorytmów na grupy. Problem ten wzbudza kontrowersje.
Podstawowe paradygmaty tworzenia algorytmów komputerowych:
- dziel i zdobywaj – dzielimy problem na kilka mniejszych i je znowu dzielimy, aż ich rozwiązania nie staną się oczywiste (rekurencja),
- programowanie dynamiczne – problem dzielony jest na kilka, ważność każdego z nich jest oceniana i po pewnym wnioskowaniu wyniki analizy niektórych prostszych zagadnień wykorzystuje się do rozwiązania głównego problemu,
- metoda zachłanna – nie analizujemy podproblemów dokładnie, tylko wybieramy najbardziej obiecującą w tym momencie drogę rozwiązania,
- programowanie liniowe – oceniamy rozwiązanie problemu przez pewną funkcję jakości i szukamy jej minimum,
- poszukiwanie i wyliczanie – kiedy przeszukujemy zbiór danych aż do odnalezienie rozwiązania,
- probabilistyczne rozwiązanie – algorytm działa poprawnie z bardzo wysokim prawdopodobieństwem, ale wynik nie jest pewny,
- heurystyka – człowiek na podstawie swojego doświadczenia tworzy algorytm, który działa w najbardziej prawdopodobnych warunkach, rozwiązanie zawsze jest przybliżone.
Najważniejsze techniki implementacji algorytmów komputerowych
- proceduralność – algorytm dzielimy na szereg podstawowych procedur, wiele algorytmów dzieli wspólne biblioteki standardowych procedur, z których są one wywoływane w razie potrzeby,
- praca po kolei – wykonywanie kolejnych procedur algorytmu, według kolejności ich wywołań, na raz pracuje tylko jedna procedura,
- praca równoległa – wiele procedur wykonywanych jest w tym samym czasie, wymieniają się one danymi,
- rekurencja – procedura wywołuje sama siebie, aż do uzyskania wyniku lub błędu,
- obiektowość – procedury i dane łączymy w pewne obiekty reprezentujące najważniejsze elementy algorytmu oraz stan wewnętrzny wykonującego je urządzenia.
Przykłady
Błędy w implementacji
Kiedy komputery stały się powszechne, algorytmy zaczęto masowo wykorzystywać do rozwiązywania problemów życia codziennego. Dzisiaj w miliardach maszyn cyfrowych działają niezliczone zastępy umieszczonych w nich programów. Wiele z nich oblicza stan konta w banku, inne kompresują dźwięk podczas rozmowy telefonicznej, a niektóre z nich dbają o sprawność wyświetlania strony Wikipedii. Jednak rewolucja cyfrowa niesie ze sobą niebezpieczeństwo błędnych implementacji algorytmów. Kody źródłowe programów zabezpieczających większość dzisiejszych systemów przed niepowołanym atakiem mogą okazać się pełne błędów. W takiej sytuacji są one narażone na atak
cyberterrorystyczny na światową skalę. Ratunkiem jest tutaj stosowanie jawnych implementacji algorytmów, których
kod źródłowy jest otwarty dla każdego. W ten sposób zwiększa się szansa na odnalezienie błędów i ich szybką naprawę. Nie mniej ważne jest stałe aktualizowanie najważniejszych programów przez administratorów ważnych
sieci komputerowych. Oczywiście może to być
broń obusieczna - wystarczy wyobrazić sobie sytuację w której osoba o złych intencjach dostrzega, i wykorzystuje błąd w kodzie źródłowym programu.
Większość nowoczesnych środowisk programistycznych dostarcza tzw. debugery - programy wspomagające wykrywanie błędów w kodzie programu, poprzez np. możliwość dokładnego prześledzenia jego działania z wglądem na wartości zmiennych.
Wciąż rozwijana inżynieria oprogramowania pozwala na tworzenie aplikacji których kod żródłowy ma setki tysięcy lini, przy równoczesnym zachowaniu kontroli nad całością projektu, jednak, choćby ze względu na statystykę, błędy w programach prawdopodobnie zawsze będą towarzyszyć (coraz większym) projektom.
Algorytmy poza komputerami
Implementacja algorytmu w ogólności oznacza występowanie pewnego podobieństwa pomiędzy algorytmem opisanym w ludzkim języku do fizycznego zjawiska lub procesu. Czasami algorytm może być podstawą budowy przez ludzi urządzenia, jak np. komputer. Jednak o implementacji możemy mówić również, kiedy pewien system zachowuje się podobnie do algorytmu. Dla przykładu mózg ptaka implementuje arytmetykę w postaci
sieci neuronowej. Dzięki temu zwierzę jest w stanie porównywać pewne odstępy czasu. W przypadku maszyn algorytm może zostać zaimplementowany jako pewna sieć połączeń elektrycznych, pneumatycznych bądź mechanicznych. Przykładem może być tutaj analogowy regulator obrotów z pierwszych
silników parowych, realizujący algorytm P (proporcjonalny). Przy takim podejściu sukces nie oznacza zatrzymanie algorytmu, lecz utrzymywanie pewnego stanu systemu. Możemy np. powiedzieć, że algorytm utrzymywania życia działa poprawnie, aż do śmierci organizmu. Poprawny algorytm ma utrzymywać pewne parametry żywej istoty (np.
temperaturę) w optymalnym zakresie.
Przyszłość algorytmów
Ograniczenia algorytmów
Prawie każdy algorytm komputerowy musi kiedyś zakończyć swoją pracę. Oznacza to, że problem musi być rozwiązany z wykorzystaniem dostępnych zasobów obliczeniowych w skończonym czasie. Jeżeli algorytm dla coraz większego zbioru danych powoduje wzrost czasu obliczeń szybciej niż to wynikałoby z funkcji wielomianowej, to mówi się że nie jest praktycznie obliczalny. Gdy kryterium braku obliczalności jest spełnione dla implementacji algorytmu na maszynę Turinga, to wtedy określa się go jako problem N-P zupełny.
Algorytmy sztucznej inteligencji
Większość problemów związanych z codziennym życiem to problemy N-P zupełne. Przykłady to odnajdywanie najkrótszej drogi, składanie układanki, czy odnajdywanie błędów w programach. Oznacza to, że algorytmy mogą radzić sobie w takimi problemami tylko w przybliżeniu lub bardzo szczególnej sytuacji. Sterowany algorytmem przybliżonym robot nie potrafi odnaleźć najkrótszej drogi w bardzo złożonym środowisku, mimo że dla człowieka może być ona oczywista.
Inżynierowie próbują rozwiązywać problemy N-P zupełne przez naśladowanie żywych organizmów. Jeżeli nie da się sformułować jasnego algorytmu rozwiązującego dany problem, można maszynę wyposażyć w zdolność do samodzielnego uczenia się. Zagadnieniem tym zajmuje się dział określany jako sztuczna inteligencja. Tego podejścia nie należy mylić z ludzką inteligencją. Maszyny naśladują tylko pewne cechy istot żywych, ale jak na razie nie są w stanie im dorównać na wielu polach.
Algorytmy kwantowe
Jednym z problemów N-P zupełnych jest łamanie kodów. Istnieją pewne algorytmy szyfrowania (
RSA,
DES), dla których szybkie znalezienie kluczy wymaga bardzo dużej mocy obliczeniowej. Tutaj rozwiązaniem mogą okazać się algorytmy zaimplementowane w
komputerach kwantowych. W odróżnieniu od komputerów elektronicznych opartych na
bitach, te kwantowe mają posługiwać się
qubitami oraz zjawiskiem
splątania. Pewne własności tych maszyn powodują, że niektóre problemy N-P zupełne dają się rozwiązać w jednym takcie obliczeń. Gdyby komuś udało się zbudować komputer
kwantowy byłby w stanie złamać wszystkie dzisiaj używane algorytmy kryptograficzne. Dużym problemem komputerów kwantowych jest
dekoherencja ich stanów. W ten sposób bardzo łatwo może dość do utraty danych. Rozwiązaniem ma być tutaj wykorzystanie splątania do
teleportacji stanu kwantowego na kolejne
cząstki elementarne. W związku z tym wielu naukowców pracuje już dziś nad implementacją algorytmów
kryptografii kwantowej. Przykładem jest tutaj szyfrowanie danych z wykorzystaniem splątanych
fotonów. Obecnie kierunki prac nad komputerami kwantowymi:
Algorytmy równoległe
Jednym ze sposobów rozwiązywania złożonych problemów jest zastosowanie algorytmów równoległych. Oznacza to, że program nie jest wykonywany tylko jeden raz na jednym
procesorze, ale równolegle na wielu różnych maszynach. Podejście to stosuje się od lat w
superkomputerach. Jednak w takiej realizacji jest ono bardzo kosztowne. Nowym pomysłem jest tutaj zastosowanie sieci zwykłych komputerów tworzących
klaster. Zadanie jest rozdzielane na wiele maszyn i
obliczane równolegle w tysiącach komputerów. Czasami taką potężną sieć nazywa się z j. angielskiego
grid. Przykłady to program
SETI@Home, gdzie dane z nasłuchu
kosmosu, analizowały dziesiątki tysięcy komputerów należących do zwykłych użytkowników. Maszyny były podłączone do
Internetu, przez który przesyłały wyniki pracy uruchomionych na nich aplikacji. Nowym pomysłem na implementację algorytmów równoległych jest wykorzystanie do tego
DNA. W jednej kropli
wody znajdują się miliony cząstek tego
kwasu. Jeżeli zsyntetyzujemy je tak, aby wykonywały pewien algorytm, to w ułamku sekundy potrzebnym na
reakcje chemiczne komputer oparty na DNA znajdzie rozwiązanie bardzo złożonego problemu. Przykładem są tutaj
bakterie, które zaprogramowano, aby mrugały rytmicznie światłem. Dziedzina nauki zajmująca się algorytmami w połączeniu z biologią to
bioinformatyka.
Przykład algorytmu
Wyobraź sobie że masz nieposortowaną listę przypadkowych liczb. Masz znaleźć największą z nich. Istnieje wiele algorytmów rozwiązujących ten problem. Jeden z najszybszych można przedstawić jako listę poleceń:
- Rozpocznij pracę
- Stwórz rejestr przechowujący bieżącą wartość elementu tabeli i wczytaj do niego pierwszy element listy, jeżeli to się nie uda wypisz na wyjście wartość błędną.
- Stwórz rejestr przechowujący największą liczbę, nadaj jej bieżącą wartość elementu tabeli.
- Początek pętli - wczytaj kolejny element tabeli, a jeżeli to się nie uda zakończ pętlę.
- Jeżeli bieżąca wartość elementu tabeli, jest większa od rejestru największej liczby, to wpisz ją do tego rejestru.
- Powróć do początku pętli.
- Wypisz na wyjście wartość z rejestru największej liczby.
- Zwolnij rejestr bieżącej wartości oraz największej liczby i zakończ pracę wypisując na wyjście wartość sukcesu.
Historia algorytmów
Początki
Słowo
algorytm pochodzi od nazwiska
arabskiego matematyka z
IX wieku
Muhammeda ibn Musa Alchwarizmiego. Początkowo słowem
algorism nazywano czynności konieczne do wykonywania obliczeń z użyciem
dziesiętnego systemu liczbowego. Obecne znaczenie słowa
algorytm jako zestawu ścisłych reguł powstało wraz z rozwojem matematyki i techniki. Wynalezienie zbiorów zasad pozwalających na obliczanie parametrów konstruowanych maszyn, stało się podstawą
rewolucji przemysłowej zapoczątkowanej w końcu
XVIII stulecia. Jednak dopiero zbudowanie maszyn, które same mogły realizować pewne proste algorytmy, stało się przełomem. Początkowo miały one postać układów mechanicznych mogących dokonywać prostych obliczeń.
Ogromnego postępu dokonał w tej dziedzinie w 1842 roku Charles Babbage, który na podstawie swoich doświadczeń sformułował ideę maszyny analitycznej zdolnej do realizacji złożonych algorytmów matematycznych. W pracy Babbage wspierała Ada Lovelace, która przetłumaczyła dla niego prace włoskiego matematyka dotyczące algorytmu obliczania liczb bernoulliego. Prace Lovelace dotyczące implementacji na maszynę różnicową tego algorytmu zawierały opis swoistego języka programowania. Niestety Babbage nigdy nie zbudował swojego mechanicznego komputera. Programy napisane przez Lovelace zostały przetestowane na modelu maszyny różnicowej wykonanym w XX wiekuu i okazały się poprawne.
Rozwój maszyn liczących
Wraz z wynalezieniem pod koniec
XIX wieku
kart perforowanych elektro-mechaniczne maszyny osiągnęły zdolność realizacji algorytmów przetwarzających ogromne zbiory danych. Karty perforowane stały się wejściem, z którego dane przetwarzały proste algorytmy sumujące. Jako wyjście służyły odpowiednie zegary. Ogromny postęp w tej dziedzinie zawdzięczamy firmie
IBM, która zbudowała tego typu urządzenia, aby policzyć wszystkich mieszkańców
USA.
W XX wieku postęp elektroniki pozwolił na budowę maszyn analogowych potrafiących w swoim wnętrzu odtwarzać pewne algorytmy matematyczne. Mogły one dokonywać operacji arytmetycznych oraz różniczkować i całkować.
Komputery
Kluczowym stał się moment, w którym badacze zdali sobie sprawę, że maszyny najlepiej radzą sobie z szybkim powtarzaniem bardzo prostych operacji. Algorytm wyrażony w najprostszym z możliwych języków okazał się dla urządzeń najlepszy. Prowadzone podczas
II wojny światowej prace
kryptologów doprowadziły do zbudowania maszyn łamiących szyfry. Największe zasługi miał tutaj
Alan Turing. Badacz ten podczas prac nad algorytmami szyfrującymi, zdał sobie sprawę, że każdy z nich da się sprowadzić do zestawu instrukcji realizowanych przez pewną teoretyczną maszynę. Miała ona zdolność do czytania i pisania poleceń z nieskończonej taśmy. Jej rozkazy mogły zawierać polecenia przesunięcia się o ileś kroków głowicy, zapisu/odczytu w jakimś miejscu taśmy nowej instrukcji.
Podług tej idei zbudowano pierwsze komputery. Posługiwały się algebrą Boole'a oraz binarnym systemem liczbowym. Kolejne rozkazy były odczytywane z kart perforowanych, a wyniki pojawiały się na świetlnych ekranach bądź w wydrukach. Okazało się, że tak proste maszyny były w stanie realizować bardzo złożone algorytmy matematyczne, jak np. obliczanie trajektorii pocisków czy rakiet.
Dzisiaj komputery są powszechne oraz tanie i przez to implementacja w nich właściwych algorytmów stała się bardzo ważną gałęzią gospodarki. Na całym świecie pracują miliony programistów zajmujących się doskonaleniem oprogramowania. Odpowiednie algorytmy noszące nazwę protokołów komunikacyjnych sterują ruchem informacji w globalnej sieci Internetowej. Wyszukiwanie w implementacjach błędów jest zajęciem nie dającym się łatwo zautomatyzować i żmudnej pracy całych zespołów hackerów i programistów.
Linki zewnętrzne
Wikipedia
Bibliografia
- Neil Gershenfeld i Isaac L. Chuang, "Molekularne komputery kwantowe"; Świat Nauki, sierpień 1998
- Nadrian C. Seeman, "Na granicy życia i nanotechnologii"; Świat Nauki, lipiec 2004 Dymek
- Thomas H. Cormen, Charles E. Leiserson, Ronald L. Rivest, Clifford Stein "Wprowadzenie do algorytmów (nowe wydanie)";WNT, wyd. VI 2004
Polskie
- artykuł o komputerach DNA - http://serwisy.gazeta.pl/nauka/1,34141,559703.html
- algorytmy i struktury danych - http://www.algorytm.org/
Angielskie
- darmowe kody źródłowe podstawowych algorytmów w Javie i C - http://www.algana.co.uk/
- inna strona z kodami źródłowymi - http://www.dcc.uchile.cl/~rbaeza/handbook/
- słownik algorytmów i struktur danych - http://www.nist.gov/dads/
- algorytmy numeryczne - http://www.nr.com
Algorytmy
Algoritme | Algoritmo | Algoritmu | Algoritam | Алгоритъм | Algorisme | Algoritmus | Algoritme | Algorithmus | Algoritm | Αλγόριθμος | Algorithm | Algoritmo | Algoritmo | Algorithmique | Algoritmo | 알고리즘 | Algoritam | Algoritma | Reiknirit | Algoritmo | אלגוריתם | ალგორითმი | Algoritms | Algorithmus | Algoritmas | Algoritmus | Algoritme | アルゴリズム | Algoritme | Algoritmo | Algoritm | Алгоритм | Algorithm | Algoritmus | Algoritem | Алгоритам | Algoritam | Algoritma | Algoritmi | Algoritm | Algoritmo | อัลกอริทึม | Thuật toán | Algoritma | Алгоритм | 算法