Professional Documents
Culture Documents
PRZYKADOWY ROZDZIA
SPIS TRECI
KATALOG KSIEK
KATALOG ONLINE
ZAMW DRUKOWANY KATALOG
TWJ KOSZYK
DODAJ DO KOSZYKA
CENNIK I INFORMACJE
ZAMW INFORMACJE
O NOWOCIACH
ZAMW CENNIK
CZYTELNIA
FRAGMENTY KSIEK ONLINE
Podstawy algorytmw
z przykadami w C++
Autorzy: Richard Neapolitan, Kumarss Naimipour
Tumaczenie: Bartomiej Garbacz, Pawe Gonera,
Artur Szczepaniak, Mikoaj Szczepaniak
ISBN: 83-7361-429-X
Tytu oryginau: Foundations of Algorithms.
Using C++ Pseudocode
Format: B5, stron: 648
Algorytmy s jednym z fundamentw programowania. Prawidowo zaprojektowany
algorytm jest podstaw efektywnego i niezawodnego programu. Opisanie problemu
w postaci algorytmu nie jest prostym zadaniem wymaga wiedzy z zakresu
matematyki, umiejtnoci oceny zoonoci obliczeniowej i znajomoci zasad
optymalizacji oblicze. Istnieje wiele metod projektowania algorytmw.
Znajomo tych metod znacznie uatwia analiz zagadnienia i przedstawienie go
w postaci zalgorytmizowanej.
Ksika Podstawy algorytmw z przykadami w C++ to kompletny podrcznik
powicony tym wanie zagadnieniom. Przedstawia sposoby podejcia
do rozwizywania zagadnie projektowych, udowadnia, e sporo z nich mona
zrealizowa rnymi metodami, a take uczy, jak dobra waciw metod
do postawionego problemu. Materia podzielony jest na wykady, zilustrowane
pseudokodem przypominajcym jzyk C++, co bardzo uatwia zastosowanie
poznanej wiedzy w praktyce.
Wprowadzenie do projektowania algorytmw
Zastosowanie techniki dziel i zwyciaj
Algorytmy programowania dynamicznego
Analiza zoonoci obliczeniowej algorytmw na przykadzie
lgorytmw sortowania i przeszukiwania
Algorytmy z zakresu teorii liczb
Algorytmy kompresji danych i kryptografii
Programowanie rwnolege
Wydawnictwo Helion
ul. Chopina 6
44-100 Gliwice
tel. (32)230-98-63
e-mail: helion@helion.pl
Spis treci
O Autorach ..............................................................................................9
Przedmowa............................................................................................11
Rozdzia 1. Algorytmy wydajno, analiza i rzd ...................................................17
1.1. Algorytmy......................................................................................................................... 18
1.2. Znaczenie opracowywania wydajnych algorytmw......................................................... 25
1.2.1. Wyszukiwanie sekwencyjne a wyszukiwanie binarne ........................................... 26
1.2.2. Cig Fibonacciego .................................................................................................. 28
1.3. Analiza algorytmw.......................................................................................................... 33
1.3.1. Analiza zoonoci.................................................................................................. 33
1.3.2. Zastosowanie teorii................................................................................................. 41
1.3.3. Analiza poprawnoci .............................................................................................. 42
1.4. Rzd .................................................................................................................................. 42
1.4.1. Intuicyjne wprowadzenie do problematyki rzdu................................................... 43
1.4.2. Formalne wprowadzenie do problematyki rzdu ................................................... 45
1.4.3. Wykorzystanie granic do okrelenia rzdu............................................................. 56
1.5. Zarys dalszej treci ksiki ............................................................................................... 59
wiczenia ................................................................................................................................. 60
Spis treci
Rozdzia 3.
Programowanie
dynamiczne
Jak zapewne Czytelnik pamita, liczba skadnikw obliczanych przez algorytm
typu dziel i zwyciaj w celu okrelenia n-tego wyrazu cigu Fibonacciego (algorytm 1.6) jest wykadnicza w stosunku do n. Wynika to z faktu, e podejcie typu
dziel i zwyciaj rozwizuje realizacj problemu poprzez jej podzia na mniejsze
realizacje, a nastpnie bezporednie rozwizywanie owych mniejszych realizacji. Jak
stwierdzono w rozdziale 2., jest to podejcie zstpujce. Sprawdza si ono w przypadku problemw w rodzaju sortowania przez scalanie, gdzie mniejsze instancje nie
s ze sob powizane. Dzieje si tak, poniewa kada z nich skada si z tablicy
kluczy, ktre musz zosta posortowane niezalenie. Jednake w przypadku problemw takich, jak n-ty wyraz cigu Fibonacciego, mniejsze instancje s ze sob
powizane. Przykadowo, zgodnie z tym, co przedstawiono w podrozdziale 1.2,
obliczenie pitego wyrazu cigu Fibonacciego wymaga obliczenia wyrazu trzeciego i czwartego. Jednak procesy okrelania czwartego i trzeciego wyrazu s ze
sob zwizane o tyle, e oba wymagaj znajomoci wyrazu drugiego. Ze wzgldu
na fakt, e algorytm typu dziel i zwyciaj wykonuje oba procesy niezalenie, drugi
wyraz cigu Fibonacciego jest obliczany wielokrotnie. W przypadku problemw,
112
w ktrych mniejsze realizacje s ze sob powizane, czsto okazuje si, e algorytm typu dziel i zwyciaj wielokrotnie rozwizuje te same realizacje i w efekcie
jest on bardzo niewydajny.
Programowanie dynamiczne (ang. dynamic programming), technika omawiana
w niniejszym rozdziale, opiera si na przyjciu odwrotnego podejcia. Programowanie dynamiczne jest podobne do podejcia typu dziel i zwyciaj o tyle, e
realizacja problemu zostaje podzielona na mniejsze realizacje. Jednak tym razem
najpierw s rozwizywane mae realizacje, a ich wyniki zostaj przechowane; pniej, kiedy zajdzie taka potrzeba, algorytm moe si do nich bezporednio odwoywa, zamiast oblicza je ponownie. Pojcie programowanie dynamiczne wywodzi si z teorii sterowania i w tym kontekcie programowanie oznacza uycie
tablicy (tabeli), w ramach ktrej jest konstruowane rozwizanie. Jak wspomniano
w rozdziale 1., wydajny algorytm (algorytm 1.7) obliczania n-tego wyrazu cigu
Fibonacciego jest przykadem programowania dynamicznego. Algorytm ten okrela
n-ty wyraz cigu Fibonacciego poprzez konstruowanie po kolei pierwszych n+1
wyrazw w tablicy f indeksowanej od 0 do n. W przypadku algorytmu programowania dynamicznego konstruujemy rozwizanie od dou tablicy (lub cigu tablic).
Programowanie dynamiczne stanowi wic podejcie wstpujce (ang. bottom-up).
Niekiedy, jak w przypadku algorytmu 1.7, po opracowaniu algorytmu wykorzystujcego tablic (lub cig tablic) istnieje moliwo ulepszenia go, tak aby zwolni
wiele niepotrzebnie przydzielonej przestrzeni pamiciowej.
Opracowanie algorytmu programowania dynamicznego polega na wykonaniu nastpujcych dziaa:
1. Okrelamy waciwo rekurencyjn, ktra pozwala znale rozwizanie
realizacji problemu.
2. Rozwizujemy realizacj problemu zgodnie z podejciem wstpujcym,
n
n!
=
dla 0 k n
k
k
n
k )!
!
(
Dla wartoci n i k, ktre nie s mae, nie moemy obliczy wspczynnika dwumianowego bezporednio z tej definicji, poniewa warto n! jest bardzo dua
nawet dla rednich wartoci n. W wiczeniach zostanie wykazane, e:
Rozdzia 3.
Programowanie dynamiczne
n 1 n 1
n
+
0<k <n
= k 1 k
k
1
k = 0 lub k = n
113
(3.1)
Moemy wyeliminowa konieczno obliczania wyraenia n! lub k!, wykorzystujc waciwo rekurencyjn. Sugeruje to zdefiniowanie poniszego algorytmu typu dziel i zwyciaj.
Algorytm 3.1.
Podobnie jak w przypadku algorytmu 1.6 (n-ty wyraz cigu Fibonacciego) algorytm ten jest bardzo niewydajny. W wiczeniach Czytelnik zostanie poproszony
o wykazanie, e algorytm oblicza
n
2 1
k
n
wyrazw w celu obliczenia wartoci . Problem polega na tym, e te same rek
alizacje s rozwizywane w kadym wywoaniu rekurencyjnym. Przykadowo
wywoania bin(n1, k1) oraz bin(n1, k) wi si z obliczeniem wartoci
bin(n2, k1) i realizacja ta jest rozwizywana niezalenie w kadym wywoaniu.
Jak wspomniano w podrozdziale 2.8, podejcie typu dziel i zwyciaj nigdy nie
jest wydajne, kiedy realizacja jest dzielona na dwie mniejsze realizacje, ktrych
rozmiar jest zbliony do rozmiaru oryginalnej realizacji.
Poniej opracujemy bardziej wydajny algorytm, wykorzystujcy programowanie
dynamiczne. W rwnaniu 3.1 okrelilimy ju waciwo rekurencyjn. Wykorzystamy j do skonstruowania rozwizania wykorzystujcego tablic B, gdzie
i
B[i][j] bdzie zawiera warto . Poniej opisano kolejne etapy tworzenia algo j
rytmu, opartego na programowaniu dynamicznym.
114
0< j<i
j = 0 lub j = i
Przykad 3.1.
4
Obliczamy warto B[4][2] = .
2
Obliczamy wiersz 0.:
Rozdzia 3.
Programowanie dynamiczne
115
B[1][0] = 1
B[1][1] = 1
B[2][0] = 1
B[2][1] = B[1][0]+B[1][1] = 1+1 = 2
B[2][2] = 1
B[3][0] = 1
B[3][1] = B[2][0]+B[2][1] = 1+2 = 3
B[3][2] = B[2][1]+B[2][2] = 2+1 = 3
B[4][0] = 1
B[4][1] = B[3][0]+B[3][1] = 1+3 = 4
B[4][2] = B[3][1]+B[3][2] = 3+3 = 6
116
Parametry n i k nie s rozmiarem danych wejciowych w przypadku tego algorytmu. Stanowi one dane wejciowe, natomiast rozmiarem danych wejciowych
jest liczba symboli uytych do ich zakodowania. Z podobn sytuacj mielimy do
czynienia w podrozdziale 1.3, gdzie omawialimy algorytm obliczajcy n-ty wyraz
cigu Fibonacciego. Jednake wci moemy zyska wgld w wydajno dziaania
algorytmu poprzez okrelenie iloci wykonywanych dziaa w funkcji zmiennych
n i k. Dla danego n i k obliczymy liczb przebiegw ptli HQT-j. W poniszej tabeli
3.1 zawarto liczby przebiegw dla kadej wartoci i.
Tabela 3.1. Liczba przebiegw ptli for-j w zalenoci od wartoci zmiennej i
i
k+1
Liczba przebiegw
k+1
k+1
k+1
1 + 2 + 3 + 4 + K + k + (k + 1) + (k + 1) + K + (k + 1)
14444
4244444
3
n k +1 razy
k (k + 1)
(2n k + 2)(k + 1)
+ (n k + 1)(k + 1) =
(nk )
2
2
Wykorzystujc programowanie dynamiczne zamiast podejcia typu dziel i zwyciaj udao nam si opracowa znacznie wydajniejszy algorytm. Jak wczeniej
wspomniano, programowanie dynamiczne jest podobne do metody dziel i zwyciaj
o tyle, e szukamy waciwoci rekurencyjnej, ktra dzieli realizacj problemu na
mniejsze realizacje. Rnica polega na tym, e w przypadku programowania dynamicznego wykorzystujemy waciwo rekurencyjn w celu iteracyjnego rozwizania realizacji w kolejnych krokach, rozpoczynajc od najmniejszej realizacji,
zamiast nieuzasadnionego naduywania rekurencji. W ten sposb kad mniejsz
realizacj rozwizujemy tylko raz. Programowanie dynamiczne jest dobrym rozwizaniem do wyprbowania w sytuacji, gdy metoda dziel i zwyciaj daje w wyniku bardzo mao wydajny algorytm.
Najprostszym sposobem przedstawienia algorytmu 3.2 jest utworzenie dwuwymiarowej tablicy B. Jednak kiedy obliczy si wartoci w danym wierszu, nie s
ju potrzebne wartoci obliczone w wierszu poprzednim. Std algorytm mona
zapisa przy uyciu tablicy jednowymiarowej, indeksowanej od 0 do k. Tego rodzaju modyfikacj zawarto w wiczeniach. Kolejnym ulepszeniem algorytmu jest
n n
.
wykorzystanie faktu, e =
k n k
Rozdzia 3.
Programowanie dynamiczne
117
Czsto spotykanym problemem jest znalezienie najkrtszych drg z kadego wierzchoka do wszystkich innych wierzchokw. Oczywicie, najkrtsza droga musi
by drog prost. Na rysunku 3.2 istniej trzy drogi proste z wierzchoka v1 do v3:
[v1, v2, v3], [v1, v4, v3] oraz [v1, v2, v4, v3]. Z uwagi na fakt, e:
118
dugo [v1 , v2 , v3 ] = 1 + 3 = 4
dugo [v1 , v4 , v3 ] = 1 + 2 = 3
dugo [v1 , v2 , v4 , v3 ] = 1 + 2 + 2 = 5
najkrtsz drog z v1 do v3 jest [v1, v4, v3]. Jak wczeniej wspomniano, jednym
z czsto wykorzystywanych zastosowa problemu najkrtszej drogi jest okrelanie
najkrtszych tras midzy miastami.
Problem najkrtszej drogi to problem optymalizacji (ang. optimization problem).
Moe istnie wicej ni jedno rozwizanie kandydujce do miana najlepszego dla
problemu optymalizacji. Kade rozwizanie kandydujce posiada zwizan ze sob
warto i rozwizaniem realizacji jest rozwizanie kandydujce o optymalnej wartoci. W zalenoci od problemu wartoci optymaln moe by minimum lub maksimum. W przypadku problemu najkrtszej drogi rozwizaniem kandydujcym (ang.
candidate solution) jest droga z jednego wierzchoka do drugiego, wartoci jest
dugo tej drogi, za wartoci optymaln jest minimum tych dugoci.
Ze wzgldu na fakt, e moe istnie wiele najkrtszych drg z jednego wierzchoka do drugiego, rozwizanie problemu polega na znalezieniu dowolnej z tych
najkrtszych drg. Oczywistym algorytmem rozwizania problemu byoby okrelenie dla kadego wierzchoka dugoci wszystkich drg z niego do innych wierzchokw i znalezienie minimum wrd tych dugoci. Jednak algorytm taki byby
wykonywany w czasie gorszym od wykadniczego. Na przykad zamy, e istnieje krawd z jednego wierzchoka do wszystkich innych wierzchokw. Ponadto podzbir wszystkich drg z tego wierzchoka do innych wierzchokw jest
zbiorem tych wszystkich drg, ktre rozpoczynaj si od pierwszego wierzchoka
i kocz na innych wierzchokach, przechodzc przez wszystkie pozostae. Z uwagi
na fakt, e drugim wierzchokiem w takiej drodze moe by dowolny spord n2
wierzchokw, trzecim wierzchokiem w takiej drodze moe by dowolny spord n3 wierzchokw itd., przedostatnim wierzchokiem w takiej drodze moe
by tylko jeden wierzchoek, cakowita liczba drg z jednego wierzchoka do innych wierzchokw, ktre przechodz przez wszystkie inne wierzchoki, wynosi:
(n 2)(n 3) K1 = (n 2)!
Wynik ten jest gorszy od wykadniczego. Z t sam sytuacj mamy do czynienia
w przypadku wielu problemw optymalizacji, to znaczy oczywisty algorytm rozpatrujcy wszystkie moliwoci jest wykadniczy lub gorszy. Naszym celem jest
znalezienie bardziej wydajnego algorytmu.
Wykorzystujc programowanie dynamiczne opracujemy algorytm wykonywany
w czasie szeciennym, stanowicy rozwizanie problemu najkrtszej drogi. Najpierw opracujemy algorytm okrelajcy tylko dugoci najkrtszych drg. Pniej
zmodyfikujemy go tak, aby dawa na wyjciu rwnie same najkrtsze drogi. Waony graf skierowany, zawierajcy n wierzchokw, reprezentujemy za pomoc
tablicy W, gdzie:
Rozdzia 3.
waga krawdzi,
W [i ][ j ] = ,
0,
Programowanie dynamiczne
119
O wierzchoku vj mwimy, e jest przylegy (ang. adjacent) do wierzchoka vi wwczas, gdy istnieje krawd z vi do vj. Tak tablic okrela si mianem reprezentacji
grafu w postaci macierzy przylegoci (ang. adjacency matrix). Graf z rysunku 3.2
przedstawiono w tej postaci na rysunku 3.3. Tablica D na rysunku 3.3 zawiera
dugoci najkrtszych drg w grafie. Przykadowo, D[3][5] wynosi 7, poniewa 7 jest
dugoci najkrtszej drogi z v3 do v5. Jeeli bdziemy w stanie znale sposb
obliczania wartoci w D na podstawie wartoci w W, otrzymamy algorytm rozwizujcy problem najkrtszej drogi. Osigniemy to, tworzc sekwencj n+1 tablic
D(k), gdzie 0 k n oraz
D(k)[i][j] = dugo najkrtszej drogi z vi do vj, zawierajcej jako wierzchoki
porednie tylko wierzchoki nalece do zbioru {v1,v2,...vk}.
Rysunek 3.3.
Tablica W
reprezentuje graf
z rysunku 3.2, za
tablica D zawiera
dugoci najkrtszych
drg. Opracowywany
algorytm rozwizania
problemu najkrtszej
drogi oblicza wartoci
w D na podstawie
wartoci w W
Obliczmy pewne przykadowe wartoci w tablicy D(k)[i][j] dla grafu z rysunku 3.2.
D(0)[2][5] = length [v2, v5] =
D(1)[2][5] = minimum (length [v2, v5], length [v2, v1, v5])
minimum (, 14) = 14
D(2)[2][5] = D(1)[2][5] = 14
D(3)[2][5] = D(2)[2][5] = 14
120
D(4)[2][5] = minimum (length [v2, v1, v5], length [v2, v4, v5])
length [v2, v1, v4, v5], length [v2, v3, v4, v5])
minimum (14, 5, 13, 10)+5
D(5)[2][5] = D(4)[2][5] = 5
D (0) = W
oraz D ( n ) = D
Std w celu okrelenia D na podstawie W musimy jedynie znale sposb otrzymywania wartoci D(n) na podstawie D(0). Poniej opisano poszczeglne etapy zmierzajcych do tego dziaa, w ktrych wykorzystamy programowanie dynamiczne.
1. Okrelamy waciwo rekurencyjn (proces), dziki ktrej moemy obliczy
(3.2)
D ( k ) [i ][ j ] = D ( k 1) [i ][ j ]
(3.3)
D ( 5 ) [1][3] = D ( 4 ) [1][3] = 3
poniewa kiedy uwzgldnimy wierzchoek v5, najkrtsza droga z v1 do v3 to wci
[v1, v4, v3].
Rozdzia 3.
Programowanie dynamiczne
121
D ( k ) [i ][ j ] = D ( k 1) [i ][k ] + D ( k 1) [k ][ j ]
(3.4)
Rysunek 3.4.
Najkrtsza droga,
zawierajca
wierzchoek vk
D ( k ) [i ][ j ] = minimum( D ( k 1) [i ][ j ], D ( k 1) [i ][k ] + D ( k 1) [k ][ j ])
14243 14444244443
przypadek 1.
przypadek 2.
Jeli mamy dany graf z rysunku 3.2, reprezentowany przez macierz przylegoci
W na rysunku 3.3, niektre obliczenia wykonuje si w nastpujcy sposb (naley
pamita, e D(0) = W):
122
Kiedy caa tablica D(1) zostanie wyliczona, obliczamy tablic D(2). Przykadowe
obliczenie ma posta:
D ( 2) [5][4] = minimum( D (1) [5][4], D (1) [5][2] + D (1) [2][4])
= minimum(4, 4 + 2) = 4
Graf jest reprezentowany przez tablic dwuwymiarow W, ktrej wiersze i kolumny s indeksowane od 1 do n, gdzie W[i][j] jest wag krawdzi, prowadzcej
od i-tego do j-tego wierzchoka.
Dane wyjciowe: dwuwymiarowa tablica D, ktrej wiersze i kolumny s indeksowane od 1 do n, gdzie D[i][j] jest dugoci najkrtszej drogi, prowadzcej od i-tego
do j-tego wierzchoka.
Rozdzia 3.
Programowanie dynamiczne
123
Moemy wykona nasze obliczenia przy uyciu tylko jednej tablicy D, poniewa
wartoci w k-tym wierszu oraz k-tej kolumnie nie s wymieniane w czasie k-tego
przebiegu ptli. Oznacza to, e w k-tym przebiegu algorytm dokonuje przypisania:
D[i ][k ] = minimum( D[i ][k ], D[i ][k ] + D[k ][k ])
co jest oczywicie rwne D[k][j]. W czasie k-tego przebiegu element D[i][j] jest
obliczany tylko na podstawie wasnej wartoci oraz wartoci w k-tym wierszu i k-tej
kolumnie. Wartoci te zostay przypisane w (k1). przebiegu, wic s poszukiwanymi przez nas wartociami. Jak wspomniano wczeniej, czasem po opracowaniu algorytmu programowania dynamicznego istnieje moliwo jego poprawienia, tak aby by bardziej wydajny pod wzgldem zajtoci pamici.
Poniej zostanie przedstawiona analiza algorytmu Floyda.
Analiza
algorytmu
3.3.
Mamy do czynienia z ptl w ptli w ptli, z ktrych kada jest zwizana z wykonaniem n przebiegw, tak wic:
T (n) = n n n = n 3 (n 3 ).
Ponisza modyfikacja algorytmu 3.3 pozwala na obliczenie najkrtszej drogi.
Algorytm 3.4.
najkrtsze drogi.
Dodatkowe dane wyjciowe: tablica P, ktrej wiersze i kolumny s indeksowane
od 1 do n, gdzie
124
Na rysunku 3.5 przedstawiono tablic P, ktra jest tworzona w przypadku zastosowania algorytmu dla grafu z rysunku 3.2.
Rysunek 3.5.
Tablica P, utworzona
w przypadku zastosowania
algorytmu 3.4 dla grafu
z rysunku 3.2
Rozdzia 3.
Programowanie dynamiczne
125
Etapy 2. oraz 3. s zwykle wykonywane mniej wicej w tym samym miejscu algorytmu. Ze wzgldu na fakt, e algorytm 3.2 nie jest problemem optymalizacji, nie
wystpuje w nim trzeci etap.
Cho moe si wydawa, e problem optymalizacji moe zawsze zosta rozwizany
przy uyciu programowania dynamicznego, nie jest to prawd. Aby tak byo, w przypadku danego problemu musi mie zastosowanie zasada optymalnoci. Zasad t
mona wyrazi nastpujco:
126
Definicja
O zasadzie optymalnoci (ang. principle of optimality) mwi si, e ma zastosowanie w problemie wwczas, gdy rozwizanie optymalne realizacji problemu
zawsze zawiera rozwizania optymalne dla wszystkich podrealizacji.
Rozwamy problem najduszej drogi, polegajcy na znalezieniu najduszych prostych drg wiodcych od kadego wierzchoka do wszystkich innych wierzchokw. Problem ograniczamy do prostych drg, poniewa w przypadku cykli zawsze
moemy utworzy dowolnie dug drog poprzez powtarzalne przechodzenie przez
cykl. Na rysunku 3.6 optymalna (najdusza) prosta droga z v1 do v4 to [v1, v3, v2, v4].
Jednak poddroga [v1, v3] nie jest optymaln (najdusz) drog z v1 do v3, poniewa
dugo[v1 , v3 ] = 1 oraz dugo[v1 , v2 , v3 ] = 4
Rozdzia 3.
Programowanie dynamiczne
127
Rysunek 3.6.
Waony graf
skierowany z cyklem
6 7 8 9
Macierz wynikowa ma rozmiary 24. Jeeli uyjemy standardowej metody mnoenia macierzy (opartej na definicji mnoenia macierzy), obliczenie kadego
elementu iloczynu wymaga bdzie wykonania trzech podstawowych operacji
mnoenia. Przykadowo, pierwszy element w pierwszej kolumnie to:
11
4
7 +4
22
24+4
34
36
4
3 mnoenia
Oglnie rzecz biorc, w celu pomnoenia macierzy o wymiarach ij przez macierz o wymiarach jk przy uyciu metody standardowej musimy wykona
i j k elementarnych operacji mnoenia
128
D
20 2
2 30
30 12
12 8
Wymiary kadej macierzy zapisano pod nimi. Mnoenie macierzy jest operacj
czn, co oznacza, e kolejno, w jakiej wykonujemy mnoenie, nie ma znaczenia. Przykadowo, operacje A(B(CD)) oraz (AB)(CD) daj ten sam wynik. Istnieje pi rnych kolejnoci, w jakich moemy pomnoy cztery macierze i ktre
dadz zwykle rn liczb elementarnych operacji mnoenia. W przypadku powyszych macierzy mamy nastpujce liczby elementarnych operacji mnoenia
dla rnych kolejnoci dziaa:
A(B(CD)) 30128+ 230 8+20 28 = 3680
(AB)(CD) 20230+3012 8+20308 = 8880
A((BC)D) 23012+ 212 8+20 28 = 1232
((AB)C)D 20230+203012+20128 = 10320
(A(BC))D 23012+20 2 12+20128 = 3120
Trzecia kolejno jest optymalna w przypadku mnoenia czterech macierzy.
Naszym celem jest opracowanie algorytmu, ktry bdzie okrela optymaln kolejno mnoenia n macierzy. Kolejno ta zaley tylko od rozmiarw macierzy.
Std oprcz n rozmiary te stanowi jedyne dane wejciowe dla algorytmu. Algorytm wykorzystujcy metod siow polegaby na rozwaeniu wszystkich moliwych kolejnoci i wybraniu minimum tak jak postpilimy powyej. Wykaemy, e taki algorytm jest wykonywany co najmniej w czasie wykadniczym.
Niech tn bdzie liczb rnych kolejnoci, w jakich moemy pomnoy n macierzy: A1, A2, , An. Jednym z podzbiorw wszystkich kolejnoci jest zbir kolejnoci, dla ktrych macierz A1 jest ostatni mnoon macierz. Jak pokazano poniej, liczba rnych kolejnoci w tym podzbiorze wynosi tn1, poniewa jest to
liczba kolejnoci, w jakich moemy pomnoy macierze od A2 do An:
A1 ( A2 A3 K An )
14243
t n 1 rnych
kolejnoci
Drugi podzbir wszystkich kolejnoci jest zbiorem kolejnoci, w przypadku ktrych macierz An jest ostatni mnoon macierz. Oczywicie, liczba rnych kolejnoci w tym podzbiorze rwnie wynosi tn1. Std:
t n t n1 + t n1 = 2t n1
Rozdzia 3.
Programowanie dynamiczne
129
to
( A2 A3 ) A4
A1
A2
5 2
23
d 0 d1
d1 d 2
A3
3 4
d2 d3
A4
46
d3 d4
A5
67
d4 d5
A6
78
d5 d6
W celu pomnoenia macierzy A4, A5 i A6 moemy okreli ponisze dwie kolejnoci oraz liczby elementarnych operacji mnoenia:
130
( A4 A5 ) A6
Std
M [4][6] = minimum(392, 528) = 392
Optymalna kolejno mnoenia szeciu macierzy musi mie jeden z nastpujcych rozkadw:
1. A1(A2A3A4A5A6)
2. (A1A2)(A3A4A5A6)
3. (A1A2A3)(A4A5A6)
4. (A1A2A3A4)(A5A6)
5. (A1A2A3A4A5)A6
gdzie w kadym nawiasie iloczyn jest otrzymywany zgodnie z optymaln kolejnoci dla liczby macierzy, znajdujcych si w tym nawiasie. Spord rozkadw
ten, ktry daje minimaln liczb operacji mnoenia, musi by optymalny. Liczba
operacji mnoenia dla k-tego rozkadu jest minimaln liczb potrzebn do otrzymania kadego czynnika, powikszon o liczb potrzebn do pomnoenia dwch
czynnikw. Oznacza to, e wynosi ona
M [1][k ] + M [k + 1][6] + d 0 d k d 6
Okrelilimy, e
M [1][6] = minimum
1424
3 ( M [1][k ] + M [k + 1][6] + d 0 d k d 6 )
1 k 5
M [i][ j ] = minimum
1424
3 ( M [i ][k ] + M [k + 1][ j ] + d i 1d k d j ), jeeli i < j
i k j 1
(3.5)
M [i ][i ] = 0
Algorytm typu dziel i zwyciaj oparty na tej waciwoci jest wykonywany w czasie
wykadniczym. Poniej opracujemy wydajniejszy algorytm, wykorzystujc programowanie dynamiczne w celu obliczenia wartoci M[i][j] w kolejnych etapach.
Rozdzia 3.
Programowanie dynamiczne
131
Uywana jest siatka podobna do trjkta Pascala (patrz podrozdzia 3.1). Obliczenia, ktre s nieco bardziej skomplikowane, ni miao to miejsce w podrozdziale 3.1, s oparte na poniej opisanej waciwoci z rwnania 3.5. Element
M[i][j] jest obliczany na podstawie wszystkich wpisw ze swojego wiersza, znajdujcych si po jego lewej stronie, oraz wpisw ze swojej kolumny, znajdujcych
si poniej niego. Wykorzystujc t waciwo mona obliczy wartoci elementw w M w poniej opisany sposb. Najpierw ustawiamy warto tych elementw
na gwnej przektnej na 0. Nastpnie obliczamy wszystkie elementy na przektnej powyej (nazywamy j przektn 1). Nastpnie obliczamy wszystkie wartoci
na przektnej 2 itd. Kontynuujemy te dziaania do momentu, a obliczymy jedyn warto na przektnej 5, ktra jest nasz odpowiedzi kocow, M[1][6]. Procedur t zilustrowano na rysunku 3.8 dla macierzy z przykadu 3.5. Poniszy
przykad zawiera odpowiednie obliczenia.
Rysunek 3.8.
Tablica M opracowana
w przykadzie 3.5.
Element M[1][4],
ktry oznaczono kkiem,
jest obliczany
na podstawie par
wskazanych wartoci
Przykad 3.6.
Obliczamy przektn 1:
M [1][2] = minimum
1424
3 ( M [1][k ] + M [k + 1][2] + d 0 d k d 2 )
1 k 1
= M [1][1] + M [2][2] + d 0 d 1 d 2
= 0 + 0 + 5 2 3 = 30
132
Przedstawiony poniej algorytm stanowi implementacj tej metody. Wymiary n macierzy, a konkretnie wartoci od d0 do dn, s jedynymi danymi wejciowymi algorytmu. Same macierze nie stanowi danych wejciowych, poniewa wartoci w macierzach nie maj znaczenia dla istoty problemu. Tablica P utworzona przez algorytm
moe zosta wykorzystana do wydrukowania optymalnej kolejnoci. Zostanie to
omwione po przeanalizowaniu algorytmu 3.6.
Rozdzia 3.
Algorytm 3.6.
Programowanie dynamiczne
133
wymaganych w celu pomnoenia n macierzy; dwuwymiarowa tablica P, na podstawie ktrej mona okreli optymaln kolejno. P posiada wiersze indeksowane od
1 do n1 oraz kolumny indeksowane od 1 do n. P[i][j] jest punktem, w ktrym macierze od i do j zostaj rozdzielone w kolejnoci optymalnej dla mnoenia macierzy.
!"#$
%
&
&
$'()
#"***
+
+
j 1 i + 1 = i + diagonal 1 i + 1 = diagonal
Dla danej wartoci diagonal liczba przebiegw ptli HQT-i wynosi ndiagonal. Ze
wzgldu na fakt, e diagonal moe przyjmowa wartoci od 1 do n1, cakowita
liczba powtrze operacji podstawowej wynosi
134
n 1
diagonal =1
n(n 1)(n + 1)
( n 3 )
6
Poniej pokaemy, w jaki sposb mona otrzyma optymaln kolejno na podstawie tablicy P. Wartoci zawarte w tej tablicy w momencie, gdy algorytm jest
stosowany dla wymiarw z przykadu 3.5, przedstawiono na rysunku 3.9. Fakt,
e na przykad P[2][5] = 4 oznacza, e optymalna kolejno dla mnoenia macierzy
od A2 do A5 posiada rozkad:
( A2 A3 A4 ) A5
gdzie macierze znajdujce si w nawiasie s mnoone w kolejnoci optymalnej.
Oznacza to, e P[2][5], czyli 4, jest punktem, w ktrym macierze powinny zosta
rozdzielone w celu otrzymania czynnikw. Moemy okreli optymaln kolejno,
odwiedzajc najpierw element P[1][n] w celu okrelenia rozkadu na najwyszym
poziomie. Ze wzgldu na fakt, e n = 6 oraz P[1][6] = 1, rozkad na najwyszym
poziomie dla kolejnoci optymalnej ma posta:
A1 ( A2 A3 A4 A5 A6 )
Rysunek 3.9.
Tablica P, utworzona
w momencie,
gdy algorytm 3.6
zosta zastosowany
wzgldem wymiarw
z przykadu 3.5
( A2 A3 A4 A5 ) A6
Wiemy, e rozkad w kolejnoci optymalnej ma posta:
A1 (( A2 A3 A4 A5 ) A6 )
gdzie rozkad dla mnoenia macierzy od A2 do A5 wci naley okreli. Sprawdzamy warto elementu P[2][5] i kontynuujemy w ten sposb dalsze dziaania do
momentu, w ktrym zostan okrelone wszystkie rozkady. Odpowied ma posta:
A1 ((( A2 A3 ) A4 ) A5 ) A6 )
Rozdzia 3.
Programowanie dynamiczne
135
rytm 3.6. P[i][j] jest punktem, w ktrym macierze od i do j s rozdzielane w kolejnoci optymalnej dla mnoenia tych macierzy.
Dane wyjciowe: optymalna kolejno mnoenia macierzy.
,,
,,
,,
+
+
Kiedy wymiary s takie same, jak w przykadzie 3.5, algorytm wywietla nastpujce informacje:
(A1((((A2A3)A4)A5)A6))
Cae wyraenie ujto w nawiasy, poniewa algorytm wstawia je wok kadego
skadnika zoonego. W wiczeniach zostanie wykazane, e dla algorytmu 3.7
T ( n ) ( n )
Opracowany algorytm (n3) dla acuchowego mnoenia macierzy pochodzi z pracy
Godbolea (1973). Yao (1982) opracowa metody przyspieszajce pewne rozwizania programowania dynamicznego. Wykorzystujc te metody mona utworzy
algorytm (n2) dla acuchowego mnoenia macierzy. Hu oraz Shing (1982, 1984)
opisuj algorytm (n lg n) dla acuchowego mnoenia macierzy.
136
Rozdzia 3.
Programowanie dynamiczne
137
138
Algorytm 3.8.
keyin.
Dane wyjciowe: wskanik p do wierzchoka zawierajcego klucz.
/
01
2
34
34
34(5'1$!'%''*
34(5'%$!'%''*
depth(key) + 1
gdzie depth(key) jest gbokoci wierzchoka zawierajcego klucz. Przykadowo,
ze wzgldu na fakt, e gboko klucza zawierajcego warto Urszula wynosi
2 w lewym poddrzewie na rysunku 3.10, czas wyszukiwania klucza Urszula wynosi
depth(Urszula) + 1 = 2 + 1 = 3
Niech Key1, Key2, , Keyn bd n uporzdkowanymi kluczami oraz niech pi bdzie
prawdopodobiestwem tego, e Keyi jest kluczem wyszukiwania. Jeeli ci oznacza liczb porwna koniecznych do znalezienia klucza Keyi w danym drzewie,
to redni czas wyszukiwania dla tego drzewa wynosi
n
c p
i =1
Rozdzia 3.
Przykad 3.7.
Programowanie dynamiczne
139
p 2 = 0,2 oraz
p 3 = 0,1
140
swojego rodzica, co oznacza, e istniej dwie moliwoci na kadym z tych poziomw. To oznacza, e liczba rnych drzew wyszukiwania binarnego o gbokoci n1 wynosi 2n1.
Wykorzystamy programowanie dynamiczne do opracowania bardziej wydajnego
algorytmu. Zamy, e klucze od Keyi do Keyj s uoone w drzewie, ktre minimalizuje
j
c
m =i
pm
Zamy, e mamy trzy klucze oraz prawdopodobiestwa okrelone w przykadzie 3.7, to znaczy:
p1 = 0,7
p 2 = 0,2 oraz
p 3 = 0,1
W celu okrelenia A[2][3] musimy rozway dwa drzewa z rysunku 3.12. Dla
tych dwch drzew otrzymujemy:
1. 1(p2)+2(p3) = 1(0,2)+2(0,1) = 0,4
2. 2(p2)+1(p3) = 2(0,2)+1(0,1) = 0,5
Rysunek 3.12.
Drzewa wyszukiwania
binarnego utworzone
z kluczy Key2 oraz Key3
Rozdzia 3.
Programowanie dynamiczne
141
musi by optymalne dla kluczy w tym poddrzewie. Zatem zachowana zostaje zasada optymalnoci.
Niech drzewo 1 bdzie drzewem optymalnym przy uwzgldnieniu ograniczenia
mwicego o tym, e klucz Key1 znajduje si w korzeniu, drzewo 2 niech bdzie
drzewem optymalnym przy uwzgldnieniu ograniczenia mwicego o tym, e klucz
Key2 znajduje si w korzeniu, , niech drzewo n bdzie drzewem optymalnym
przy uwzgldnieniu ograniczenia mwicego o tym, e klucz Keyn znajduje si
w korzeniu. Dla 1 k n poddrzewa drzewa k musz by optymalne, a wic
rednie czasy wyszukiwania w tych poddrzewach s zgodne z tym, co przedstawiono na rysunku 3.13. Rysunek ten pokazuje rwnie, e dla kadego m k
wymagana jest dokadnie o jeden wiksza liczba porwna w celu zlokalizowania
klucza Keym w drzewie k ni w celu zlokalizowania tego klucza w poddrzewie,
w ktrym si on znajduje (dodatkowe porwnanie jest zwizane z korzeniem). Owo
dodatkowe porwnanie dodaje 1pm do redniego czasu wyszukiwania klucza Keym
w drzewie k. Okrelilimy, e redni czas wyszukiwania dla drzewa k wynosi:
A[1][k 1] +
14243
redni czas
w lewym poddrzewie
p + K pk 1
11 4243
p
{k
redni czas
wyszukania korzenia
A[k + 1][n] +
14243
redni czas
w prawym poddrzewie
p +1 + K pn
1k 42
43
co jest rwnowane:
n
Rysunek 3.13.
Optymalne drzewo
wyszukiwania
binarnego przy
zaoeniu, e klucz
Keyk jest korzeniem
Ze wzgldu na fakt, e jedno z k drzew musi by optymalne, redni czas wyszukiwania optymalnego drzewa okrela zaleno:
n
A[1][n] = minimum
1424
3 ( A[1][k 1] + A[k + 1][n]) + p m
1 k n
m =1
gdzie A[1][0] i A[n+1][n] s z definicji rwne 0. Chocia suma prawdopodobiestw w ostatnim wyraeniu wynosi bez wtpienia 1, zapisalimy j jako sum,
poniewa teraz chcemy uoglni rezultat. W powyszej dyskusji nie ma nic, co
wymagaoby, aby klucze miay wartoci od Key1 do Keyn. Oznacza to, e dyskusja
odnosi si oglnie do kluczy od Keyi do Keyj, gdzie i < j. W ten sposb otrzymujemy:
142
j
A[1][ j ] = minimum
1424
3 ( A[i ][k 1] + A[k + 1][ j ]) + m=i pm i < j
i k j
A[i ][i ] = pi
(3.6)
Rozdzia 3.
Programowanie dynamiczne
143
!"
#$%&'(
!!$)*
j
p
m =i
')+,&%-!!--
Analiza
algorytmu
3.9.
p
m =i
Sterowanie tym algorytmem jest niemal identyczne, jak w przypadku algorytmu 3.6.
Jedyna rnica polega na tym, e dla danych wartoci diagonal oraz i operacja
podstawowa jest wykonywana diagonal+1 razy. Analiza, podobna jak w przypadku algorytmu 3.6, pozwala okreli, e:
T ( n) =
n(n 1)(n + 4)
( n 3 )
6
kluczy oraz tablica R, utworzona przez algorytm 3.9. R[i][j] jest indeksem klucza
w korzeniu drzewa optymalnego, zawierajcego klucze od i-tego do j-tego.
Dane wyjciowe: wskanik tree do optymalnego drzewa wyszukiwania binarnego,
zawierajcego n kluczy.
144
Izabela
Rudolf
Waldemar
Key[1]
Key[2]
Key[3]
Key[4]
oraz
p1 =
3
8
p2 =
3
8
p3 =
1
8
p4 =
1
8
Rozdzia 3.
Programowanie dynamiczne
145
Rysunek 3.14.
Tablice A oraz R utworzone
przez algorytm 3.9
w przypadku uycia go
wobec realizacji problemu
z przykadu 3.9
Rysunek 3.15.
Drzewo utworzone
w przypadku zastosowania
algorytmw 3.9 oraz 3.10
wobec realizacji problemu
z przykadu 3.9
146
tour) w waonym grafie skierowanym jest tak drog, ktra posiada najmniejsz
dugo. Problem komiwojaera polega na znalezieniu optymalnej trasy w waonym grafie skierowanym, kiedy istnieje przynajmniej jedna trasa. Ze wzgldu na
fakt, e wierzchoek pocztkowy nie ma wpywu na dugo optymalnej trasy,
jako wierzchoek pocztkowy bdziemy traktowa wierzchoek v1. Poniej przedstawiono trzy trasy i ich dugoci dla grafu z rysunku 3.16:
length[v1 , v 2 , v3 , v 4 , v1 ] = 22
length[v1 , v3 , v 2 , v 4 , v1 ] = 26
length[v1 , v3 , v 4 , v 2 , v1 ] = 21
Rysunek 3.16.
Optymalna trasa
ma posta:
[v1, v3, v4, v2, v1]
Rozdzia 3.
Programowanie dynamiczne
147
Rysunek 3.17.
Macierz przylegoci W,
reprezentujca graf
z rysunku 3.16
Przykad 3.10.
Naley zauway, e zapis {v1, v2, v3, v4} wykorzystuje nawiasy klamrowe w celu
reprezentowania zbioru, gdy zapis [v1, v2, v3, v4] wykorzystuje nawiasy kwadratowe w celu reprezentowania drogi. Jeeli A = {v3}, to
D[v 2 ][ A] = length[v 2 , v 3 , v1 ]
=
Ze wzgldu na fakt, e zbir V{v1, vj} zawiera wszystkie wierzchoki oprcz v1 oraz
vj i ma tu zastosowanie zasada optymalnoci, moemy stwierdzi, co nastpuje:
Dlugo trasy minimalnej = minimum
1424
3 (W [1][ j ] + D[v j ][V {v1 , v j }])
2 j n
(3.7)
Moemy utworzy algorytm programowania dynamicznego dla problemu komiwojaera, korzystajc z zalenoci 3.7. Jednak najpierw pokaemy, jak algorytm
ten dziaa.
Przykad 3.11.
148
Podobnie:
D[v 4 ][{v 2 }] = 3 + 1 = 4
D[v 2 ][{v 3 }] = 6 + =
D[v 4 ][{v 3 }] = + =
D[v 2 ][{v 4 }] = 4 + 6 = 10
D[v 3 ][{v 4 }] = 8 + 6 = 14
Podobnie:
D[v 3 ][{v 2 , v 4 }] = minimum(7 + 10, 8 + 4) = 12
D[v 2 ][{v 3 , v 4 }] = minimum(6 + 14, 4 + ) = 20
Rozdzia 3.
Programowanie dynamiczne
149
Dane wyjciowe: zmienna minlength, ktrej wartoci jest dugo optymalnej trasy
oraz dwuwymiarowa tablica P, na podstawie ktrej mona skonstruowa optymaln tras. Wiersze tablicy P s indeksowane od 1 do n, za jej kolumny s indeksowane przez wszystkie podzbiory zbioru V{v1}. Element P[i][A] jest indeksem pierwszego wierzchoka, znajdujcego si po vi na najkrtszej drodze z vi do v1,
ktra przechodzi przez wszystkie wierzchoki nalece do A dokadnie raz.
! !"#$ $%
&
! '
!( (!) '
!
*+!!" ,(,,
!
*+!!" ,(,,
Dla kadego n 1
n
k =1
k k = n2
n 1
n
n 1
k = n
k
k 1
Std:
n
k =1
n 1
k k = n k 1
n 1
= n
k =0 k
k =1
n 1
= n 2 n1
150
( )
zaleno:
n2
n 1
T (n) = (n 1 k )k
k =1
k
(3.8)
Nietrudno wykaza, e:
n 1
n 2
= (n 1)
(n 1 k )
k
k
Podstawiajc to rwnanie do rwnania 3.8 otrzymujemy:
n2
n 2
T (n) = (n 1) k
k
k =1
M (n) = 2 n2 n 1 = n2 n (n2 n )
Rozdzia 3.
Programowanie dynamiczne
151
152
[v1 , v 3 , v 4 , v 2 , v1 ]
Jak dotd nikomu nie udao si opracowa takiego algorytmu dla problemu komiwojaera, ktrego zoono w najgorszym przypadku byaby lepsza ni wykadnicza. Jednake nikt rwnie nie udowodni, e taki algorytm nie istnieje. Problem ten naley do szerokiej klasy blisko ze sob zwizanych problemw, ktre
dziel t waciwo. S one tematem rozdziau 9.
wiczenia
Podrozdzia 3.1
1. Wyprowad rwnanie 3.1, podane w tym podrozdziale.
2. Uyj dowodu indukcyjnego wzgldem n w celu wykazania, e algorytm typu
Podrozdzia 3.2
5. Uyj algorytmu Floyda dla problemu najkrtszych drg 2 (algorytm 3.4)
Rozdzia 3.
Programowanie dynamiczne
153
Podrozdzia 3.3
11. Znajd problem optymalizacji, w przypadku ktrego zasada optymalnoci
Podrozdzia 3.4
12. Znajd optymaln kolejno oraz koszt obliczenia iloczynu macierzy
A1A2A3A4A5, gdzie
A1 ma rozmiar (10 4)
A2 ma rozmiar (4 5)
A3 ma rozmiar (5 20)
A4 ma rozmiar (20 2)
A5 ma rozmiar (2 50)
13. Zaimplementuj algorytm minimalnej liczby operacji mnoenia (algorytm 3.6)
diagonal =1
n(n 1)(n + 1)
6
154
czasowa.
18. Zapisz wydajny algorytm, ktry znajduje optymaln kolejno mnoenia
Podrozdzia 3.5
19. Ile rnych drzewa wyszukiwania binarnego mona skonstruowa
p
m =i
notacji rzdu.
24. Uoglnij algorytm wyszukiwania optymalnego drzewa binarnego
Podrozdzia 3.6
26. Znajd optymaln tras dla waonego grafu skierowanego, reprezentowanego
Rozdzia 3.
Programowanie dynamiczne
155
0 8 13 18 20
3 0 7 8 10
W = 4 11 0 10 7
6 6 7 0 11
10 6 2 1 0
27. Zapisz bardziej szczegow wersj algorytmu programowania
wiczenia dodatkowe
29. Podobnie jak w przypadku algorytmw obliczajcych n-ty wyraz cigu
1 2n
n + 1 n
32. Czy mona opracowa algorytm optymalnego drzewa wyszukiwania