Algorytmy i złożoność obliczeniowa Wojciech Horzelski 1
Tematyka wykładu Ø Ø Ø Ø Ø Wprowadzenie Poprawność algorytmów (elementy analizy algorytmów) Wyszukiwanie Sortowanie Elementarne i abstrakcyjne struktury danych 2
Literatura T. Cormen, Ch. Lieserson, R. Rivest, Wprowadzenie do Algorytmów, WNT, 1997 R. Sedgewick, Algorytmy w C++, RM, 1999 N. Wirth, Algorytmy + struktury danych = programy, WNT, 2001 3
O co w tym wszystkim chodzi? Ø Rozwiązywanie problemów: Układanie planu zajęć Bilansowanie budżet Symulacja lotu samolotem Prognoza pogody Ø Dla rozwiązania problemów potrzebujemy procedur, recept, przepisów inaczej mówiąc algorytmów 4
Historia Ø Nazwa pochodzi od perskiego matematyka Muhammeda ibn Musa Alchwarizmiego (w łacińskiej wersji Algorismus) IX w n.e. Ø Pierwszy dobrze opisany algorytm algorytm Euklidesa znajdowania największego wspólnego podzielnika, 400-300 p.n.e. Ø XIX w. Charles Babbage, Ada Lovelace. Ø XX w. Alan Turing, Alonzo Church, John von Neumann 5
Struktury danych i algorytmy Ø Algorytm metoda, zestaw działań (instrukcji) potrzebnych do rozwiązania problemu Ø Program implementacja algorytmu w jakimś języku programowania Ø Struktura danych organizacja danych niezbędna dla rozwiązania problemu (metody dostępu etc.) 6
Ogólne spojrzenie Wykorzystanie komputera: Ø Projektowanie programów (algorytmy, struktury danych) Ø Pisanie programów (kodowanie) Ø Weryfikacja programów (testowanie) Cele algorytmiczne: - poprawność, - efektywność, Cele implementacji: - zwięzłość - możliwość powtórnego wykorzystania 7
Problemy algorytmiczne Specyfikacja wejścia? Specyfikacja wyjścia, jako funkcji wejścia Ilość instancji danych spełniających specyfikację wejścia może być nieskończona, np.: posortowana niemalejąco sekwencja liczb naturalnych, o skończonej długości: 1, 20, 908, 909, 100000, 1000000000. 3, 44, 211, 222, 433. 3. 8
Rozwiązanie problemu Instancja wejściowa (dane), odpowiadająca specyfikacji algorytm Wyniki odpowiadające danym wejściowym Algorytm opisuje działania, które mają zostać przeprowadzone na danych Może istnieć wiele algorytmów rozwiązujących ten sam problem 9
Definicja algorytmu Ø Algorytmem nazywamy skończoną sekwencję jednoznacznych instrukcji pozwalających na rozwiązanie problemu, tj. na uzyskanie pożądanego wyjścia dla każdego legalnego wejścia. Ø Własności algorytmów: określoność skończoność poprawność ogólność dokładność 10
Przykład 1: poszukiwanie Wejście: uporządkowany niemalejąco ciąg n (n >0) liczb liczba a 1, a 2, a 3,.,a n ; q Wyjście: indeks (pozycja) odnalezionej wartości lub NIL j 2 5 6 10 11; 5 2 2 5 6 10 11; 9 NIL 11
Przykład 1: poszukiwanie liniowe INPUT: A[1..n] tablica liczb, q liczba całkowita. OUTPUT: indeks j taki, że A[j] = q. NIL, jeśli j (1 j n): A[j] q j 1 while j n and A[j] q do j++ if j n then return j else return NIL Ø Ø Ø Algorytm wykorzystuje metodę siłową (brute-force) przegląda kolejno elementy tablicy. Kod napisany jest w jednoznacznym pseudojęzyku (pseudokodzie). Wejście (INPUT) i wyjście (OUTPUT) zostały jasno określone. 12
Pseudokod Ø Zbliżony do Ady, C, Javy czy innego języka programowania: struktury sterujące (if then else, pętle while i for) przypisanie ( ) dostęp do elementów tablicy: A[i] dla typów złożonych (record lub object) dostęp do pól: A.b zmienna reprezentująca tablicę czy obiekt jest traktowana jak wskaźnik do tej struktury (podobnie, jak w C). 13
Warunki początkowe i końcowe (precondition, postcondition) Ø Ważne jest sprecyzowanie warunków początkowego i końcowego dla algorytmu: INPUT: określenie jakie dane algorytm powinien dostać na wejściu OUTPUT: określenie co algorytm powinien wyprodukować. Powinna zostać przewidziana obsługa specjalnych przypadków danych wejściowych 14
Przykład 2: sortowanie Wejście ciąg n liczb Wyjście Permutacja wejściowego ciągu a 1, a 2, a 3,.,a n Sort b 1,b 2,b 3,.,b n 2 5 4 10 7 2 4 5 7 10 poprawność wyjścia: Dla każdego wejścia algorytm po zakończeniu działania powinien dać jako wynik b 1, b 2,, b n takie, że: b 1 < b 2 < b 3 <. < b n b 1, b 2, b 3,., b n jest permutacją a 1, a 2, a 3,.,a n 15
Sortowanie przez wstawianie (Insertion Sort) Strategia A zaczynamy od pustego ciągu ( pustej ręki ) wkładamy kartę we właściwe miejsce wśród kart poprzednio już posortowanych kontynuujemy takie postępowanie aż wszystkie karty zostaną wstawione 3 4 6 8 9 7 2 5 1 1 j n i INPUT: A[1..n] tablica liczb całkowitych OUTPUT: permutacja A taka, że A[1] A[2] A[n] for j 2 to n do key A[j] // wstaw A[j] do posortowanej // sekwencji A[1..j-1] i j-1 while i>0 and A[i]>key do A[i+1] A[i] i-- A[i+1] key 16
Analiza algorytmów Ø Efektywność: Czas działania Wykorzystanie pamięci Ø Efektywność jako funkcja rozmiaru wejścia: Ilość danych wejściowych (liczb, punktów, itp.) Ilość bitów w danych wejściowych 17
Analiza sortowania przez wstawianie Ø Określany czas wykonania jako funkcję rozmiaru wejścia for j 2 to n do key A[j] //wstaw A[j] do posortowanej sekwencji A[1..j-1] i j-1 while i>0 and A[i]>key do A[i+1] A[i] i-- A[i+1]:=key czas c 1 c 2 0 c 3 c 4 c 5 c 6 c 7 ile razy n n-1 n-1 n-1 n t j 2 j n ( t 1) j 2 j n= ( t 1) j 2 j = n-1 = 18
Przypadki: najlepszy/najgorszy/średni Ø Najlepszy przypadek: elementy już są posortowane t j =1, czas wykonania liniowy (Cn). Ø Najgorszy przypadek: elementy posortowane nierosnąco (odwrotnie posortowane) t j =j, czas wykonania kwadratowy (Cn 2 ) Ø Przypadek średni : t j =j/2, czas wykonania kwadratowy (Cn 2 ) 19
Przypadki: najlepszy/najgorszy/średni Dla ustalonego n czas wykonania dla poszczególnych instancji: 6n 5n 4n 3n 2n 1n 20
Przypadki: najlepszy/najgorszy/średni Dla różnych n: najgorszy przypadek Czas działania 6n 5n 4n 3n 2n 1n średni przypadek najlepszy przypadek 1 2 3 4 5 6 7 8 9 10 11 12.. Rozmiar wejścia 21
Przypadki: najlepszy/najgorszy/średni Ø Analizę najgorszego przypadku stosuje się zwykle wtedy, kiedy czas działania jest czynnikiem krytycznym (kontrola lotów, sterowanie podawaniem leków itp.) Ø Dla pewnych zadań najgorsze przypadki mogą występować dość często, jednak w praktyce zwykle zdarza się to rzadko lub wręcz jest to nierealne. Ø Określenie przypadku średniego (analiza probabilistyczna) jest często bardzo kłopotliwe 22
Różnice w podejściu? Ø Czy sortowanie przez wstawianie jest najlepszą strategią dla zadania sortowania? Ø Rozważmy alternatywną strategię opartą o zasadę dziel i zwyciężaj : Sortowanie przez łączenie (MergeSort): ciąg <4, 1, 3, 9> dzielimy na dwa podciągi Sortujemy te podciągi: <4, 1> i <3, 9> łączymy wyniki Czas wykonania rzędu n log n 23
Analiza wyszukiwania liniowego INPUT: A[1..n] tablica liczb całkowitych, q liczba całkowita OUTPUT: indeks j taki, że A[j] = q. NIL, jeśli j (1 j n): A[j] q j 1 while j n and A[j] q do j++ if j n then return j else return NIL Najgorszy przypadek: C n Średni przypadek: C n/2 24
Poszukiwanie binarne Pomysł: dziel i zwyciężaj INPUT: A[1..n] posortowana tablica liczb całkowitych, q liczba całkowita. OUTPUT: indeks j taki, że A[j] = q. NIL, jeśli j (1 j n): A[j] q left 1 right n do j (left+right)/2 if A[j]=q then return j else if A[j]>q then right j-1 else left=j+1 while left<=right return NIL 25
Poszukiwanie binarne - analiza Ø Ile razy wykonywana jest pętla: Po każdym przebiegu różnica między left a right zmniejsza się o połowę początkowo n pętla kończy się kiedy różnica wynosi 1 lub 0 Ile razy trzeba połowić n żeby dostać 1? lg n lepiej niż poprzedni algorytm (n) 26
Porównanie czasów wykonania Maksymalny rozmiar problemu (n) 1 sekunda 1 minuta 1 godzina 400n 2500 150000 9000000 20n log n 4096 166666 7826087 2n 2 707 5477 42426 n 4 31 88 244 2 n 19 25 31 27