Algorytmy – c.d. złożoność algorytmów struktury danych Przy opracowywaniu wykładu wykorzystano m.in.: http://www.algorytm.org/index.php?option=com_frontpage&Itemid=1 Wstęp do informatyki (materiały Wyższej Szkoły Informatyki) J. Sikorski
Przypomnienie Schematy blokowe Służą one do zapisu algorytmu w obrazowy sposób podając kierunek procesu obliczeń. Najważniejsze używane symbole: START, STOP PROCES (CZYNNOŚĆ) BLOK DECYZYJNY ODCZYT LUB ZAPIS DANYCH
Pojęcie zmiennej Przypomnienie Zmienne to informacje, której nadano strukturę. Związane są z obszarem pamięci przechowującym tę zmienną w postaci ciągu bitów. O sposobie prezentacji tych danych decyduje typ zmiennej. Najbardziej oczywistym typem są zmienne liczbowe (przechowujące liczby). - zmienne całkowite; - zmienne zmiennoprzecinkowe; Typy zmiennych charakteryzują się: - zakresem (np. od -128 do + 127) - dokładnością (np. maksymalnie do 10 liczb po przecinku) - zbiorem operacji, które można na zmiennych wykonywać (np. dzielenie zmiennoprzecinkowe jest niedozwolone (problematyczne) dla zmiennych całkowitych).
Pojęcie zmiennej Przypomnienie Zmienne w informatyce symbolizowane są przez ciąg znaków i cyfr (ciąg alfanumeryczny), bez odstępów (spacji), bez polskich znaków, z możliwym znakiem podkreślenia, nie zaczynający się od cyfry. Dokładne zasady związane są z przyjęciem konkretnego systemu (np. danego języka programowania). Poprawne ciągi, które mogą symbolizować zmienne to np.: ala, nazwa_zmiennej, zmienna3, malyKotek, pi
Pojęcie zmiennej Przypomnienie Najważniejszą cechą zmiennych jest to, że mogą one przechowywać DANE, które musimy przypisać. Bardzo ważne jest określenie tzw. instrukcji przypisania, symbolizowana najczęściej przez symbol := (dwukropek i równa się). Kompletne instrukcje na ogół kończy się znakiem ; (średnik). Na przykład: Liczba := 5; // przypisaliśmy zmiennej o nazwie Liczba wartość 5 Liczba := 10; // zmieniliśmy zdanie i teraz ma wartość 10 Liczba := Liczba + 2; // Teraz do poprzedniej wartości dodaliśmy 2, więc Razem 12
Struktury danych Algorytmy wymagają danych początkowych i tworzą nowe dane.
Co to są dane? Znamy już wstępnie pojęcie tzw. zmiennej… Ogólnie dane są zdefiniowane jako to wszystko co może być przetwarzane umysłowo lub komputerowo. Są to więc informacje, które posiadają określoną strukturę.
Struktury danych Jedna z gałęzi informatyki zajmuje się strukturami danych, czyli organizacją danych różnych typów w logicznie powiązane ze sobą struktury.
Sposoby reprezentacji danych Przykład drzewa Przykład kolejki Dane numeryczne: całkowite, „rzeczywiste” posiadają określony zakres i dokładność Tablice Listy Stosy Kolejki Drzewa Grafy Przykłady list Przykład grafu Przykłady tablic Przykład stosu
Tablice Tablicą nazywamy złożoną strukturę danych, która zawiera zbiór elementów tego samego typu. Wyróżniamy: tablice jednowymiarowe tablice wielowymiarowe
Tablice jednowymiarowe Elementy tego samego typu znajdują się pod wspólną nazwą. Konkretny element wskazujemy za pomocą tzw. indeksu. Tablica o nazwie TAB, 8 elementów (liczby całkowite, ze znakiem), numerowane od 1 15 [0] 5 [1] -1 [2] 20 [3] 55 [4] 51 [5] 8 [6] 12 [7] 15 [0] 5 [1] -1 [2] 12 [3] 55 [4] 51 [5] 8 [6] [7] Jeśli chcemy w polu o indeksie [3] wpisać inną wartość (np. 20), to piszemy: TAB[3] := 20;
Tablice jednowymiarowe – wyszukiwanie minimum 15 [0] 5 [1] -1 [2] 12 [3] 55 [4] 51 [5] 8 [6] [7] min:=tablica[0]; i:=1; START Do zastanowienia: Jak wyglądałoby wyszukiwanie maksymalnego (minimalnego) elementu w tablicy uporządkowanej rosnąco? i >= N TAK NIE WYPISZ min min>tablica[i] TAK min:=tablica[i]; NIE STOP i:=i+1;
Tablice wielowymiarowe Np. jeśli chcemy zapisać tzw. „tabliczkę mnożenia” możemy utworzyć tablicę dwuwymiarową (macierz) 10 na 10 1 2 3 4 5 6 7 8 9 10 20 56 Do poszczególnych elementów odwołujemy się poprzez podanie indeksu kolumny i wiersza. Np.: TAB_2D[4][5] := 20; TAB_2D[7][8] := 56;
Tablice wielowymiarowe Tablice wielowymiarowe nie muszą ograniczać się do dwuwymiarowych. Mogą posiadać także nieregularne kształty. Przykłady tablic wielowymiarowych
Drzewa Struktury drzewiaste są stosowane, gdy chcemy uporządkować dane zgodnie z ich hierarchiczną strukturą. Przykłady drzew: Drzewo genealogiczne Układ plików na dysku
Drzewa Dla każdego drzewa wyróżniony jest jeden, charakterystyczny element- korzeń. Korzeń nie posiada elementów poprzednich. Dla każdego innego elementu określony jest dokładnie jeden element poprzedni. Dla każdego elementu oprócz ostatnich, tzw. liści istnieje co najmniej jeden element następny (jest to węzeł). Jeżeli liczba następnych elementów wynosi dokładnie 2 to drzewo nazywamy binarnym. Znaczenie drzew jest bardzo duże i ze względu na swoje własności drzewa są stosowane praktycznie w każdej dziedzinie informatyki. Dla każdego drzewa można określić: długość drogi u (głębokość) - liczba wierzchołków, przez które należy przejść od korzenia do wierzchołka u wysokość u - maksymalna liczba wierzchołków na drodze od u do pewnego liścia wysokość drzewa = głębokość = wysokość korzenia +1 ścieżka z u do v - zbiór wierzchołków, przez które należy przejść z wierzchołka u do v droga - ścieżka skierowana stopień wierzchołka - liczba jego bezpośrednich następników stopień drzewa - maksymalny stopień wierzchołka
Grafy W informatyce grafem nazywamy strukturę składającą się z węzłów (wierzchołków, oznaczanych przez V) wzajemnie połączonych za pomocą krawędzi (oznaczonych przez E). Grafy dzielimy na grafy skierowane i nieskierowane: Jak można się domyślić, drzewa są szczególnym przypadkiem grafów. Grafy są bardzo popularne w nowoczesnej algorytmice. Graf nieskierowany Graf skierowany
Przykłady grafów Sieć komputerowa
Schemat metra w Moskwie Przykłady grafów Schemat metra w Moskwie
Przykłady grafów Drzewo genealogiczne
Przykłady grafów Pajęczyna
Historia systemu LINUX Przykłady grafów Historia systemu LINUX
STOS Struktury takie jak stosy, listy i kolejki Stos to struktura umożliwiająca wstawianie i usuwanie danych dostępnych jedynie w tzw. wierzchołku stosu. Czyli w wierzchołku stosu znajdują się zawsze dane, które zostały wstawione do stosu w trakcie ostatnio wykonanej operacji wstawiania. Struktury takie jak stosy, listy i kolejki mogą być różnie realizowane. Jedną z możliwości jest wykorzystanie tablic, inną struktur dynamicznych. Operacje to: POP (pobierz ze stosu) PUSH (połóż na stosie)
KOLEJKA Kolejka, to struktura w której można wstawić element za tym, który trafił do struktury jako ostatni, a usuwać ten, który został wstawiony jako pierwszy. POBIERZ WSTAW Operacje to: WSTAW(na koniec kolejki) POBIERZ(z początku kolejki)
LISTY LISTY to uogólniony przypadek kolejek, stosów i podobnych struktur. Opisuje ona liniową strukturę elementów, powiązanych ze sobą. Przykłady list
Złożoność algorytmów
Który algorytm jest „lepszy”? Do danego rozwiązania prowadzi zwykle więcej niż jedna droga. Jak więc oceniać alternatywne sposoby rozwiązania problemu? Podstawowym parametrem algorytmu jest jego złożoność.
Złożoność Algorytmy efektywne dają rozwiązania w „rozsądnym” czasie oraz zużywają „rozsądną ilość zasobów”. Co to jest rozsądny czas? Milisekunda, godzina, rok…?
Złożoność Złożoność czasowa mówi, ile kroków obliczeniowych trzeba wykonać dla zakończenia algorytmu. Za podstawę określania złożoności przyjmuje się najbardziej operację, której trzeba wykonać najwięcej. Np. mnożenie, dzielenie, pierwiastek… Jest to OPERACJA PODSTAWOWA Złożoność jest to ilość zasobów potrzebnych do działania algorytmu. W zależności od rozważanego zasobu mówimy o złożoności czasowej lub pamięciowej. Ilość potrzebnych zasobów będzie się różnić w zależności od konkretnego przypadku. Złożoność pamięciowa mówi, jaką maksymalnie część danych i wyników pośrednich trzeba w ramach danego algorytmu przechowywać w pamięci operacyjnej.
czyli uporządkować rosnąco. Przykład 3 liczby – a, b, c zapisane w trzech komórkach pamięci (zmiennych) x, y, z Zadanie: Przemieścić liczby tak, aby spełnione było (x) <= (y) <= (z) czyli uporządkować rosnąco. Np. (1, 5, 2); (2, 6, 1) itp.
Przykład Jakie są więc wszystkie możliwości uporządkowania? Aby rozwiązać zadanie będą nam potrzebne operacje testu oraz zamiany
Przykład Przedstawmy sekwencje testów, które pozwolą stwierdzić, z jakim przypadkiem mamy do czynienia?
Przykład Teraz, w zależności od konkretnego przypadku, wybieramy odpowiednią sekwencję zamian.
Przykład Ile wykonamy poszczególnych operacji? Najlepiej Najgorzej Testy Zamiany Najlepiej Najgorzej
Dla większości algorytmów rozmiar danych też może się zmieniać. Przykład Czas wykonania tego zadania zależy więc od ułożenia danych wejściowych. Możemy określić przypadki najgorszego ułożenia i najlepszego ułożenia. Mówi się o pesymistycznej i optymistycznej złożoności. Dla algorytmów najczęściej przyjmuje się tzw. złożoność średnią (2,7 testów, 1,2 permutacji) W przykładzie rozmiar danych zawsze był taki sam (3 liczby). Zmieniła się konfiguracja danych. Dla większości algorytmów rozmiar danych też może się zmieniać. Problemem jest wówczas określenia złożoności w zależności od rozmiaru danych.
Przykład Na przyjęciu dyplomatycznym bawi się N ambasadorów. Ich uściski rąk są rejestro-wane przez fotografa po kolei. Ile czasu zajmie taka sesja zdjęciowa? Algorytm: Ambasador 1 podaje rękę amba-sadorom 2, 3, 4... aż do N. Ambasador 2 po-daje rękę ambasadorom 3,4,...,N. W ten spo-sób dochodzimy do ambasadorów N-1 i N, którzy jako ostatni wymieniają uścisk. Złożoność czasowa: N(N-1)/2 jednostek (suma ciągu arytmetycznego)
Złożoność Problemy do których rozwiązania potrzebna jest podobna ilość zasobów łączymy w klasy złożoności.
Złożoność Bierzemy pod uwagę asymptotyczne tempo wzrostu, czyli to jak zachowuje się funkcja określająca złożoność dla odpowiednio dużych, granicznych rozmiarów danych wejściowych, ignorując zachowanie dla małych danych.
Złożoność W algorytmice najczęściej pojawia się tzw. O-notacja. Jeśli F(N) jest funkcją złożoności algorytmu to spełnienie zależności oznacza, że algorytm ma złożoność rzędu f(N) (O (f(N) )
Złożoność IDEAŁ TO ZŁOŻONOŚĆ LINIOWA – funkcja f(x) jest ograniczona – funkcja f(x) jest ograniczona przez funkcję logarytmiczną – funkcja f(x) jest ograniczona przez funkcję liniową – funkcja f(x) jest ograniczona przez funkcję potęgową lub wielomian – funkcja f(x) jest ograniczona przez funkcję wykładniczą – funkcja f(x) jest ograniczona przez silnię
Porównanie niektórych złożoności:
Zapotrzebowanie na czas
Trudne zadania Dla pierwszoklasisty: 7 * 8 = ??? Dla faceta: Jak umówić się z Dodą? Dla studenta: wszystko jest łatwe…
Trudne zadania Czy istnieją zadania trudne dla komputerów? Wiele prostych w sformułowaniu zagadnień należy do zagadnień trudnych, np. „problem wędrującego komiwojażera”: jak znaleźć najkrótszą drogę, łączącą N miast odwiedzając każde tylko jeden raz.
Baaardzo trudne zadania - NP Problem P to problem decyzyjny, dla którego rozwiązanie można znaleźć w czasie wielomianowym. Problem NP to problem decyzyjny, dla którego rozwiązanie można zweryfikować w czasie wielomianowym. (ang. deterministic polynomial - deterministycznie wielomianowy) NP. (niedeterministycznie wielomianowy, ang. nondeterministic polynomial)
Baaardzo trudne zadania - NP Przykłady problemów NP. – układanki 2D (ang. deterministic polynomial - deterministycznie wielomianowy) NP. (niedeterministycznie wielomianowy, ang. nondeterministic polynomial)
Baaardzo trudne zadania - NP Przykłady problemów NP. – problem komiwojażera (ang. deterministic polynomial - deterministycznie wielomianowy) NP. (niedeterministycznie wielomianowy, ang. nondeterministic polynomial)
Baaardzo trudne zadania - NP Przykłady problemów NP. – droga Hamiltona (ang. deterministic polynomial - deterministycznie wielomianowy) NP. (niedeterministycznie wielomianowy, ang. nondeterministic polynomial)
Baaardzo trudne zadania - NP Przykłady problemów NP. – przydział ograniczonego miejsca (ang. deterministic polynomial - deterministycznie wielomianowy) NP. (niedeterministycznie wielomianowy, ang. nondeterministic polynomial)
Baaardzo trudne zadania - NP Pytanie, czy klasa P jest tym samym, co NP jest prawdopodobnie najważniejszym otwartym problemem w całej teorii informatyki. Dla pierwszej osoby, która rozwiąże ten problem przewidziano nagrodę w wysokości miliona dolarów (ang. deterministic polynomial - deterministycznie wielomianowy) NP. (niedeterministycznie wielomianowy, ang. nondeterministic polynomial)
Rekurencja
Funkcję rekurencyjną nazywamy taką funkcję która wywołuje samą siebie. Rekurencja Funkcję rekurencyjną nazywamy taką funkcję która wywołuje samą siebie. Funkcja taka musi posiadać warunek zakończenia rekurencji. Jeżeli takiego warunku by nie posiadała funkcja wywoływała by siebie bez końca. Funkcja taka jest wykonywana trochę wolniej niż funkcja nierekurencyjna, ale kod jest zdecydowanie krótszy i prostszy w niektórych wypadkach.
Silnia START wczytaj n; NIE TAK n = 0 zwróć n*(n-1)! zwróć 1 POWRÓT
Wieże Hanoi Problem: Przełożyć krążki, przenosząc po jednym, z jednego „patyka” na drugi z zachowaniem docelowej kolejności (mniejsze na większych). Dla 3:
Wieże Hanoi Rozwiązanie sprowadza się do odpowiedniego podziału problemu w sposób rekurencyjny.
Ciąg Fibonacciego F = 1 + 1 + 2 + 3 + 5 + 8 + 13… Ciąg Fibonacciego używany jest do określanie idealnej populacji zwierząt (pszczoły,króliki), jest również używany w pseudogeneratorach liczb losowych oraz w zaawansowanych obliczeniach matematycznych. F = 1 + 1 + 2 + 3 + 5 + 8 + 13… F(5)= F(4) + F(3) = F(3) + F(2) + F(2) + F(1) = F(2) + F(1) + F(1) + F(0) + F(1) + F(0) + F(1)= F(1) + F(0) + F(1) + F(1) + F(0) + F(1) + F(0) + F(1) = 1 + 0 + 1 + 1 + 0 + 1 + 0 + 1 = 5 - pułapka rekurencji!
Stabilność numeryczna Określa ona wrażliwość wyniku końcowego na błędy zaokrągleń w trakcie obliczeń oraz na dokładność danych początkowych. Przykłady: Komputer wykonuje operacje liczbowe ze skończoną precyzją. Może się okazać, że wynik działania 10 000 000 000 + 1 to dalej 10 000 000 000. Podobnie, realizacja dzielenia jako mnożenie przez odwrotność jest mało stabilna numerycznie dla argumentów bliskich zeru.
Problem STOPU Problemem stopu nazywamy sytuację, gdy dla danego algorytmu należy stwierdzić, czy program realizujący dany algorytm zatrzyma się. Pytanie może odnosić się albo do konkretnych danych wejściowych, albo do wszystkich możliwych danych. Jeśli program zatrzymuje się dla wszystkich danych, to mówimy, że ma własność stopu. Problem stopu jest często bardzo trudny do rozstrzygnięcia dla niektórych algorytmów.
Świat nie jest czarno-biały… W latach 60-tych naszego stulecia logikę rozszerzono na pojęcia logiki rozmytej (fuzzy logic) oraz zbiorów przybliżonych. W obu przypadkach chodzi o opis wiedzy niepewnej, nieprecyzyjnej. W klasycznej teorii zbiorów obiekty należą do zbioru lub nie. W teorii zbiorów rozmytych możliwa jest częściowa przynależność do zbioru, np. zbiór osób określanych jako „wysokie” nie jest precyzyjnie określony i można o kimś powiedzieć, że jest „w pewnym stopniu wysoki”. Wnioski wyciągane w oparciu o logikę rozmytą nie mają takiego stopnia pewności jak wnioski oparte o logikę klasyczną, możliwe jest jednakże rozumowanie w warunkach niepewnej czy nieprecyzyjnie określonej informacji. W oparciu o logikę rozmytą działa coraz więcej urządzeń technicznych. Sposób „rozumowania” tych urządzeń i sposób komunikacji z nimi jest z punktu widzenia człowieka bardziej naturalny, gdyż logika rozmyta oprócz stwierdzeń „tak” i „nie” pozwala na używanie takich określeń, jak „być może”, „chyba tak”, „prawie na pewno”. Teoria zbiorów przybliżonych stworzona została przez profesora Zdzisława Pawlaka.
Podsumowanie, wnioski ?
Przykłady algorytmów…