plik


Projektowanie efektywnych algorytmw Laboratorium TEMAT: Algorytm programowania dynamicznego PROBLEM: Problem Komiwoja|era Data oddania & .......................................... Ocena & .......................................... Autor: MichaB Kaczara Nr indeksu: 181132 Rok i kierunek Informatyka I st. in|., rok 3, sem. 5 studiw: Grupa wiczeniowa: PN/TN 9:15-11:00 Prowadzcy: Mgr in|. Agata RusoD 1. Opis sBowny i matematyczny problemu. Kryterium optymalizacji 1.1 Opis problemu Problem Komiwoja|era(ang. TSP  Travelling Salesman Problem) definiuje sytuacj, w ktrej komiwoja|er ma odwiedzi wszystkie N miast tylko raz i wrci do miasta pocztkowego, przy czym trasa jego podro|y powinna by jak najkrtsza. Droga pomidzy ka|d par miast ma parametr  koszt jej przebycia, dBugo[ lub np. czas podr|y. W rozpatrywanym przypadku parametrem jest koszt przebycia drogi. Pod wzgldem matematycznym, problem ma swoje odzwierciedlenie w teorii grafw. Ka|de z N miast jest wierzchoBkiem grafu zupeBnego, wa|onego  ka|da krawdz Bczca dwa wierzchoBki(Vi, Vj) ma wag, odpowiadajc kosztowi przebycia drogi z Vi do Vj. Znalezienie takiej drogi, aby ka|dy z N wierzchoBkw wystpowaB na niej tylko raz sprowadza si do znalezienia w grafie tzw. cyklu Hamiltona. Problem Komiwoja|era jest problemem NP-trudnym. 1.2 Dane wej[ciowe problemu Dane wej[ciowe problemu stanowi N-wierzchoBkowy graf peBny, wa|ony, przedstawiony w postaci macierzy kosztw o rozmiarach NxN, zapisanej w pliku tekstowym. Ka|da warto[ macierzy nale|y do przedziaBu <0;100> i jest oddzielona od pozostaBych za pomoc tabulatora(\t). Poniewa| z miasta Ni do miasta Ni drogi nie ma, diagonala macierzy zawiera warto[ci reprezentujce nieskoDczono[. Dla uBatwienia implementacji za nieskoDczono[ przyjta zostaBa liczba 9999. Listing 1. PrzykBadowe dane wej[ciowe problemu 9999 9 93 13 42 9999 88 16 17 88 9999 36 33 7 21 9999 1.3 Rozwizanie problemu Rozwizanie problemu skBada si z czterech linii. W pierwszej znajduje si caBkowity koszt optymalnej trasy; w drugiej: wektor indeksw N miast, ktre kolejno wystpuj na trasie(z uwzgldnieniem powrotu do pocztkowego, dBugo[ wektora  N+1). Kolejne indeksy s oddzielone przecinkiem i znakiem spacji; w trzeciej: czas wykonania algorytmu podany w milisekundach; Warto[ czwartej linii jest [ci[le zale|na od implementacji i zawiera liczb bdc warto[ci licznika u|y danych zapisanych poprzednio w pamici. Listing 2. PrzykBadowe rozwizanie problemu 63 [ 0, 1, 3, 2, 0 ] 15 0 2 1.4 Kryterium optymalizacji Za kryterium optymalizacji zostaBa przyjta minimalizacja kosztu cyklu Hamiltona w grafie wej[ciowym, co jest rwnowa|ne znalezieniu najkrtszej drogi przej[cia przez graf. 2. Opis dziaBania algorytmu 2.1 Algorytm przegldu zupeBnego Metoda przegldu zupeBnego zastosowana w przypadku problemu komiwoja|era polega na znalezieniu wszystkich mo|liwych cykli Hamiltona w zadanym grafie, a nastpnie wybranie spo[rd nich takiego, ktrego obliczony koszt jest najmniejszy. Krtka analiza zBo|ono[ci obliczeniowej tego algorytmu: Wezmy graf o N=9 wierzchoBkach i policzmy ile ma cykli Hamiltona. Z pierwszego wierzchoBka mo|emy wybra 8 krawdzi, z drugiego 7, z trzeciego 6, & , z dziewitego  1 krawdz. W efekcie liczba cykli Hamiltona jest rwna: H = 8 * 7 * 6 * 5 * & * 1 = 8! = 40 320 Zatem dla N wierzchoBkw liczba cykli wyniesie H = (N-1)!. Wynik ten nale|y do wykBadniczej klasy zBo|ono[ci obliczeniowej O(n!). 2.2 Algorytm programowania dynamicznego Algorytm programowania dynamicznego zostaB zaimplementowany przeze mnie wg zasady dziel i zwyci|aj(ang. divide & conquer), polegajcej na rekurencyjnym podziale gBwnego problemu na podproblemy, tak aby rozwizywa najprostsze instancje problemw, ktrych rozwizania s potem scalane. Rozwizania (koszt i [cie|ka) uzyskane w ka|dym z krokw s zapisywane do struktur umo|liwiajcych ich przechowywanie i identyfikacj  dziki temu algorytm mo|e wykonywa si szybciej, bo przed rozwizaniem podproblemu sprawdza, czy nie zostaB on ju| wcze[niej rozwizany i je[li tak, to zwraca to rozwizanie(pomija zbdne obliczenia). Do przechowywania rozwizaD po[rednich wykorzystaBem specyficzne struktury dostpne w jzyku Java(wicej w pkt. 4). Podproblemy, ktre mog by rozwizane w ramach danego problemu nadrzdnego okre[la tablica o rozmiarze N z wpisanymi pod odpowiednie indeksy warto[ciami logicznymi TRUE lub FALSE. Je[li wpis na i-tej pozycji tablicy to TRUE, algorytm bdzie kontynuowaB dziaBanie bez wywoBywania rekurencji dla tego podroblemu, w przeciwnym wypadku rekurencja zostanie wywoBana. W przypadku, w ktrym wszystkie elementy tablicy maj warto[ci TRUE, jako [cie|ka zapisywane jest miasto pocztkowe, a jako koszt  warto[ na pozycji [aktualne miasto][miasto pocztkowe] w macierzy kosztw 3 instancji problemu. Scalanie wynikw podproblemw zostaBo przeze mnie zrealizowane w dwch krokach: wyznaczenie minimum z kosztw dla ka|dego z podproblemw i zapisanie numeru podproblemu, dla ktrego koszt byB minimalny, po rozwizaniu wszystkich mo|liwych podproblemw: stworzenie tablicy zawierajcej [cie|k, skBadajc si z numeru podproblemu, dla ktrego koszt byB minimalny i [cie|ki uzyskanej w wyniku rozwizywania tego podproblemu. Aby algorytm dziaBaB poprawnie, konieczne byBo wprowadzenie odpowiedniego sterowania warto[ciami tablicy u|ytych miast(rozwizanych podproblemw). Przed ka|dym wywoBaniem rekurencji na pozycji danego podproblemu w tablicy ustawiana jest warto[ TRUE. Po wykonaniu si rekurencji, warto[ ustawiana jest z powrotem na FALSE. 2.2.1 Pseudokod algorytmu Poni|ej zamieszczam pseudokod zaimplementowanego algorytmu programowania dynamicznego. Listing przedstawia tre[ funkcji rekurencyjnej liczKoszt, przy zaBo|eniu, |e instancja problemu zostaBa wczytana poprawnie, zostaBo wybrane miasto pocztkowe miastoStart, np. 0, zostaBa stworzona tablica miast u|ytych miastaUzyte i wpisana warto[ TRUE na pozycji miastoStart, zostaBa stworzona tablica listaWynik, w ktrej przechowywana bdzie lista wierzchoBkw znajdujcych si na optymalnej [cie|ce oraz struktury koszty i sciezki, w ktrych przechowywane bd wyniki uzyskane dla kolejnych podproblemw. Listing 3. Pseudokod algorytmu DP dla TSP procedure liczKoszt(tablica, listaWynik, aktualneMiasto, miastoStart, uzyteMiasta) begin wynik ! stworzTablice(pobierzRozmiar(uzyteMiasta) aktualneID ! aktualneMiasto + toString(uzyteMiasta) if wszystkieUzyte(uzyteMiasta) then begin dopisz(listaWynik, miastoStart) dopisz(koszty, aktualneID, tablica[aktualneMiasto][miastoStart]) return tablica[aktualneMiasto][miastoStart] end else begin if pobierz(koszty, aktualneID) != null then begin dopisz(listaWynik, pobierz(sciezki, aktualneID)) licznik ! licznik + 1 return pobierz(koszty, aktualneID) end 4 for i ! pobierzRozmiar(uzteMiasta) step -1 until 0 do begin if uzyteMiasta[i] continue uzyteMiasta[i] ! TRUE k ! liczKoszt(tablica,wynik[i],i,miastoStart,uzyteMiasta) uzyteMiasta[i] ! FALSE k ! k + tablica[aktualneMiasto][i] if k < min then begin Min ! k wynikIdx ! i end end dopisz(temp, wynikIdx) dopisz(temp, wynik[wynikIdx]) dopisz(listaWynik, temp) dopisz(koszty, aktualneID, min) dopisz(sciezki, aktualneID, temp) end end 3. PrzykBadowe rozwizania dla wybranej instancji Poni|ej zamieszczam przykBadowe rozwizanie algorytmu dla instancji przedstawionej na listingu 1.(str 2.). Macierz kosztw jest macierz kwadratow i asymetryczn o rozmiarach 4x4, rozwa|am wic asymetryczny problem komiwoja|era dla N=4 miast. 9999 9 93 13 42 9999 88 16 [ ] 17 88 9999 36 33 7 21 9999 3.1 WywoBanie funkcji liczKoszt() uzyteMiasta = T, F, F, F Nie wszystkie miasta s odwiedzone i nie ma odpowiedniego wpisu w mapie kosztw  przechodzimy do ptli i wywoBujemy odpowiednie rekurencje i = 3 3.1.1 Rekurencja, miasto: 3, listaWynik: wynik[3] uzyteMiasta = T, F, F, T Nie wszystkie miasta s odwiedzone i nie ma odpowiedniego wpisu w mapie kosztw  przechodzimy do ptli i wywoBujemy odpowiednie rekurencje i = 3 uzyteMiasta[3] == T, wic kontynuujemy i = 2 5 3.1.1.1 Rekurencja, miasto: 2, listaWynik: wynik[2] uzyteMiasta = T, F, T, T Nie wszystkie miasta s odwiedzone i nie ma odpowiedniego wpisu w mapie kosztw  przechodzimy do ptli i wywoBujemy odpowiednie rekurencje i = 3 uzyteMiasta[3] == T, wic kontynuujemy i = 2 uzyteMiasta[2] == T wic kontynuujemy i = 1 3.1.1.1.1 Rekurencja, miasto: 1, listaWynik: wynik[1] uzyteMiasta = T, T, T, T Wszystkie miasta odwiedzone  zapis wynikw listaWynik = 0; koszty += (1 [T, T, T, T]; tablica[1,0] = 42) koszt = 42 + tablica[2][1] = 130 min = 130 wynikIdx = 1 i = 0 uzyteMiasta[0] == T, wic kontynuujemy listaWynik = 1,0 koszty += (1 [T, F, T, T]); 130) sciezki += (1 [T, F, T, T); 1,0) koszt = 130 + tablica[3][2] = 151 min = 151 wynikIdx = 2 i = 1 3.1.1.2 Rekurencja, miasto: 1, listaWynik: wynik[1] uzyteMiasta = T, T, F, T Nie wszystkie miasta s odwiedzone i nie ma odpowiedniego wpisu w mapie kosztw  przechodzimy do ptli i wywoBujemy odpowiednie rekurencje i = 3 uzyteMiasta[3] == T, wic kontynuujemy i = 2 3.1.1.2.1 Rekurencja, miasto: 2, listaWynik: wynik[2] uzyteMiasta = T, T, T, T Wszystkie miasta odwiedzone  zapis wynikw listaWynik = 0; 6 koszty += (1 [T, T, T, T]; tablica[2][0] = 17) koszt = 17 + tablica[1][2] = 105 min = 105 wynikIdx = 2 i = 1 uzyteMiasta[1] == T, wic kontynuujemy i = 0 uzyteMiasta[0] == T, wic kontynuujemy listaWynik = 2,0 koszty += (1 [T, T, F, T]); 105) sciezki += (1 [T, T, F, T); 2,0) koszt = 105 + tablica [2][1] = 112 min = 112 wynikIdx = 1 i = 0 uzyteMiasta[0] == T, wic kontynuujemy listaWynik = 1, 2, 0 koszty += (3 [T, F, F, T]); 112) sciezki += (1 [T, F, F, T); 1,2,0) koszt = 112 + tablica[0][3] = 125 min = 125; wynikIdx = 3; i = 2 Wykonujemy operacje analogiczne do przedstawionych powy|ej. Warto[ minimalna si nie zmieni. i = 1 Wykonujemy operacje analogicznie do przedstawionych powy|ej. Po ich wykonaniu warto[ minimum wyniesie 63, a [cie|ka bdzie kolejno przyjmowa warto[ci: 0; 2,0, nastpnie: 3,2,0. Indeks tablicy [cie|ek bdzie rwny 1. i = 0 uzyteMiasta[0] == T, wic kontynuujemy listaWynik = 1,3, 2, 0 koszty += (0 [T, F, F, F]; 63) sciezki += (0 [T, F, F, F]; 1,3,2,0) 3.2 Wyniki 63  koszt przebycia drogi [0, 1, 3, 2, 0] - droga 1500000  czas wykonywania  25 min, zajBo mi przeliczenie na kartkach 0  licznik wykorzystaD rozwizaD podproblemw 7 4. SzczegBy implementacyjne Algorytm zostaB zaimplementowany w jzyku Java, w [rodowisku Eclipse. CaBy program jest reprezentowany przez jedn klas KomiwojazerDP, w ktrej zdefiniowane s metody niezbdne do rozwizania problemu oraz pomocnicze, np. metoda odpowiedzialna za konwersj tablicy warto[ci typu boolean na BaDcuch tekstowy, w ktrym 1 oznaczaj TRUE a 0 - FALSE. Program, do przechowywania rozwizaD podproblemw, korzysta ze struktur HashMap dostpnych domy[lnie w jzyku Java. Wyniki s przechowywane na zasadzie klucz => warto[, gdzie klucz to warto[ zmiennej aktualneID(pkt. 2.2.1). Poni|ej zamieszczam listing najwa|niejszej funkcji  liczKoszt(). Listing 4. Metoda liczKoszt klasy KomiwojazerDP private static int liczKoszt(int [][]tablica, ArrayList<Integer> listaWynik, int aktualneMiasto, int miastoStart, boolean[] uzyteMiasta){ //Tablica ze sciezka wynikowa ArrayList<Integer> []wynik = new ArrayList[uzyteMiasta.length]; String aktualneID = "" + aktualneMiasto + arrayToString(uzyteMiasta); System.out.println("Rekurencja (miasto "+aktualneMiasto+"):"); //Jezeli wszystkie miasta przebyte if(wszystkieUzyte(uzyteMiasta)){ listaWynik.add(miastoStart); int koszt = tablica[aktualneMiasto][miastoStart]; koszty.put(aktualneID, koszt); System.out.println("\t> Wszystkie miasta odwiedzone"); return koszt; } //Jezeli nie else { int min = Integer.MAX_VALUE; int wynikIdx = -1; //Jezeli podproblem juz rozwiazany if(koszty.get(aktualneID) != null){ listaWynik.addAll(sciezki.get(aktualneID)); licznik++; System.out.println("\t> Wykorzystanie wartosci obliczonej wczesniej"); return koszty.get(aktualneID); } //Jezeli nie to obliczenia System.out.println("\t> Obliczenia"); for(int i = uzyteMiasta.length -1; i >= 0; i--){ if(uzyteMiasta[i]) continue; //Rekurencja uzyteMiasta[i] = true; wynik[i] = new ArrayList<Integer>(); int koszt = liczKoszt(tablica, wynik[i], i, miastoStart, uzyteMiasta); uzyteMiasta[i] = false; koszt += tablica[aktualneMiasto][i]; //Aktualizacja kosztu minimalnego if(koszt < min){ min = koszt; wynikIdx = i; System.out.println("\t> Ustawienie minimum"); } } 8 //Zapis wynikow System.out.println("\t> Zapis wynikow"); ArrayList<Integer> temp = new ArrayList<Integer>(); temp.add(wynikIdx); temp.addAll(wynik[wynikIdx]); listaWynik.addAll(temp); koszty.put(aktualneID, min); sciezki.put(aktualneID, temp); System.out.println("\t> Powrot poziom wyzej"); return min; } } Pomiar czasu wykonywania algorytmu wykonany zostaB z u|yciem funkcji System.nanoTime(). Komputer, na ktrym testowany algorytm wyposa|ony byB w procesor Intel Core 2 Duo 2,2 GHz i 2 GB pamici RAM. Program uruchamiany byB pod systemem Windows 7 Professional 32-bit. 5. PrzykBad dziaBania programu dla wybranej instancji Poni|ej zamieszony zostaB listing zawierajcy przykBad dziaBania programu. Jest to wycig z konsoli programu Eclipse. Program wy[wietla kolejne rekurencje i akcje, ktre w ramach nich podejmuje. Informuje m.in. o dokonywaniu obliczeD, pomijaniu obliczeD, ustawianiu minimum i zapisie wynikw. Listing 5. PrzykBad dziaBania programu Program: Algorytm Dynamic Programming dla problemu komiwojazera Przedmiot: Projektowanie Efektywnych Algorytmw Autor: Michal Kaczara 181132 > Wczytywanie danych z pliku data04.txt... > Start! Rekurencja (miasto 0): > Obliczenia Rekurencja (miasto 3): > Obliczenia Rekurencja (miasto 2): > Obliczenia Rekurencja (miasto 1): > Wszystkie miasta odwiedzone > Ustawienie minimum > Zapis wynikow > Powrot poziom wyzej > Ustawienie minimum Rekurencja (miasto 1): > Obliczenia Rekurencja (miasto 2): > Wszystkie miasta odwiedzone > Ustawienie minimum > Zapis wynikow > Powrot poziom wyzej > Ustawienie minimum > Zapis wynikow > Powrot poziom wyzej > Ustawienie minimum Rekurencja (miasto 2): > Obliczenia 9 Rekurencja (miasto 3): > Obliczenia Rekurencja (miasto 1): > Wszystkie miasta odwiedzone > Ustawienie minimum > Zapis wynikow > Powrot poziom wyzej > Ustawienie minimum Rekurencja (miasto 1): > Obliczenia Rekurencja (miasto 3): > Wszystkie miasta odwiedzone > Ustawienie minimum > Zapis wynikow > Powrot poziom wyzej > Zapis wynikow > Powrot poziom wyzej Rekurencja (miasto 1): > Obliczenia Rekurencja (miasto 3): > Obliczenia Rekurencja (miasto 2): > Wszystkie miasta odwiedzone > Ustawienie minimum > Zapis wynikow > Powrot poziom wyzej > Ustawienie minimum Rekurencja (miasto 2): > Obliczenia Rekurencja (miasto 3): > Wszystkie miasta odwiedzone > Ustawienie minimum > Zapis wynikow > Powrot poziom wyzej > Zapis wynikow > Powrot poziom wyzej > Ustawienie minimum > Zapis wynikow > Powrot poziom wyzej > Stop! 63 [ 0, 1, 3, 2, 0 ] 3 0 6. Badania eksperymentalne Badania przeprowadziBem dla dziesiciu rozmiarw instancji problemu. Dane wej[ciowej macierzy kosztw byBy generowane losowo. Ka|de pole macierzy (oprcz tych le|cych na diagonali), mogBo przyjmowa warto[ci z zakresu <1;100>. Pomiary czasu wykonywania algorytmu zostaBy wykonane dla 100 instancji danego rozmiaru i u[rednione([rednia arytmetyczna). Tabela 1. Wyniki pomiarw czasu dziaBania algorytmu w zale|no[ci od rozmiaru instancji. Rozmiar instancji N 2 4 6 8 10 12 14 16 Zredni czas [ms] 0,01 0,02 0,12 2,27 20,43 186,73 1271,21 6788,43 Pomiarw dla instancji o rozmiarze N=18 nie byBem w stanie wykona, ze wzgldu na ograniczenie pamiciowe wirtualnej maszyny Java. Po zwikszeniu limitu pamici z 256 10 na 512 MB program policzyB rozwizanie, jednak w czasie rwnym ok. 50 s. Przy N=20 i zwikszeniu limitu pamici do 1 GB program nie potrafiB policzy rozwizania, wiksza ilo[ pamici nie mogBa zosta przydzielona ze wzgldu na ograniczon ilo[ pamici zainstalowanej w komputerze. Wykres 1. Zale|no[ czasu wykonywania algorytmu od rozmiaru instancji problemu. 8000 6788,43 7000 6000 5000 4000 Czas [ms] 3000 2000 1271,21 1000 186,73 0,01 0,02 0,12 2,27 20,43 0 2 4 6 8 10 12 14 16 Rozmiar instancji N 7. Wnioski 1. Krzywa widoczna na wykresie 1. pokazuje, |e zale|no[ czasu rozwizywania problemu w zale|no[ci od rozmiaru instancji ro[nie wykBadniczo, czyli zgodnie z przewidywaniami(algorytm programowania dynamicznego dla problemu komiwoja|era ma zBo|ono[ O(n22n)). 2. Najwiksza badana instancja posiadaBa N=16 miast. Przy instancjach wikszych, np. N=20 algorytm pracowaB nieprzerwanie przez dBu|szy okres czasu. Potwierdza to fakt, |e algorytm programowania dynamicznego najlepiej stosowa do maBych instancji problemw. Nie bez znaczenia mogBo by w tym wypadku losowe generowanie macierzy kosztw. Im wiksza instancja problemu tym wicej pamici operacyjnej potrzebowaB program. Do rozwizania problemu z N=16 miastami potrzebne byBo 265MB pamici, z N=18 ju| 512MB, a przy N=20 wicej ni| 1 GB. Du|e u|ycie pamici RAM to cecha algorytmw programowania dynamicznego i zarazem du|a wada tego rozwizania. 3. Zaimplementowany algorytm rozwizuje problem komiwoja|era sprawnie i wystarczajco szybko dla N < 14 miast. DziaBa wolniej ni| algorytm B&B. 11 Czas [ms] 4. Przyczyn du|ej zajto[ci pamici i du|ego czasu rozwizywania problemu ju| przy instancjach zawierajcych N>15 miast, jest prawdopodobnie sposb przechowywania po[rednich rozwizaD  s one indeksowane po kluczach bdcych BaDcuchami tekstowymi. Problemem jest te| przeszukiwanie struktur, ktre te rozwizania przechowuj. 12 8. Bibliografia [1] Alfred V. Aho, John E. Hopcroft, Jeffrey D. Ullman, Projektowanie i analiza algorytmw, Wyd. Helion, 2003, str. 41-47 [2] Politechnika WrocBawska, Programowanie dynamiczne (Dynamic Programming - DP) [online]. [Dostp 17 grudnia 2011]. Dostpny w Internecie: <ftp://sith.ict.pwr.wroc.pl/Informatyka/PEA/PD_wstep.pdf> [3] Maria Jose Serna Iglesias, Dynamic Programming [online]. [Dostp 17 grudnia 2011]. Dostpny w Internecie: <http://www.lsi.upc.edu/~mjserna/docencia/algofib/P07/dynprog.pdf> 13

Wyszukiwarka

Podobne podstrony:
DP Miscallenous wnt5 x86 32
sprawozdanie felixa2
Sprawozdanie Konduktometria
zmiany w sprawozdaniach fin
Errata do sprawozdania
2009 03 BP KGP Niebieska karta sprawozdanie za 2008rid&657
Sprawozdanie nr 3 inz
Sprawozdanie FundacjaBioEdu2007
6 dp!3 konspekt cukrzyca 09
Sprawozdanie Ćw 2
sprawozdanie 4
Fanuc 0T DP [TTT] L567 85
sprawozdanie 2009

więcej podobnych podstron