Algorytmy o tej właściwości nazywa się algorytmami z nawrotami (backtracking). Charakteryzują się tym, że kolejny krok, który może prowadzić do rozwiązania, jest zapamiętywany; gdy później okaże się, że nie prowadzi do rozwiązania, następuje usunięcie jego zapisu i wycofanie się do stanu poprzedzającego błędną decyzję. Najbardziej naturalnym opisem algorytmów z nawrotami jest rekurencja.

Dyskretny problem plecakowy

Poszukiwanie optymalnego rozwiązania metodą prób i błędów polega na systematycznym podejmowaniu kolejnych prób doboru przedmiotów — aż zostaną wyczerpane wszystkie dopuszczalne kombinacje. Dla każdego przedmiotu istnieją dwie możliwości: pozostawić go lub wziąć, co daje łącznie wszystkie kombinacje podzbiorów zbioru przedmiotów.

Złożoność obliczeniowa oraz notacja asymptotyczna

Złożoność obliczeniową algorytmu definiuje się jako ilość zasobów komputerowych potrzebnych do jego wykonania. Podstawowymi zasobami rozważanymi podczas analizy algorytmu są czas wykonania oraz ilość zajmowanej pamięci. Nie zawsze możliwe jest wyznaczenie złożoności jako funkcji konkretnych danych wejściowych (np. drzewa, grafy, tablice, ciągi).

Zwykle z zestawem danych wejściowych wiąże się jego rozmiar, rozumiany jako liczba elementów składowych.

Przykład

  • Sortowanie (rozmiar liczba elementów w ciągu wejściowym)
  • Problem przejścia drzewa binarnego (rozmiar liczba węzłów w drzewie)
  • Problem wyznaczania wartości wielomianu (rozmiar stopień wielomianu)

Na złożoność obliczeniową składa się:

  • złożoność pamięciowa
  • złożoność czasowa

W przypadku złożoności pamięciowej za jednostkę przyjmuje się zwykle słowo pamięci maszyny. Złożoność czasowa powinna być własnością samego algorytmu jako metody rozwiązania problemu, niezależnie od komputera, języka programowania czy sposobu kodowania. W tym celu wyróżnia się w algorytmie operacje dominujące, takie że łączna ich liczba jest proporcjonalna do liczby wykonania wszystkich operacji jednostkowych w dowolnej implementacji.

Przykłady

  • Algorytmy sortowania (operacja dominująca: porównanie dwóch elementów)
  • Algorytmy wyznaczania wartości wielomianu (operacja dominująca: operacje arytmetyczne)

Za jednostkę złożoności czasowej przyjmuje się wykonanie jednej operacji dominującej.

Złożoność obliczeniową algorytmu traktuje się jako funkcję rozmiaru danych . Wyróżnia się złożoność pesymistyczną (worst-case) — zasoby potrzebne dla najgorszych danych wejściowych rozmiaru — oraz złożoność oczekiwaną (average-case) — zasoby potrzebne dla typowych danych wejściowych rozmiaru .

Rozkład prawdopodobieństwa zmiennej losowej wyznacza się na podstawie informacji o zastosowaniach rozważanego algorytmu, gdy zbiór danych jest opisywalny przez pewien rozkład.

Pesymistyczna złożoność algorytmu

Oczekiwana złożoność algorytmu

Aby ocenić, w jakim stopniu funkcje i reprezentują zachowanie algorytmu dla danych wejściowych rozmiaru , rozważa się miary wrażliwości algorytmu:

  • miara wrażliwości pesymistycznej — jak bardzo najgorsze przypadki wpływają na zachowanie algorytmu
  • miara wrażliwości oczekiwanej — jak rozkład danych wpływa na średni czas działania

Miary wrażliwości algorytmu

Miara wrażliwości pesymistycznej:

Wariancja (miara wrażliwości oczekiwanej):

Wartość oczekiwana:

Im większe są wartości liczbowe i , tym bardziej algorytm jest wrażliwy na dane wejściowe i tym bardziej może odbiegać od zachowania opisanego funkcjami i .

Przykład: Wyszukiwanie liniowe

Załóżmy, że prawdopodobieństwo znalezienia elementu a na każdym z możliwych miejsc jest takie samo, to znaczy dla .

Pesymistyczna złożoność czasowa:

Oczekiwana złożoność czasowa:

Miara wrażliwości:

Wynika stąd duża wrażliwość liczby operacji dominujących na dane wejściowe.

Notacja asymptotyczna

Faktyczna złożoność algorytmu (czas działania) w chwili jego użycia jako programu różni się od wyliczonej teoretycznie współczynnikiem proporcjonalności, który zależy od konkretnej realizacji tego algorytmu. Istotną zatem częścią informacji, która jest zawarta w funkcjach złożoności i , jest rząd wielkości, czyli ich zachowanie asymptotyczne przy dążącym do nieskończoności. Zwykle staramy się podać jak najprostszą funkcję charakteryzującą rząd wielkości i .

Notacja O (duże O)

Niech . Mówimy, że jest rzędu , oznaczane jako , jeśli istnieją stała rzeczywista oraz takie, że:

Przykład:

ponieważ:

Notacja Ω (duże Omega)

wtedy i tylko wtedy, gdy .

Oznacza to, że rośnie co najmniej tak szybko jak .

Notacja Θ (duże Theta)

wtedy i tylko wtedy, gdy:

  • i

Oznacza to, że i rosną w tym samym tempie asymptotycznie.

Porównywanie rzędów wielkości

Rzędy wielkości dwóch funkcji i mogą być porównywane dzięki granicy:

gdzie:

  • Jeśli , to i rośnie wolniej niż
  • Jeśli , to i i rosną w tym samym tempie
  • Jeśli , to i rośnie szybciej niż

Typowe rzędy wielkości (od najwolniejszego wzrostu) EGZAMIN

  1. — stała
  2. — logarytmiczna - czas działania logarytmiczny występuje np. dla algorytmów typu zadanie rozmiaru n zostaje sprowadzone do zadania rozmiaru n na 2+pewna stała liczba działań, np. poszukiwanie binarne
  3. — liniowa - złożoność liniowa, czas działania liniowy występuje np. dla algorytmów, w których jest wykonywana pewna stała liczba działań dla każdego z n elementów danych wejściowych np. algorytm hornera
  4. — liniowo-logarytmiczna - czas dzialania wystepuje np. dla algorytmów typu: zadanie rozmiaru n zostaje sprowadzone do 2 podzadań n1/2 +pewna liczba dzialań liniowa względem rozmiaru n potrzebnych do wykonania najpierw rozbicia a nastepnie scalenia rozwiazania rozmiaru n1/2 w rozwiazanie rozmiaru n (merge-sort)
  5. — kwadratowa - czas działania kwadratowy występuje np. dla algorytmów, których jest wykonywana pewna stała liczba działań dla każdej pary elementów, podwójna instrukcja iteracyjna
  6. — sześcienna
  7. — wykładnicza - czas działania ma algorytm w którym jest wykonywana stała liczba działań dla każdego podzbioru danych wejsciowych
  8. — silnia - wykładnicza - czas działania n! ma np. algorytm w którym jest wykonywana stała liczba działań dla każdej permutacji danych wejściowych

Uwaga:

  1. Algorytm o złożoności wykładniczej może byc realizowany dla małych rozmiarów danych, istnieje próg dla którego funkcja zaczyna rosnąć tak szybko że realizacja algorytmu na komputerze staje się nie możliwa
  2. Dane wejściowe dla których czas działania jest wykładniczy mogą się nigdy nie pojawić w rzeczywistych okolicznościach np. metoda simplex programowania liniowego, choć ta metoda ma złożoność wykładniczą dla najgorszych danych dla pojawiających się w praktyce danych wejściowych działa w czasie wielomianowym, a nawet liniowym

Przy korzystaniu z wyników analizy złożoności algorytmu należy brać pod uwage następujące uwarunkowania:

  • algorytm i jego realizacja sa wyrażone w 2 różnych językach
  • wrażliwość algorytmu na dane wejściowe może spowodować że faktyczne zachowanie się algorytmu na używanych danych może odbiegać od zachowania opisanego przez i
  • może być trudno przewidzieć rozkład
  • dla niektórych algorytmów nie są znane matematyczne oszacowania i
  • czasami działanie 2 algorytmów jest trudno jednoznacznie porównać jeden działa dla pewnej klasy zestawu danych a drugi dla innych