Metoda bisekcji (inaczej połowienia przedziału lub równych podziałów)

Podobne dokumenty
Wyszukiwanie. Wyszukiwanie binarne

Rekurencje. Jeśli algorytm zawiera wywołanie samego siebie, jego czas działania moŝe być określony rekurencją. Przykład: sortowanie przez scalanie:

1 Metody rozwiązywania równań nieliniowych. Postawienie problemu

Poprawność semantyczna

Efektywna metoda sortowania sortowanie przez scalanie

Wstęp do programowania

METODY NUMERYCZNE. Wykład 4. Numeryczne rozwiązywanie równań nieliniowych z jedną niewiadomą. prof. dr hab.inż. Katarzyna Zakrzewska

Wstęp do programowania

Znaleźć wzór ogólny i zbadać istnienie granicy ciągu określonego rekurencyjnie:

Algorytmy sortujące i wyszukujące

Strategia "dziel i zwyciężaj"

I. Podstawy języka C powtórka

Algorytmy i struktury danych Matematyka III sem.

Złożoność obliczeniowa zadania, zestaw 2

Wykład 2. Poprawność algorytmów

Algorytmy zrandomizowane

Zadania do wykonania. Rozwiązując poniższe zadania użyj pętlę for.

Rekurencja. Dla rozwiązania danego problemu, algorytm wywołuje sam siebie przy rozwiązywaniu podobnych podproblemów. Przykład: silnia: n! = n(n-1)!

Analiza algorytmów zadania podstawowe

ALGORYTMY. 1. Podstawowe definicje Schemat blokowy

Programowanie dynamiczne

operacje porównania, a jeśli jest to konieczne ze względu na złe uporządkowanie porównywanych liczb zmieniamy ich kolejność, czyli przestawiamy je.

Poprawność algorytmów

Podstawy Informatyki. Sprawność algorytmów

METODY NUMERYCZNE. Wykład 4. Numeryczne rozwiązywanie równań nieliniowych z jedną niewiadomą. Rozwiązywanie równań nieliniowych z jedną niewiadomą

Optymalizacja ciągła

Zaawansowane algorytmy i struktury danych

Liczby całkowite i rzeczywiste

Podstawowe algorytmy i ich implementacje w C. Wykład 9

Indukcja. Materiały pomocnicze do wykładu. wykładowca: dr Magdalena Kacprzak

ALGORYTMY Algorytm poprawny jednoznaczny szczegółowy uniwersalny skończoność efektywność (sprawność) zmiennych liniowy warunkowy iteracyjny

ALGORYTMY. 1. Podstawowe definicje Schemat blokowy

1 Równania nieliniowe

Obliczenia iteracyjne

Konstrukcje warunkowe Pętle

Laboratorium nr 7 Sortowanie

Zadanie 1. Korale (8 pkt) Rozważamy następującą rekurencyjną procedurę Korale, której parametrem jest dodatnia liczba całkowita n.

Pochodna funkcji odwrotnej

Podyplomowe Studium Informatyki

Sortowanie przez scalanie

lekcja 8a Gry komputerowe MasterMind

Sortowanie Shella Shell Sort

Rekurencja. Przykład. Rozważmy ciąg

Zadanie 3 Oblicz jeżeli wiadomo, że liczby 8 2,, 1, , tworzą ciąg arytmetyczny. Wyznacz różnicę ciągu. Rozwiązanie:

Zajęcia: VBA TEMAT: VBA PROCEDURY NUMERYCZNE Metoda bisekcji i metoda trapezów

Programowanie w VB Proste algorytmy sortowania

Wybrane metody przybliżonego. wyznaczania rozwiązań (pierwiastków) równań nieliniowych

Możliwości i ograniczenia komputerów

Zadanie 1 Przygotuj algorytm programu - sortowanie przez wstawianie.

Iteracje. Algorytm z iteracją to taki, w którym trzeba wielokrotnie powtarzać instrukcję, aby warunek został spełniony.

Propozycje rozwiązań zadań otwartych z próbnej matury rozszerzonej przygotowanej przez OPERON.

Tablice mgr Tomasz Xięski, Instytut Informatyki, Uniwersytet Śląski Katowice, 2011

Metody numeryczne. dr Artur Woike. Ćwiczenia nr 2. Rozwiązywanie równań nieliniowych metody połowienia, regula falsi i siecznych.

Podstawy Programowania C++

Metody numeryczne. materiały do wykładu dla studentów

Podstawy Informatyki. Algorytmy i ich poprawność

Metody numeryczne w przykładach

Wprowadzenie Metoda bisekcji Metoda regula falsi Metoda siecznych Metoda stycznych RÓWNANIA NIELINIOWE

3. Podaj elementy składowe jakie powinna uwzględniać definicja informatyki.

Instrukcje pętli przykłady. Odgadywanie hasła. 1) Program pyta o hasło i podaje adres, gdy hasło poprawne lub komunikat o błędnym haśle.

METODY ROZWIĄZYWANIA RÓWNAŃ NIELINIOWYCH

Wykład z Technologii Informacyjnych. Piotr Mika

FUNKCJE I RÓWNANIA KWADRATOWE. Lekcja 78. Pojęcie i wykres funkcji kwadratowej str

Podstawy Informatyki. Metalurgia, I rok. Rekurencja. skomplikowane zadanie. Rekurencja

Podstawy Informatyki. Metalurgia, I rok. Wykład 5 Rekurencja

2 Arytmetyka. d r 2 r + d r 1 2 r 1...d d 0 2 0,

TEORETYCZNE PODSTAWY INFORMATYKI

Algorytmy sortujące. sortowanie kubełkowe, sortowanie grzebieniowe

Pętle instrukcje powtórzeo

Kubatury Gaussa (całka podwójna po trójkącie)

FUNKCJA LINIOWA - WYKRES

RÓWNANIA NIELINIOWE Maciej Patan

ROZWIĄZYWANIE RÓWNAŃ NIELINIOWYCH

Rekurencja. Rekurencja zwana także rekursją jest jedną z najważniejszych metod konstruowania rozwiązań i algorytmów.

Algorytm simplex i dualność

Wykład 3. Metoda dziel i zwyciężaj

Zestaw 1 ZESTAWY A. a 1 a 2 + a 3 ± a n, gdzie skªadnik a n jest odejmowany, gdy n jest liczb parzyst oraz dodawany w przeciwnym.

Metody rozwiązywania równań nieliniowych

Schematy blokowe I. 1. Dostępne bloki: 2. Prosty program drukujący tekst.

Definicja i własności wartości bezwzględnej.

Podstawy Informatyki. Inżynieria Ciepła, I rok. Wykład 9 Rekurencja

Po uruchomieniu programu nasza litera zostanie wyświetlona na ekranie

Sortowanie. LABORKA Piotr Ciskowski

Rozwiązywanie równań nieliniowych

Arkusz maturalny nr 2 poziom podstawowy ZADANIA ZAMKNIĘTE. Rozwiązania. Wartość bezwzględna jest odległością na osi liczbowej.

Ciała i wielomiany 1. przez 1, i nazywamy jedynką, zaś element odwrotny do a 0 względem działania oznaczamy przez a 1, i nazywamy odwrotnością a);

4. Postęp arytmetyczny i geometryczny. Wartość bezwzględna, potęgowanie i pierwiastkowanie liczb rzeczywistych.

5. Rozwiązywanie układów równań liniowych

EGZAMIN MATURALNY Z INFORMATYKI MAJ 2014 POZIOM ROZSZERZONY CZĘŚĆ I WYBRANE: Czas pracy: 90 minut. Liczba punktów do uzyskania: 20 WPISUJE ZDAJĄCY

FUNKCJA KWADRATOWA. Zad 1 Przedstaw funkcję kwadratową w postaci ogólnej. Postać ogólna funkcji kwadratowej to: y = ax + bx + c;(

Przykładowe zadania z teorii liczb

Raport z projektu. Przedmiot: Algorytmy i struktury danych 1 Projekt: Wieża Hanoi Autor: Wojciech Topolski

Analiza algorytmów zadania podstawowe

Sortowanie przez wstawianie Insertion Sort

Technologie cyfrowe. Artur Kalinowski. Zakład Cząstek i Oddziaływań Fundamentalnych Pasteura 5, pokój 4.15

WYKŁAD 3 WYPEŁNIANIE OBSZARÓW. Plan wykładu: 1. Wypełnianie wieloboku

Materiały: kartki papieru (5 x 5 kolorów), piłeczki pingpongowe (5 x 5 kolorów), worek (nieprzeźroczysty).

Zagadnienia - równania nieliniowe

Podyplomowe Studium Programowania i Systemów Baz Danych

Transkrypt:

Metoda bisekcji (inaczej połowienia przedziału lub równych podziałów) Metoda służy do wyznaczenia miejsca zerowego danej funkcji i polega na cyklicznym połowieniu zadanego z góry przedziału (w którym znajduje się pierwiastek) aż do osiągnięcia zadanej dokładności. Twierdzenie Jeżeli funkcja ciągła f(x) ma na końcach przedziału domkniętego wartości różnych znaków, to wewnątrz tego przedziału, istnieje co najmniej jeden pierwiastek równania f(x) = 0. Aby można było zastosować metodę, muszą być spełnione założenia: 1. funkcja f(x) jest ciągła w przedziale domkniętym [a; b] 2. funkcja przyjmuje różne znaki na końcach przedziału: f(a)f(b) < 0 1

Algorytm 1. Sprawdzamy, czy pierwiastkiem równania jest punkt s leżący w środku przedziału [a, b] (tj s=(a+b)/2), czyli czy f(s) = 0. Jeżeli tak jest, algorytm kończy się (znaleźliśmy rozwiązanie). 2. W przeciwnym razie s dzieli przedział [a, b] na dwa mniejsze przedziały: [a, s] oraz [s, b]. Wybierany jest ten przedział, dla którego spełnione jest drugie założenie, tzn. albo f(s)f(a) < 0 albo f(s)f(b) < 0. Cały proces powtarzany jest od punktu 1 dla wybranego przedziału i do osiągnięcia żądanej dokładności eps przybliżenia pierwiastka. 2

Algorytm (opis alternatywny) Pętla, wykonywana dopóki długość przedziału (b-a) jest większa od dokładności eps: Wylicz środek przedziału s = (a+b)/2 Jeżeli pierwiastkiem równania jest punkt s (tzn. jeżeli f(s) = 0), to wynik = s, zakończ pętlę W przeciwnym wypadku s dzieli przedział [a, b] na dwa mniejsze przedziały - [a, s] oraz [s, b]. Wybierany jest przedział z miejscem zerowym, tzn. jeżeli f(a)*f(s) < 0 to przypisz zmiennej b wartość s, a jeżeli f(s)*f(b) < 0 to przypisz zmiennej a wartość s. wynik = s 3

Wyszukiwanie Wejście: posortowana, n-elementowa tablica liczbowa T oraz liczba p. Wyjście: liczba naturalna, określająca pozycję elementu p w tablicy T, bądź 1, jeżeli element w tablicy nie występuje. Gdyby tablica T była nieposortowana, zastosowalibyśmy wyszukiwanie liniowe (przeszukiwanie całej tablicy od początku do końca). Koszt: O(n). Wyszukiwanie binarne Wyszukiwanie binarne polega na tropieniu fragmentu tablicy, o którym wiemy, że musi zawierać element p, o ile element ten znajduje się w tablicy T. Początkowo tym fragmentem jest cała tablica. Przedział kurczy się po porównaniu środkowego elementu ze zmienną p i odrzuceniu odpowiedniej połowy tego przedziału. Proces trwa do chwili odnalezienia p w tablicy lub do momentu, gdy wiadomo, że przedział, w którym musiałby się on znajdować, jest pusty. Złożoność obliczeniowa: O(log 2 n). 4

Sformułowanie algorytmu Wiemy, że jeżeli p znajduje się w gdziekolwiek w tablicy T, to musi być w określonym przedziale. Oznaczmy ten fakt skrótem: musi_być(przedział). Szkic programu: zainicjuj przedział jako 1...n pętla // niezmiennik: musi_być(przedział) jeżeli przedział pusty elementu p nie ma w tablicy T koniec oblicz wartość środek, środka przedziału użyj środek do testów, aby zmniejszyć przedział jeżeli p znaleziono podczas testu wynik = pozycja p w tablicy koniec 5

Przedział reprezentujemy przy pomocy dwóch indeksów: dół, góra. Oznaczenie musi_być(dół, góra) oznacza, że jeżeli element znajduje się gdzieś w tablicy, to znajduje się w przedziale domkniętym T[dół... góra]. Inicjowanie: jakie wartości muszą mieć zmienne góra i dół, aby warunek musi_być(dół, góra) był spełniony? Oczywiście 1 oraz n. A zatem: dół = 1 góra = n Następnie sprawdzamy, czy przedział jest pusty: jeżeli dół > góra wynik = -1 // elementu nie ma w tablicy koniec 6

Obliczamy wartość środka przedziału: środek = (dół + góra) div 2 // Dzielenie całkowite Szkic programu wygląda teraz tak: dół = 1 góra = n pętla // niezmiennik: musi_być(dół, góra) jeżeli dół > góra wynik = -1 koniec środek = (dół + góra) div 2 użyj środek do testów, aby zmniejszyć przedział [dół... góra] jeżeli p znaleziono podczas testu wynik = pozycja p w tablicy koniec 7

Teraz porównujemy p i T[środek] oraz podejmujemy odpowiednie działania w celu zachowania niezmiennika (4 ostatnie wiersze). Piszemy: jeżeli T[środek] < p: przypadek A jeżeli T[środek] == p: przypadek B jeżeli T[środek] > p: przypadek C Przypadek B oznacza, że znaleziono element: przypisujemy wynik = środek i kończymy program. Analiza przypadku A: Jeżeli T[środek] < p, to T[dół] T[dół+1]... T[środek] < p. Innymi słowy, p nie może znajdować się w przedziale T[dół... środek]. Zatem, jeżeli p znajduje się w tablicy T, to znajduje się w przedziale [środek + 1... góra], co zapisujemy: musi_być(środek + 1, góra). Przywracamy zatem prawdziwość niezmiennika musi_być(dół, góra) poprzez podstawienie: dół = środek + 1. 8

Analogicznie, w przypadku C przywracamy niezmiennik podstawiając: góra = środek 1. Ostateczna postać pseudokodu wyszukiwania binarnego: dół = 1 góra = n pętla // niezmiennik: musi_być(dół, góra) jeżeli dół > góra wynik = -1 koniec środek = (dół + góra) div 2 jeżeli T[środek] < p: dół = środek + 1 jeżeli T[środek] == p: wynik = środek; koniec jeżeli T[środek] > p: góra = środek - 1 9

Dowód poprawności algorytmu Metoda niezmienników Floyda (przypomnienie) wyróżnić newralgiczne punkty w algorytmie, określić warunki (niezmienniki), jakie mają być spełnione w każdym wyróżnionym punkcie, udowodnić poprawność kolejnych warunków, zakładając poprawność warunków poprzedzających, własność stopu udowodnić np. metodą liczników iteracji lub metodą malejących wielkości. 10

1. // musi_być(1, n) 2. dół = 1; góra = n 3. // musi_być(dół, góra) 4. pętla 5. // musi_być(dół, góra) 6. jeżeli dół > góra 7. // dół > góra i musi_być(dół, góra) 8. // p nie ma w tablicy T 9. wynik = -1; koniec pętli 10. // dół góra i musi_być(dół, góra) 11. środek = (dół + góra) div 2 12. // dół środek góra i musi_być(dół, góra) 13. jeżeli T[środek] < p 14. // musi_być(dół, góra) i nie_może_być(dół, środek) 15. // musi_być(środek+1, góra) 16. dół = środek + 1 17. // musi_być(dół, góra) 18. jeżeli T[środek] == p 19. // T[środek] == p 20. wynik = środek; koniec pętli 21. jeżeli T[środek] > p 22. // musi_być(dół, góra) i nie_może_być(środek, góra) 23. // musi_być(dół, środek-1) 24. góra = środek -1 25. // musi_być(dół, góra) 26. // musi_być(dół, góra) 11

Dowód poprawności algorytmu wyszukiwania binarnego będzie się składał się z 3 części: 1. Inicjowanie. Niezmiennik jest prawdziwy podczas pierwszego wykonania pętli. 2. Zachowanie prawdziwości niezmiennika. Jeżeli niezmiennik jest prawdziwy na początku iteracji i treść pętli zostanie wykonana, to niezmiennik pozostanie prawdziwy po jej zakończeniu. 3. Zakończenie. Pętla się skończy i da pożądany skutek (u nas: nadanie zmiennej wynik odpowiedniej wartości). 12

Szczegółowa analiza (uwaga nudne!). Prawdziwość warunku (asercji) z wiersza 1, czyli musi_byc(1,n), wynika z definicji tego warunku: jeśli p znajduje się w tablicy, to musi być w przedziale T[1...n]. Przypisania w wierszu 2 zapewniają więc prawdziwość asercji z wiersza 3, czyli musi_być(dół, góra). Inicjowanie pętli: wiemy, że asercja w wierszu 3 jest taka sama, jak w wierszu 5. Jeżeli przeprowadzimy odpowiednią analizę dla wierszy 6-26 będziemy wiedzieli, że prawdziwość niezmiennika jest w pętli zachowana, bo asercje w wierszach 5 i 26 są identyczne. Pozytywny wynik testu w wierszu 6 prowadzi do asercji w wierszu 7: jeśli p znajduje się gdziekolwiek w tablicy, to musi być między dół i góra dla dół < góra. Z tych warunków wynika wiersz 8: p nie ma w tablicy. Tak więc poprawnie kończymy pętlę w wierszu 9 po nadaniu zmiennej wynik wartości -1. Jeżeli test w wierszu 6 da wynik negatywny, to przechodzimy do wiersza 10. Niezmiennik jest nadal zachowany (nie zrobiliśmy nic, co mogłoby go zmienić), a w wyniku testu wiemy, że dół <= góra. Wiersz 11 to nadanie zmiennej środek wartości średniej z dół i góra, zaokrąglonej w dół do najbliższej liczby całkowitej. Ponieważ średnia zawsze znajduje się pomiędzy dwiema wartościami a zaokrąglenie nie zmniejszy jej poniżej dół, prawdziwa jest asercja w wierszu 12. Dowód poprawności instrukcji warunkowych w wierszach 13-25 dotyczy każdego z trzech możliwych przypadków. Przypadek drugi (wiersz 18): ponieważ prawdziwa jest asercja z wiersza 19, nadanie zmiennej wynik wartości środek i zakończenie pętli są poprawne. To jest drugie miejsce, w którym pętla może się zakończyć. 13

Pozostałe przypadki (czyli pierwszy i trzeci) są symetryczne. Rozpatrzmy dla przykładu warunek z wierszy 21-25. Pierwszy człon asercji z wiersza 22 nie został naruszony podczas działania programu. Drugi człon jest prawdziwy, bo p < T[środek] T[środek+1]... T[n] wiemy, że p nie może się znajdować w tablicy powyżej indeksu środek-1, co wyrażone zostało warunkiem nie_może_być(środek, góra). Logika podpowiada, że jeżeli p musi być między dół a góra, i nie może być pod indeksem środek ani wyżej, to musi być znajdować się między dół a środek-1 (o ile w ogóle się oczywiście w tablicy znajduje). Stąd się bierze wiersz 23. Wykonanie instrukcji z wiersza 24 przy prawdziwej asercji z wiersza 23, daje prawdziwość asercji w wierszu 25. Zatem niezmiennik w wierszu 26 pozostaje prawdziwy. Rozumowanie dla wierszy 13-17 wygląda identycznie. Wykazaliśmy więc, że jeżeli pętla się kończy, to zmienna wynik ma właściwą wartość. Może się jednak pojawić pętla nieskończona. W dowodzie własności stopu wykorzystamy metodę malejących wielkości. Przedział dół... góra ma początkowy rozmiar n. Z wierszy 6-9 wynika, że pętla się skończy, jeżeli przedział zawiera mniej niż jeden element. Musimy więc wykazać, że przedział się zmniejsza przy każdym obiegu pętli. Na podstawie wiersza 12 wiemy, że środek znajduje się zawsze w bieżącym przedziale. Pierwsza i trzecia instrukcja warunkowa wykluczają indeks środek z bieżącego przedziału i w ten sposób zmniejszają jego rozmiar co najmniej o 1. A zatem pętla a co za tym idzie cały program musi się zatrzymać. 14

Generowanie podciągów Problem Na wejściu znajdują się dwie liczby całkowite m i n, gdzie m <= n. Wynikiem jest posortowana lista m losowych liczb całkowitych z przedziału 1... n, wśród których żadna nie powtarza się dwukrotnie. Algorytm nr 1 zwykłe wybieranie Generujemy m liczb pseudolosowych z przedziału 1... n. Po każdym losowaniu sprawdzamy, czy liczba się nie powtórzyła; w takim przypadku powtarzamy losowanie. Wylosowane liczby sortujemy wybraną metodą. Zalety: prosty, intuicyjny Wady: nieefektywny (szczególnie dla m n), konieczność sortowania wyników 15

Pseudokod: wczytaj m, n pętla od i=1 do m powtarzaj wygeneruj liczbę losową los z przedziału [1,n] jeżeli i > 1 to sprawdź, czy liczba los już wcześniej wystąpiła: wystąpiła = false pętla od j=1 do i-1 jeżeli W[j] == los wystąpiła = true zakończ pętlę jeżeli wystąpiła == true zapisz los do wyniku: W[i] = los posortuj tablicę W koniec 16

Algorytm nr 2 test losowy Algorytm analizuje kolejno liczby całkowite 1, 2,..., n i na podstawie odpowiedniego testu losowego decyduje, czy wybrać, czy też odrzucić każdą z nich. Oglądając liczby po kolei mamy pewność, że w wyniku otrzymamy ciąg posortowany. Rozważmy przykład, w którym m = 2 i n = 5. Powinniśmy wybrać liczbę 1 z prawdopodobieństwem 2/5; program powinien realizować to zadanie za pomocą instrukcji w rodzaju if RandReal(0,1) < 2/5 then... Niestety, nie możemy wybrać liczby 2 z tym samym prawdopodobieństwem: w wyniku takiego postępowania nie mielibyśmy pewności, że otrzymamy dokładnie 2 liczby spośród 5. Tak więc na następnej decyzji zaważy poprzedni wybór i decyzję na temat liczby 2 podejmiemy z prawdopodobieństwem 1/4, jeśli jedynka została wybrana i 2/4, jeśli wybrana nie została. Ogólnie, aby wylosować w liczb spośród p pozostałych, będziemy następną liczbę wybierać z prawdopodobieństwem w/p. 17

Zalety: oparty na solidnych podstawach matematycznych, wynik od razu posortowany. Wady: nieefektywny dla m «n Pseudokod: wczytaj m, n wybierz = m pozostało = n pętla od i=1 do n oblicz prawdopodobieństwo wylosowania i-tej liczby, prawd = wybierz / pozostało wygeneruj liczbę losową los z przedziału [0,1) jeżeli los < prawd wypisz i wybierz = wybierz 1 pozostało = pozostało - 1 koniec 18

Algorytm nr 3 przemieszanie Umieszczamy liczby z przedziału 1... n w n-elementowej tablicy T. Następnie mieszamy (czyli zamieniamy) pierwszych m elementów tablicy T z elementami 1... n tej samej tablicy (oczywiście, w szczególnym przypadku taka zamiana może nie nastąpić, gdy chcąc przemieszać i-tą liczbę wylosujemy właśnie liczbę i). Wynikiem (po posortowaniu) jest tablica złożona z pierwszych m przemieszanych elementów z tablicy T. Zalety: szybki (szczególnie dla m «n) Wady: wymaga użycia sortowania oraz pomocniczej tablicy 19

Pseudokod: wczytaj m, n utwórz tablicę T=[1,2,...,n]: pętla od i=1 do n T[i] = i pętla od i=1 do m wygeneruj liczbę losową los z przedziału [1,n] zamień T[i] z T[los] pętla od i=1 do m // Utwórz tablicę wynikową W = T[1,2,...,m] W[i] = T[i] posortuj tablicę W koniec 20

Problem komiwojażera Wejście: n punktów (miast), odległości pomiędzy miastami (d ij i, j = 1, 2,..., n); Wyjście: trasa komiwojażera przez wszystkie miasta (przy czym dopuszczalna jest tylko jedna wizyta w każdym mieście permutacja miast) o najmniejszej sumie odległości. Bardziej formalnie: znaleźć cykl w grafie o minimalnym całkowitym koszcie. Przykład: Miasta={Gdańsk, Warszawa, Poznań, Kraków}, Odległości={ {Gdańsk, Kraków}=700, {Gdańsk, Warszawa}=300, {Gdańsk, Poznań}=280, {Warszawa, Poznań}=320, {Warszawa, Kraków}=350, {Poznań, Kraków}=360}. Należy znaleźć najkrótszą trasę wychodzącą np. z Gdańska i przechodzącą jednokrotnie przez wszystkie pozostałe miasta i wracającą do Gdańska. 21

Złożoność obliczeniowa algorytmu bezpośredniego: O(n!) tyle tras jest do porównania. Powstały różne algorytmy usprawniające algorytm bezpośredni (programowanie liniowe, metody typu podział-ograniczenie itp.), ale nie udało się pokonać granicy O(2 n ). Istnieją też algorytmy heurystyczne, które rozwiązują problem w przybliżeniu, bez gwarancji, że otrzymane rozwiązanie jest optymalne. Najlepszy do chwili obecnej rezultat: rozwiązano problem 85900 miast przy użyciu programu CONCORDE (mieszanina metod dokładnych i heurystycznych, 2006 rok). Czas działania pojedynczego procesora dla otrzymania tego rozwiązania: ponad 136 lat. 22

Wieże Hanoi Zadanie polega na przeniesieniu wieży na inny pręt, z zachowaniem następujących reguł: jednorazowo można przenosić tylko jeden krążek dopuszczalne jest umieszczanie tylko mniejszego krążka na większym algorytm rekurencyjny złożoność O(2 n ) 23

Oznaczmy podstawki przez A, B, C, niech n oznacza liczbę krążków, ponumerujmy krążki od najmniejszego u góry do największego u dołu. W celu przeniesienia n krążków z A do B należy: przenieść n-1 krążków z A do C wówczas n-ty dysk samotnie pozostaje w A przenieść n-ty (największy krążek) z A do B przenieść n-1 krążków z C do B 24