Teoria Obliczeń i Złożoności Obliczeniowej

Transkrypt

Teoria Obliczeń i Złożoności Obliczeniowej
Teoria Obliczeń i Złożoności Obliczeniowej
Laboratorium: Analiza złożonosci algorytmów dla problemów NP-zupełnych.
Problem komiwojażera (Travelling Salesman Problem).
Zadanie komiwojażera jest koncepcyjnie bardzo proste: komiwojażer musi odwiedzić każde miasto dokładnie
raz i wrócić do punktu startowego. Powinien tak zaplanować swoją trasę, znając koszt przejazdu między
miastami, aby zminimalizować całkowity koszt objazdu. Optymalnym rozwiązaniem jest więc przejechanie
przez wszystkie miasta jak najkrótszą drogą.
Udowodniono, iż zadanie komiwojażera jest NP-trudne, czyli nie znajdziemy algorytmu szukającego
optymalnego rozwiązania którego złożoność czasowa byłaby wielomianowa.
Prosto napisać algorytm znajdujący optymalne rozwiązanie, ale złożoność takiego algorytmu wyklucza go w
praktyce z użytku. Algorytm taki polega na kompletnym przeglądzie przestrzeni rozwiązań; ponieważ ilość
możliwych dróg rośnie z ilością miast jak N!, złożoność problemu wynosi O(N!).
Podobny problem pojawia się często w licznych zastosowaniach praktycznych i liczba "miast" może być
całkiem znaczna, więc powyższy algorytm kompletnie nie daje się do wykorzystania. Opracowuje się więc
algorytmy przybliżone, których wyniki nieznacznie "odstają" od wyników optymalnych. W praktyce nie gra
dużej roli czy zadanie np. sterowania ruchem głowicy jakiejś maszyny wydłuży się o kilka sekund...
Jeśli ,,zgadniemy'' sekwencję kolejnych miast, to możemy w czasie wielomianowym udowodnić, że przebyta
droga spełnia warunki zadania. Jednak nie znamy deterministycznego algorytmu znajdowania rozwiązania.
Stąd problemy o tych własnościach nazywamy ,,niedeterministycznie wielomianowymi'' -- nondeterministic
polynomial, czyli NP.
Skupiono się więc na znajdywaniu rozwiązań możliwie bliskich optymalnemu. W ciągu ostatnich kilku
dziesięcioleci powstało kilka algorytmów wyznaczania rozwiązania bliskiego optymalnemu: algorytm
najbliższego sąsiada, algorytm zachłanny, algorytm najbliższego wstawiania, najdalszego wstawiania,
podwajanego najkrótszego drzewa rozpinającego, oddzielania powłoki wypukłej, krzywej wypełniającej
przestrzeń, algorytmy Karpa, Litkego, Christofidesa itp.
Zajmiemy się przetestowaniem działania kilku algorytmów używanych do poszukiwania rozwiązania problemu
Komiwojażera:
Heurystyka to metoda znajdowania rozwiązań dla której nie ma gwarancji znalezienia rozwiązania
optymalnego, a często nawet prawidłowego. Rozwiązań tych używa się np. wtedy, gdy pełny algorytm jest
z przyczyn technicznych zbyt kosztowny... tak też jest w naszym przypadku.
Wśród algorytmów heurystycznych dużą role odgrywają algorytmy sukcesywnego dołączania węzłów.
W każdym kroku do trasy dodawane jest nowe miasto, proces ten trwa do chwili aż trasa złożona będzie ze
wszystkich miast. Istnieje wiele możliwych strategii dołączania miast np. dołączanie najdalszego miasta,
dołączanie najbliższego miasta itp.
Wyniki eksperymentów dla większych problemów potwierdzają, że długość rozwiązań uzyskiwanych za
pomocą tej metody dołączającej najdalej położone miasto jest lepsza od pozostałych metod sukcesywnego
dołączania węzłów.
O dołączeniu kolejnego miasta do ścieżki decyduje tu jego odległość od najbliższego miasta w cyklu.
Dołączamy to miasto, dla którego ta odległość jest największa. Raz dołączone do ścieżki częściowej miasto
pozostaje w niej w kolejnych iteracjach aż do końca postępowania. Rozwiązanie uzyskane za pomocą tej
metody jest zbliżone do optymalnego.
Zaletą takiego postępowania jest jego niska złożoność obliczeniowa.
Najbliższe miasto – drugim algorytmem jaki zbadaliśmy był algorytm dołączający do ścieżki kolejne miasta,
wybierając za każdym razem to, które znajuje się najbliżej dodanego ostatnio. Algorytm charakteryzuje duża
szybkość i prostota. Algorytm przegląda listę miast, oblicza odległości do każdego z nich i dołącza do ścieżki
to leżące najbliżej. W każdym kolejnm kroku liczba miast które można dołączyć do ścieżki maleje o 1.
Dla n miast algorytm musi więc wykonać n przebiegów, za każdym razem wybierając jedno z n-1, n-2, n-3 itd.
miast. Można z tego wywnioskować, że taki algorytm będzie miał złożoność O(nlogn). Pomimo tego daje on
jednak przeważnie słabe rezultaty...
Algorytmy genetyczne
Klasyczne algorytmy genetyczne używają łańcuchów binarnych o skończonej długości i dwóch operatorów:
binarnej mutacji i binarnego krzyżowania. Program oparty o algorytm genetyczny jest algorytmem
probabilistycznym, w którym generuje się populację osobników, która przekształcana jest w każdej kolejnej
iteracji. Każdy osobnik przedstawia możliwe rozwiązanie rozpatrywanego zadania. W przypadku problemu
Komiwojażera osobnikiem będzie struktura przedstawiająca ścieżkę łączącą wszystkie miasta. Początkowo
dysponujemy pewną populacją losowo wygenerowanych osobników i w kolejnych iteracjach przez selekcję
najlepszych z nich tworzy się kolejne populacje. Pewne osobniki nowej populacji podlegają dodatkowo
transformacji za pomocą operatorów genetycznych, dając w ten sposób nowe rozwiązania. Po kilku krokach
generacji program zbiega się i spodziewamy się, że najlepsze osobniki reprezentują rozwiązanie leżące
blisko optymalnego.
Reprezentacja trasy jest reprezentacją ścieżkową (kodowanie całkowitoliczbowe). Aby wyeliminować
możliwość powstania osobników niedopuszczalnych w przypadku testowanego algorytmu zastosowano
krzyżowanie z porządkowaniem. W tym krzyżowaniu potomków tworzy się na podstawie podtras pobranych z
rodziców (podtrasa pierwszego dziecka pobierana jest z drugiego rodzica natomiast podtrasa drugiego
dziecka z pierwszego). Następnie uzupełnia się trasy miastami pobranymi z drugiego rodzica z zachowaniem
porządku z pominięciem miast już wykorzystanych.
Jest to algorytm iteracyjny – kończy się, gdy rozwiązanie osiągnie pewną założoną dokładność.
Testy
Oto wyniki testów działania i efektywności powyższych algorytmów przeprowadzone dla 3 różnych
konfiguracji miast.
1.
(heurystyczny)
1611
(najbliższe miasto)
2078
(genetyczny)
1611
Na tym prostym przykładzie widać, że algorytm dołączający najbliższe miasto jest raczej mało efektywny.
Nawet
"na
oko"
widać,
że
rozwiązanie
odbiega
od
optimum.
Natomiast
pozostałe
2 algorytmy dały takie same rezultaty, co utwierdza nas w przekonaniu, że udało nam się znaleźć rozwiązanie
optymalne.
2.
(heurystyczny)
1733
(najbliższe miasto)
1487
(genetyczny)
3023
Dla tego specyficznego przypadku najlepszy wynik dał algorytm dołączający najbliższe miasto. Miasta jednak
w tym przypadku były ułożone w bardzo charakterystyczny sposób. Nieco gorzej poradził sobie z tym zadanie
algorytm heurystyczny. Zawiódł natomiast algorytm genetyczny, pomimo ustawienia ilości pokoleń na 10000.
Być może dobranie innych parametrów dla mutacji i krzyżowania dałoby lepszy efekt...
3.
(heurystyczny)
1248
(najbliższe miasto)
1377
(genetyczny)
1268
W tym wypadku najlepszy rezultat dał algorytm heurystyczny, a niewiele gorszy – genetyczny. Po raz kolejny
zawiódł algorytm dołączający najbliższe miasto...
Wnioski
Końcowy wniosek nasuwa się jeden: do rozwiązywania podobnych problemów należy zawsze używać kilku
metod, porównać ich wyniki i wybrać najlepszą dla konkretnego przypadku. W przypadku wszystkich
problemów NP-zupełnych jesteśmy skazani na algorytmy generujące rozwiązania przybliżone. Można też
łączyć różne techniki np. genrując za pomocą jednego algorytmu populację startową dla algorytmu
genetycznego. W wielu przypadkach algorytmy przybliżone dają na tyle satysfakcjonujące rezultaty, że
można z powodzeniem wykorzystywać je do rozwiązywania rzeczywistych problemów.

Podobne dokumenty