Zasady analizy algorytmów A więc dziś w programie: - Kilka ważnych definicji i opisów formalnych - Złożoność: czasowa i pamięciowa - Kategorie problemów - Jakieś przykłady
Problem: Zadanie możliwe do rozwiązania na maszynie liczącej (w szczególności na komputerze) z opisem zbioru danych wejściowych i charakterystyce oczekiwanej odpowiedzi. Formalnie to funkcja ze zbioru danych wejściowych w dane wyjściowe. Problem Nie mylić z instancją problemu! Przykładem problemu może być problem mnożenia liczb: Mając dwie liczby x i y znajdź ich iloczyn Instancją problemu mnożenia liczb mogą być dane 6 4, oczekiwaną odpowiedzą jest 24
Zadanie algorytmiki Przykłady algorytmów rozwiązujących problem mnożenia a x b Algorytm 1: a razy dodać do siebie liczbę b Algorytm 2: pomnożyć pisemnie (wymaga zdanego AK!) Algorytm 3: Mnożenie,,po rosyjsku : 1. Oblicz ciąg a 1, a 2 a k, taki, że a 1 = a, a 2 = a/2, a k = 1 (dzielimy całkowitoliczbowo) 2. Oblicz ciąg b 1, b 2 b k, taki, że b 1 = b, b 2 = 2b, b 3 = 4b 3 k 3. Oblicz σ i=1 b i dla a i nieparzyste
Złożoność obliczeniowa algorytmu Złożoność czasowa liczba jednostek czasu potrzebna na wykonanie algorytmu Jednostką czasu jest czas potrzebny na wykonanie elementarnej operacji (np. na maszynie RAM) Zakładamy kryterium jednorodne koszt każdej operacji na maszynie RAM jest jednostkowy 4 Złożoność pamięciowa liczba jednostek pamięci (np. komórek, bitów) potrzebnych na wykonanie algorytmu.
Złożoność algorytmów Jakie sytuacje należy rozpatrzeć? Złożoność najgorszego przypadku (pesymistyczna) Maksimum kosztu obliczeń dla danych rozmiaru N Złożoność średniego przypadku (oczekiwana) Średni koszt obliczeń dla danych rozmiaru N Złożoność najlepszego przypadku (optymistyczna) Minimum kosztu obliczeń dla danych rozmiaru N 5
Złożoność obliczeniowa Asymptotyczne tempo wzrostu Często interesuje nas ogólny przebieg funkcji kosztu, a nie jej dokładny wykres Do takiego ogólnego opisu używa się notacji Wykorzystywane notacje: Duże O ogranicza funkcję z góry Duże Ω ogranicza funkcję z dołu Duże ϴ - ogranicza funkcję z góry i z dołu 6
Notacja duże O Definicja formalna Mówimy, że f(n) = O( g(n) ), gdy dla każdego n większego od n 0 istnieje takie c, że f n c g(n) Zaraz narysuje o co chodzi Definicja intuicyjna Jesteśmy w stanie dobrać taką stałą dla funkcji ograniczającej, że wartości funkcji ograniczonej są mniejsze od wartości funkcji ograniczającej Jeśli rozumiesz liczenie granic to to bardzo podobne 7
Praktyka czyni mistrza Kilka przykładów Zapisz za pomocą dużego O: 8 1 3 n2 + 10n + 1 100 n4 + 10000n 3 + 125 nlog n + 10n + log n 2 n + 100n 5 + 1000000000 n n log n + n 1.00001 + 2 log n! + n 2 2 n + 3 n + 5 n
Elementarny słowniczek Nazewnictwo O(1) stała liczba operacji, koszt stały, złożoność stała O(n) liniowa liczba operacji, koszt liniowy O(nlogn) złożoność quasi-liniowa (pseudoliniowa) O(n 2 ) złożoność kwadratowa O(n c ) złożoność wielomianowa O(2 no(1) ) złożoność wykładnicza Jeśli mówimy o złożoności pamięciowej, to algorytmy wykorzystujące nie więcej niż logarytmicznie wiele pamięci dodatkowej, to są to algorytmy działające w miejscu (in situ). 9
Klasy złożoności problemów Przez klasę problemów rozumiemy takie zbiory problemów, że do ich rozwiązania potrzebna jest podobna ilość zasobów (czasu lub pamięci). Pokazanie do jakiej klasy należy algorytm jest ważne przy konstrukcji rozwiązania. Nie ma bowiem sensu próbować wymyślać szybkiego algorytmu dla problemu, dla którego pokazano, że nie należy do klasy P (czym jest klasa P zaraz). 10
Zaraz zrobię wykres i to omówię, dajcie mi chwilę! Najważniejsze klasy problemów Klasa R Klasa P Klasa EXP Klasa NP Klasa PSPACE 11
To teraz praktyka Analiza złożoności - sortowanie Rozpatrzmy sortowanie przez wybór (select sort) Polega ono na wybieraniu kolejnych najmniejszych elementów spośród przedstawionych danych Pseudokod zaraz na tablicy 12
Kontynujemy Sortowanie przez wybór 13 Widać zatem, że w pierwszej iteracji zewnętrznej pętli for wykonamy jedno przypisanie do zmiennej min, pętlę wewnętrzną for i jedną zamianę elementów Każde kolejne odpalenie pętli for kosztuje odpowiednio n, n-1, n-2,, 2, 1 operacji Jeśli zatem pętla zewnętrzna kręci się n-razy, to otrzymamy złożoność programu n + n 1 + n 2 + + 2 + 1 = (n 2 + n)/2 plus liniowa liczba operacji wynikająca z przypisania i zamiany elementów Zatem złożoność sortowania przez wybór to..
Czemu tak słabo? Co tutaj decyduje o złożoności? Widać, że złożoność jest uzależniona od dwóch pętli for, które powodują kwadratową liczbę operacji względem wielkości danych Konieczność zastosowania pętli wewnętrznej wynika z naiwnego wyszukiwania minimum w zbiorze Gdyby jakoś usprawnić to wyszukiwanie, to można usprawnić całą złożoność 14
Ulepszenie Sortowanie przez kopcowanie Zauważmy, że jeśli elementy u z uniwersum U mają porządek liniowy, to możemy te elementy kopcować Wytwarzanie kopca kosztuje O(n) operacji Otrzymanie elementu minimalnego i jego usunięcie z kopca kosztuje O(log n ) operacji Zatem sumaryczny koszt sortowania przez kopcowanie to O(n log n ) (dowód zaraz na tablicy) 15
Pytania na koniec