Вы находитесь на странице: 1из 21

Matematyka Dyskretna

Andrzej Szepietowski
25 marca 2004 roku

Rozdzia 1

Rekurencja
1.1 Wieze Hanoi
Rekurencja jest to zdolnosc podprogramu (procedury lub funkcji) do wywoywania samego siebie. Zacznijmy od przykadu wiez Hanoi. Przypusc my, z e mamy trzy wieze lub
trzy paliki: A, B i C. Na pierwszym paliku, A, znajduja sie trzy kra
zki rznej wielkosci,
nanizane w porzadku

od najwiekszego na dole do najmniejszego na grze. Paliki B i C


sa na poczatku
puste. Nalezy przeniesc wszystkie kra
zki z palika A na B, posugujac
sie
w razie potrzeby palikiem C, wedug nastepujacych

regu:
mozna przenosic po jednym kra
zku z jednego palika na inny,
nie mozna umieszczac wiekszego kra
zka na mniejszym.
Rozwiazaniem

tej amigwki dla trzech kra


zkw jest nastepujacy
ciag
siedmiu przeoz en:
A B,

A C,

B C,

A B,

C A,

C B,

A B,

gdzie zapis X Y oznacza przeniesienie szczytowego kra


zka z palika X na palik Y .
Chodzi nam teraz o algorytm, ktry dla dowolnej liczby N kra
zkw wypisze ciag

operacji potrzebnych do przeozenia N kra


zkw z palika A na palik B.
Algorytm przekadania kra
zkw
jezeli N = 1, to przekadamy ten jeden kra
zek

A B,

jezeli N > 1, to:

 przekadamy N 1 kra
zkw z A na pomocniczy palik C (posugujac
sie w
razie potrzeby palikiem B),
 przekadamy N -ty kra
zek z A na B,

 przekadamy N 1 kra
zkw z C na A (za pomoca palika B).
3

Rozdzia 1. Rekurencja

Nietrudno zauwazyc, z e jezeli proces przekadania N 1 kra


zkw jest prawidowy, to
cay proces tez jest prawidowy, poniewaz obecnosc najwiekszego kra
zka na dole palika
nie przeszkadza w przekadaniu N 1 mniejszych kra
zkw.
Powyzszy algorytm opiszmy teraz za pomoca rekurencyjnej procedury przenies, ktra odwouje sie sama do siebie i wypisuje ciag
instrukcji przeniesienia N kra
zkw z palika
X na palik Y .
procedura przenies(N kra
zkw z X na Y , za pomoca Z):
jezeli N = 1, to wypisz X Y ,
jezeli N > 1, to

 przenies(N 1 kra
zkw z X na Z, za pomoca Y ),

 wypisz X Y ,

 przenies(N 1 kra
zkw z Z na Y , za pomoca X).

1.2 Drzewo rekursji


Rysunek 1.1: Drzewo rekursji dla przekadania trzech kra
zkw w wiezach Hanoi
3
AB

2
AC

1
AB

2
CB

1
BC

1
CA

1
AB

Dziaanie procedury rekurencyjnej dobrze ilustruje tak zwane drzewo rekursji. Rysunek 1.1 8.1 przedstawia drzewo rekursji dla algorytmu przekadania trzech kra
zkw na
wiezach Hanoi. Wierzchoki odpowiadaja wywoaniom procedury. Skrt
N
XY
oznacza wywoanie procedury przenies(N kra
zkw z X na Y , za pomoca trzeciego palika ). W korzeniu wywoujemy procedure do przeozenia 3 kra
zkw z palika A na B. To
wywoanie samo dwa razy wywouje przenies: raz dla przeniesiena 2 kra
zkw z A na C i
drugi raz dla przeniesienia 2 kra
zkw z C na B, Tym wywoaniom odpowiadaja synowie

1.3. Algorytm Euklidesa, wersja rekurencyjna

korzenia drzewa i tak dalej. Wykonanie procedury rekurencyjnej nasladuje przeszukanie


drzewa rekursji metoda w gab.
Uzywamy do tego celu stosu, na ktry wkadane sa wywoania procedury. W kazdym momencie na stosie znajduja sie informacje o otwartych i
ciagle
nie zamknietych wywoaniach. Jeez eli dane wywoanie sie wykona i zamknie, to
odpowiedni element jest zdejmowany ze stosu. Stos taki nazwywany jest stosem rekursji.
Ponizej wypisano zawartosc stosu po kolejnych wywoaniach i zamknieciach procedury
przenies.
[Przenies(3,A B)]
[Przenies(3,A B)] [Przenies(2,A C)]
[Przenies(3,A B)] [Przenies(2,A C)] [Przenies(1,A B)]
[Przenies(3,A B)] [Przenies(2,A C)]
[Przenies(3,A B)] [Przenies(2,A C)] [Przenies(1,B C)]
[Przenies(3,A B)] [Przenies(2,A C)]
[Przenies(3,A B)]
[Przenies(3,A B)] [Przenies(2,C B)]
[Przenies(3,A B)] [Przenies(2,C B)] [Przenies(1,C A)]
[Przenies(3,A B)] [Przenies(2,C B)]
[Przenies(3,A B)] [Przenies(2,C B)] [Przenies(1,A B)]
[Przenies(3,A B)] [Przenies(2,C B)]
[Przenies(3,A B)]

1.3 Algorytm Euklidesa, wersja rekurencyjna


Innym przykadem algorytmu rekurencyjnego moze byc rekurencyjna wersja algorytmu
Euklidesa, ktry oblicza najwiekszy wsplny dzielnik dwch dodatnich liczb naturalnych
a i b: Oto uproszczona wersja definicji funkcji N W D
if ab=0 then NWD(a,b):=a+b
else if ab then NWD(a,b):=NWD(a mod b,b)
else NWD(a,b):=NWD(a,b mod a)

Jak widac definicja funkcji odwouje sie sama do siebie. Rysunek 1.2 przedstawia
drzewo rekursji dla obliczenia najwiekszego wsplnego dzielnika liczb 5 i 3. W tym przypadku drzewo jest zredukowane do jednej sciezki. Ponizej przedstawiono zawartosci stosu
rekursji po kazdym wywoaniu i zamknieciu funkcji.
[N W D(5, 3)]
[N W D(5, 3)] [N W D(2, 3)]
[N W D(5, 3)] [N W D(2, 3)] [N W D(2, 1)]
[N W D(5, 3)] [N W D(2, 3)] [N W D(2, 1)] [N W D(0, 1)]
[N W D(5, 3)] [N W D(2, 3)] [N W D(2, 1)]
[N W D(5, 3)] [N W D(2, 3)]
[N W D(5, 3)]

Rozdzia 1. Rekurencja

Rysunek 1.2: Drzewo reursji dla funkcji Euklidesa


N W D(5, 3)

N W D(2, 3)

N W D(2, 1)

N W D(0, 1)

1.4 Rekurencyjne algorytmy przeszukiwania drzew


Istnieje prosty i ciekawy sposb uzyskiwania postaci postfixowej wyrazenia arytmetycznego z drzewa tego wyrazenia. Aby uzyskac postac postfixowa wyrazenia, nalezy przeszukac drzewo tego wyrazenia w pewien okreslony sposb, zwany przeszukiwaniem postorder.
Przeszukiwanie postorder. Aby przeszukac (pod)drzewo majace
swj korzen w wierzchoku x:
przeszukujemy jego lewe poddrzewo (z korzeniem w x0),
przeszukujemy jego prawe poddrzewo (z korzeniem w x1),
odwiedzamy wierzchoek x (korzen drzewa).
Algorytm ten mozemy krtko przedstawic w schemacie:
lewe poddrzewo prawe poddrzewo korzen .
Przykad 1.1 Jezeli przeszukamy drzewo wyrazenia arytmetycznego z rysunku 1.3 i wypiszemy po kolei etykiety odwiedzanych wierzchokw, to otrzymamy ciag:

2a3d/ +
ktry jest postacia postfixowa wyrazenia 2(a + 3/d).
Istnieja jeszcze dwie inne pokrewne metody przeszukiwania drzew binarnych: inorder
i preorder:

1.4. Rekurencyjne algorytmy przeszukiwania drzew

Rysunek 1.3: Drzewo wyrazenia 2(a + 3/d)

Przeszukiwanie inorder. Aby przeszukac (pod)drzewo majace


swj korzen w wierzchoku x:
przeszukujemy jego lewe poddrzewo (z korzeniem w x0),
odwiedzamy wierzchoek x (korzen drzewa),
przeszukujemy jego prawe poddrzewo (z korzeniem w x1).
Przeszukiwanie preorder. Aby przeszukac (pod)drzewo majace
swj korzen w wierzchoku x:
odwiedzamy wierzchoek x (korzen drzewa),
przeszukujemy jego lewe poddrzewo (z korzeniem w x0),
przeszukujemy jego prawe poddrzewo (z korzeniem w x1).
Przykad 1.2 Jezeli przeszukamy drzewo z rysunku ?? metoda inorder, to etykiety utworza ciag:

2 a + 3/d
czyli wyrazenie w postaci infixowej, ale bez nawiasw. Przeszukanie tego samego drzewa
metoda preorder da ciag
etykiet:
2 + a/3d
Jest to tak zwana postac prefixowa wyrazenia. Znak operacji wystepuje w niej przed argumentami. Podobne jak w postaci postfixowej, postac prefixowa da sie jednoznacznie
rozkadac i nie wymaga nawiasw.

Rozdzia 1. Rekurencja

1.5 Drzewa poszukiwan binarnych


Drzewa sa podstawowa struktura przy budowie duzych baz danych. Jeda z najprostszych
takich struktur sa drzewa poszukiwan binarnych. Aby utworzyc drzewo poszukiwan binarnych, zaczynamy od pustego drzewa, a nastepnie wstawiamy po kolei elementy, ktre
maja byc przechowywane w drzewie. Wstawiane elementy powinny byc z jakiegos uporzadkowanego

zbioru. Ponizej przedstawiamy rekurencyjny algorytmu wstawiania elementw do drzewa. W (x) oznacza wartosc przechowywana w wierzchoku x. Pamietajmy, z e Tx oznacza poddrzewo o korzeniu w wierzchoku x.
Algorytm wstawiania elementu do drzewa poszukiwan binarnych.
Aby wstawic element e do drzewa Tx :
jezeli drzewo Tx jest puste, to
W (x) := e (wstaw e do korzenia x),
w przeciwnym razie
porwnaj e z zawartoscia korzenia W (x):
jezeli e < W (x), to
wstaw e do poddrzewa Tx0 ,
jezeli e > W (x), to
wstaw e do poddrzewa Tx1 .
Przykad 1.3 Przypusc my, ze mamy ciag
liczb naturalnych:
128, 76, 106, 402, 100, 46, 354, 1018, 112, 28, 396, 35.
Utworzymy dla tego ciagu
drzewo poszukiwan binarnych.

Rysunek 1.4: Drzewo poszukiwan po wstawieniu elementw: 128, 76, 106, 402
128

76

402

106
Po wstawieniu pierwszych czterech elementw ciagu
otrzymamy drzewo, ktre jest
przedstawione na rysunku 1.4, a po wstawieniu caego ciagu
otrzymamy drzewo, ktre
jest przedstawione na rysunku 1.5. Jezeli teraz przeszukamy to drzewo metoda inorder, to
otrzymamy ten sam ciag,
ale uporzadkowany:

28, 35, 46, 76, 100, 106, 112, 128, 354, 396, 402, 1018.

1.5. Drzewa poszukiwan binarnych

Rysunek 1.5: Drzewo dla ciagu:


128,76,106,402,100,46,354,1018,112,28, 396,35

128

76

402

46

28

106

100

354

112

1018

396

35

Jezeli mamy juz drzewo poszukiwan binarnych T , to dla kazdego wierzchoka x T


zachodzi
dla kazdego y Tx0 , W (y) < W (x),
dla kazdego y Tx1 , W (y) > W (x).
Czyli wszystkie wierzchoki w lewym poddrzewie Tx0 zawieraja wartosci mniejsze
od wartosci w x, a wszystkie wierzchoki w prawym poddrzewie Tx1 zawieraja wartosci
wieksze od wartosci w x.
Aby stwierdzic, czy jakis element e znajduje sie na tym drzewie. Postepujemy podobnie jak przy wstawianiu elementw. Zaczynamy od korzenia drzewa x = i szukamy
elementu e za pomoca ponizszego rekurencyjnego algorytmu.
Algorytm szukania elementu e na drzewie Tx .
Aby stwierdzic, czy element e znajduje sie na drzewie Tx :
jezeli Tx jest puste, to
koniec, elementu e nie ma na drzewie,
jezeli Tx nie jest puste, to
porwnujemy e z wartoscia W (x):
jezeli e = W (x), to
koniec, znalezlismy element e na drzewie,
jezeli e < W (x), to
szukamy e w lewym poddrzewie Tx0 ,

10

Rozdzia 1. Rekurencja
jezeli e > W (x), to
szukamy e w prawym poddrzewie Tx1 .

W drzewie poszukiwan binarnych czas wyszukiwania lub wstawiania elementu jest


O(h), gdzie h jest wysokoscia drzewa. W obu algorytmach tylko raz przechodzimy od
korzenia w d do liscia. Najlepiej by byo, gdyby wysokosc drzewa bya rzedu logarytm
od liczby wierzchokw, ale nie w kazdym drzewie poszukiwa n binarnych tak musi byc.

1.6 Funkcje rekurencyjne


Czasami wygodnie jest zdefiniowac funkcje za pomoca wzoru rekurencyjnego. Na przykad funkcje silnia definiuje sie zwykle za pomoca nastepujacych

dwch rwna n :
silnia(0) = 1,
silnia(n) = n silnia(n 1),

dla n 1.

Podobnie mozna definiowac inne funkcje ze zbioru liczb naturalnych w zbir liczb naturalnych. Definicja taka zawiera przepis, jak policzyc wartosc funkcji dla wartosci poczat
kowych, oraz drugi przepis, jak wyliczyc wartosc dla argumentu n za pomoca wartosci
funkcji dla mniejszych argumentw.

1.7 Funkcja (ciag)


Fibonacciego
Nastepnym przykadem rekurencyjnego definiowania funkcji jest funkcja Fibonacciego,
okreslona rwnaniami:
F (0)
= 0,
F (1)
= 1,
F (n + 2) = F (n + 1) + F (n).
Kolejne wartosci funkcji Fibonacciego to:
0, 1, 1, 2, 3, 5, 8, 13, . . .
Udowodnimy teraz przez indukcje, z e
n n

,
(1.1)
5

gdzie = 12 (1 + 5) 1, 61803 oraz = 21 (1 5) 0, 61803


Rwnosc (1.1) zachodzi dla n = 0 i n = 1. Zazmy teraz, z e zachodzi dla wszystkich
argumentw mniejszych od n. Zauwazmy, z e oraz sa rozwiazaniami

rwnania x 2
2
2
n1
n2
x 1 = 0, mamy wiec + 1 = oraz + 1 = a takze
+
= n oraz
n1
n2
n

+
= . atwo teraz mozna pokazac, z e F (n) = F (n 1) + F (n 2) =
1 (n n ).
5
Poniewaz || < 1, mamy 15 n < 15 < 12 , wiec wartosc F (n) jest rwna 15 n po
zaokragleniu

do najblizszej liczby naturalnej i funkcja Fibonacciego rosnie wykadniczo.


F (n) =

1.8. Algorytm sortowania przez scalanie

11

1.8 Algorytm sortowania przez scalanie


Zajmijmy sie teraz pewnym prostym rekurencyjnym algorytem sortowania ciagu.

Dla
prostoty zazmy, z e dugosc ciagu
jest potega dwjki.
Algorytm sortowania
jezeli ciag
ma dugosc jeden, to jest juz posortowany,
jezeli ciag
jest duzszy, to:

 dzielimy go na poowy,
 sortujemy te poowy,

 aczymy

posortowane poowy w jeden posortowany ciag.

Istota pomysu polega na tym, z e mozna szybko poaczy


c dwa posortowane ciagi
w jeden
posortowany ciag.
Algorytm aczenia

wyjasnijmy na przykadzie. Przypusc my, z e mamy


dwa ciagi:

A = (1, 3, 6, 7),
B = (2, 4, 8, 9),
i z e chcemy je poaczy
c w posortowany ciag
C. Na poczatku

ciag
C jest pusty. Ustawiamy dwa wskazniki po jednym na poczatku
kazdego ciagu
(wskazane elementy beda
oznaczone daszkiem):
A = (
1, 3, 6, 7),

B = (
2, 4, 8, 9),

C = ().

Porwnujemy wskazane elementy. Mniejszy z porwnanych elementw przepisujemy na


ciag
C i przesuwamy wskaznik w tym ciagu,
z ktrego by wziety element do ciagu
C.
W wyniku otrzymamy:
3, 6, 7),
A = (1,

2, 4, 8, 9),
B = (

C = (1).

Powtarzamy ten proces tak dugo, az w jednym z ciagw

ostatni element zostanie zabrany


do ciagu
C.
A = (1,
3, 6, 7),
A = (1, 3,
6, 7),

A = (1, 3, 6, 7),
A = (1, 3, 6,
7),
A = (1, 3, 6, 7),

B
B
B
B
B

= (2,
4, 8, 9),
= (2,
4, 8, 9),
= (2, 4,
8, 9),
= (2, 4,
8, 9),
= (2, 4,
8, 9),

C
C
C
C
C

= (1, 2),
= (1, 2, 3),
= (1, 2, 3, 4),
= (1, 2, 3, 4, 6),
= (1, 2, 3, 4, 6, 7).

W takiej sytuacje pozostae elementy tego drugiego ciagu


przenosimy do ciagu
C:
A = (1, 3, 6, 7),

B = (2, 4, 8, 9),

C = (1, 2, 3, 4, 6, 7, 8, 9).

Liczba porwnan potrzebna do scalenia ciagw

nie jest wieksza od sumy dugosci tych


ciagw.

Algorytm merge-sort (inaczej sortowanie przez scalanie), ktry sortuje ciag


S,
mozna rekurencyjnie opisac tak (rysunek 8.3):

12

Rozdzia 1. Rekurencja

merge-sort(S):
jezeli S ma tylko jeden element, to koniec,
jezeli S ma wiecej elementw, to:
 dzielimy ciag
S na poowy S1 i S2 ,
 merge-sort(S1),
 merge-sort(S2),
 aczymy

S 1 i S2 .

Rysunek 1.6: Schemat dziaania algorytmu merge-sort dla ciagu


3, 7, 5, 2, 6, 1, 8, 4
3752|6184
37|52

61|84

3|7

5|2
7

37

6|1
2

25

8|4
1

16

2357

4
48

1468
12345678

Algorytm merge-sort jest przykadem algorytmu typu dziel i zwyciez aj, ktrego
oglny schemat wyglada
tak:
jezeli problem jest maego rozmiaru, to rozwiazujemy

go bezposrednio,
jezeli problem jest duzy, to:
 dzielimy problem na podproblemy,
 rozwiazujemy

podproblemy,
 aczymy

rozwiazania

podproblemw w rozwiazanie

caego problemu.

1.9. Rozwiazywanie

rwnan i nierwnosci rekurencyjnych

13

1.9 Rozwiazywanie

rwnan i nierwnosci rekurencyjnych


Oszacujmy teraz czas dziaania algorytmu sortowania przez scalanie. Niech T (n) oznacza
liczbe operacji porwnania potrzebna do posortowania ciagu
dugosci n. Mamy nastepujace
oszacowania:

T (1) = 0,

(1.2)

n
T (n) 2T ( ) + n.
2

(1.3)

Druga zaleznosc wynika stad,


z e aby posortowac ciag
dugosci n, sortujemy dwa ciagi

dugosci n2 , a nastepnie potrzebujemy n porwnan , aby scalic te dwie powki. Dla prostoty rozwazan zakadamy tutaj, z e n jest potega dwjki, n = 2k dka jakiegos naturalnego
k.
Istnieje wiele sposobw wyliczania lub szacowania funkcji okreslonej rekurencyjnie.
Przedstawimy teraz dwa najprostsze z nich: metode podstawiania i metode iteracji.

1.10 Metoda podstawiania


W metodzie podstawiania odgadujemy rozwiazanie

albo jego oszacowanie, a nstepnie


pokazujemy, z e jest ono poprawne. Pokazemy dziaanie tej metody szacujac
zozonosc
czasowa merge-sortu okreslona rekurencja (1.2)-(1.3). Zgadujemy, z e
T (n) cn log n
dla jakiejs staej c > 0 i udowodnimy przez indukcje, z e powyzsza nierwnosc zachodzi
dla kazdego potegi dwjki n 1. Zachodzi ona dla n = 1. Zakadamy teraz, z e T ( n2 )
c n2 log( n2 ) i podstawiamy do nierwnosci (1.3)
n
n
T (n) 2c( ) log( ) + n
2
2
cn log n cn + n
cn log n
Ostatnia nierwnosc jest speniona, jezeli c 1.
Metoda podstawiania zostaa zastosowana w podrozdziale o funkcji Fibonacciego do
pokazania, z e
n n

,
(1.4)
F (n) =
5
ale tam odgadnieto dokadne rozwiazanie.

Teraz pokazemy jak dojsc do rozwiaznia

zaczynajac
od oglniejszej postaci. Zacznijmy od rwnania
F (n + 2) = F (n + 1) + F (n).

(1.5)

14

Rozdzia 1. Rekurencja

Sprawdzmy, jakie funkcje postaci F (n) = cn speniaja to rwnanie. Po podstawieniu do


rwnania (1.5) mamy
cn+2 = cn+1 + cn
Po podzieleniu stromnami przez cn , otrzymamy
c2 = c + 1.

Jest to rwnanie kwadratowe z dwoma rozwiazaniami

= 21 (1 + 5)2 oraz =

1
5)2, czyli dwie funkcje F1 (n) = n oraz F2 (n) = n speniaja rwnanie (1.5).
2 (1
Zauwazmy, z e takze kazda funkcja postaci
F (n) = c1 F1 (n) + c2 F2 (n)
gdzie c1 i c2 to stae, spenia rwnanie (1.5). Sprawdzmy teraz, dla jakich staych c 1 i c2
funkcja F spenia zaleznosci F (0) = 0 i F (1) = 1. Otrzymujemu ukad rwnosci
0 = c 1 + c2
1 = c 1 + c2
Powyzszy ukad jest speniony dla
c1
c2

1
1
=
( )
5
1
= c1 =
5

Tak wiec otrzymujemy wzr na funkcje Fibonacciego


F (n) =

n n

,
5

(1.6)

1.11 Metoda iteracyjna


Moteda iteracyjna polega na rozwijaniu rekursji. Przedstawimyja na trzech przykadach
Przykad 1.4 Jako pierwszy przykad rozwazmy zaleznosc .
T (1) = 1
n
T (n) = 3T ( ) + n
4
Dla uproszczenia zakadamy, ze n jest potega n = 4k , dla jakiegos k naturalnego. Funkcje
T rozwijamy w nastepujacy
sposb:
T (n)

=
=

n
n + 3T ( )
4
n
n
n + 3( + 3T ( ))
4
16

1.11. Metoda iteracyjna

15

3
n
= n + n + 9T ( )
4
16
...
 i1
n
3
3
+ 3i T ( i )
= n+n +...+n
4
4
4
Iteracje powtarzamy, az ostatni skadnik bedzie zawiera T (1), czyli gdy i = log 4 n.
Otrzymamy wtedy
 i1
3
3
T (n) = n + n + . . . + n
+ 3i T (1)
4
4
 i
X
3
+ 3log4 n = 4n + o(n) = O(n)
n
4
i=0
Skorzystalismy tu z rwnosci 3log4 n = nlog4 3 oraz z faktu, ze log4 3 < 1 i nlog4 3 = o(n).
Przykad 1.5 Jako drugi przykad rozwazmy rekursje
T (1) = 1
n
T (n) = 2T ( ) + n
2
Jak bedziemy ja rozwijac, to otrzymamy
T (n)

n
n + 2T ( )
2

=
=
...
=

n
n + n + 4T ( )
4

n + n + . . . + n + 2i T (

n
)
2i

Dla i = log2 n. Otrzymamy wtedy


log2 n1

T (n) = n

1 + 2log2 n = n log n + n = O(n log n)

i=0

Przykad 1.6 Jako trzeci przykad rozwazmy rekursje


T (1) = 1
n
T (n) = 4T ( ) + n
2
Jak bedziemy ja rozwijac, to otrzymamy
n
T (n) = n + 4T ( )
2
=
...
=

n
n + n2 + 16T ( )
4

n + n2 + . . . + n2i1 + 4i T (

n
)
2i

16

Rozdzia 1. Rekurencja

Dla i = log2 n. Otrzymamy wtedy


log2 n1

T (n) = n

X
i=0

2i + 4log2 n = n(2log n 1) + n2 = O(n2 )

1.12 Metoda rekurencji uniwersalnej


Przypusc my, z e mamy rwnanie rekurencyjne
n
T (n) = aT ( ) + f (n)
b

(1.7)

gdzie a 1 i b > 1. Rwnanie takie otrzymamy szacujac


czas dziaania algorytmu
rekurencyjnego, ktry metoda "dziel i rzad
z" dzieli problem na a podproblemw rozmiaru
n
b . Funkcja f (n) opisuje czas potrzebny na podzielenie problemu na podproblemy i na
poaczenie

rozwiaza
n podproblemw w rozwiazanie

caego problemu.
Na koniec podamy bez dowodu twierdzenie mwiace
jak mozna szacowac funkcje
T (n) okreslona rwnaniem (1.7).
Twierdzenie 1.7 (o rekurencji uniwersalnej) Niech T (n) bedzie okreslone dla nieujemnych liczb cakowitych rwnaniem rekurencyjnym
n
T (n) = aT ( ) + f (n),
b
gdzie a 1, b > 1 i

n
b

oznacza d nb e lub b nb c. Wtedy

(a) Jezeli f (n) = O(nlogb a ) dla pewnej staej  > 0, to T (n) = (nlogb a ).
(b) Jezeli f (n) = (nlogb a ), to T (n) = (nlogb a log n).
(c) Jezeli f (n) = (nlogb a+ ) dla pewnej staej  > 0 oraz af ( nb ) cf (n) dla
pewnej staej c < 1, to T (n) = (f (n)).
Z pewnym uproszczeniem, powyzsze twierdzenie przedstawia rozwiazanie

w zaleznosci od wyniku porwnania funkcji f (n) i jednomianu nlogb a . W punkcie (a) funkcja
(n)
cn dla pewnych staych c i
f (n) rosnie wolniej niz nlogb a , a scislej, iloraz nflog
ba
 > 0. Taka sytuacja jest w przykadzie 1.6, w ktrym a = 4, b = 2 oraz f (n) = n, a
rozwiazaniem

jest funkcja T (n) = O(n2 ).


W punkcie (b) funkcje f (n) i nlogb a sa tego samego rzedu, tak jak w przykadzie 1.5,
w ktrym a = 2, b = 2 oraz f (n) = n, a rozwiazaniem

jest funkcja T (n) = O(n log n).


(n)
logb a
W punkcie (c) funkcja f (n) rosnie szybciej niz n
, a scislej, iloraz nflog
cn
ba
dla pewnych staych c i  > 0. Taka sytuacja jest w przykadzie 1.4, w ktrym a = 3,
b = 4 oraz f (n) = n, a rozwiazaniem

jest funkcja T (n) = O(n).

1.13. Funkcje tworzace

17

1.13 Funkcje tworzace

Rwnania rekurencyjne mozna rozwiazywa

c za pomoca funkcji tworzacych.

Przesledzmy
ta metode na przykadzie funkcji Fibinacciego. Rozwazmy funkcje okreslona szeregiem
potegowym.
G(z) = F (0) + F (1)z + F (2)z 2 + + F (n)z n +

(1.8)

Funkcje G(z) nazywamy funkcja tworzac


a ciagu
F (n). Nie przejmujemy sie teraz, czy
szereg (1.8) jest zbiezny. Nasze rozumowanie bedzie mozna pzniej zweryfikowa c za
pomoca indukcji matematycznej. Mnozymy obie strony rwnania (1.8) przez z i przez
z 2.
z G(z) = F (0)z + F (1)z 2 + F (2)z 3 + + F (n)z n+1 +
(1.9)
z 2 G(z) = F (0)z 2 + F (1)z 3 + F (2)z 4 + + F (n)z n+2 +

(1.10)

a nastepnie odejmujemy od rwnania (1.8) rwnania (1.9) oraz (1.10)


G(z) zG(z) z 2 G(z) = F (0) + (F (1) f (0))z + (F (2) F (1) F (0))z 2 +
+ (F (n) F (n 1) F (n 2))z n +

W tym szeregu wyraz wolny wynosi F (0) = 0, wspczynnik przy z rwna sie F (1)
F (0) = 1, a wszystkie nastepne wspczynniki sa zerami poniewaz F (n) F (n 1)
F (n 2) = 0 dla kazdego n 2. Mamy wiec
G(z)(1 z z 2 ) = z
czyli
G(z) =

z
.
(1 z z 2 )

(1.11)

Jezeli rozwiniemy funkcje (1.11) w szereg, to wspczynniki tego rozwiniecia utworza ciag
Fibonacciego. Aby to zrobic, zauwazmy, z e funkcje G(z) mozna przedstawic
jako


z
1
1
1

G(z) =
,
=

(1 z z 2 )
1 z
5 1 z
gdzie oraz sa znanymi juz nam pierwiastkami wielomianu z 2 z 1. Funkcja
posiada rozwiniecie

X
1
=
ai z i ,
1 az
i=0
Wiec funkcja G(z) posiada rozwiniecie
G(z) =
a z tego mamy

X
1
(i i )z i ,
5
i=0

1
F (n) = (i i ).
5

1
1az

18

Rozdzia 1. Rekurencja

1.14 Zadania
1. Wypisz ciag
przeozen potrzebnych do przeniesienia czterech kra
zkw na wiezach
Hanoi.
2. Udowodnij, z e algorytm opisany w podrozdziale 8.1 wymaga 2 n 1 przeozen do
przeniesienia n kra
zkw.
3. Oblicz N W D(39, 24) wedug rekurencyjnego algorytmu Euklidesa.
4. Napisz program, ktry rekurencyjnie oblicza: a) funkcje silnia, b) funkcje Fibonacciego,
5. Napisz program, ktry oblicza symbol Newtona:
a) wedug wzoru rekurencyjnego

   

n+1
n
n
=
+
,
k
k
k1
b) wedug wzoru
 
n
n(n 1) (n k + 1)
.
=
k!
k
Porwnaj te programy.
6. Funkcja h okreslona jest nastepujacymi

rwnaniami:
h(0)
= 1,
h(n + 1) = 2 h(n) + 1.
Oblicz wartosci h(1), h(2), h(3), h(4), h(5). Udowodnij, z e h(n) = 2n+1 1.
7. Funkcja F okreslona jest nastepujacymi

rwnaniami:
F (0)
= 0,
F (1)
= 1,
F (n + 2) = 3 F (n + 1) F (n).
Oblicz wartosci F (2), F (3), F (4), F (5). Rozwia
z ulad rwnosci metoda podstawiania.
8. Wedug algorytmu aczenia

poacz
ciagi
a = (2, 5, 10, 13, 16, 23)
i b = (1, 3, 4, 7, 15, 20).
9. Stosujac
algorytm merge-sort posortuj ciag
(2, 5, 10, 13, 16, 23, 1, 3, 4, 7, 15, 20).
10. Stosujac
algorytm merge-sort posortuj ciag
sw: sowik, wrbel, kos, jaskka,
kogut, dziecio, gil, kukuka, szczygie, sowa, kruk, czubatka.
[Fragment wiersza Ptasie radio Juliana Tuwima]

1.14. Zadania

19

11. Dana jest funkcja D : N N N :


D(x, 0)
= x,
D(x, y + 1) = D(x, y) + 1.
Oblicz D(2, 3). Co oblicza funkcja D?
12. Dana jest funkcja M : N N N :
M (x, 0)
= 0,
M (x, y + 1) = D(x, y) + x.
Oblicz M (4, 3). Co oblicza funkcja M ?
13. Przedstaw rekurencyjna definicje funkcji wykadniczej x y .
14. Przedstaw rekurencyjna definicje odejmowania jedynki w liczbach n aturalnych,
ktre okreslone jest wzorem M (x) = max{x 1, 0}.
15. Przedstaw rekurencyjna definicje odejmowania w liczbach naturalnych, ktre okreslone jest wzorem M inus(x, y) = max{x y, 0}.
16. Rozwia
z metoda iteracyjna ukad rwnan
T (1) = 1,
T (n) = 2 T ( n2 ) + n2 ,

dla n 1.

Porwnaj z twierdzeniem o rekurencji uniwersalnej.


17. Rozwia
z metoda iteracyjna ukad rwnan
T (1) = 1,
T (n) = 4 T ( n2 ) + n2 ,

dla n 1.

Porwnaj z twierdzeniem o rekurencji uniwersalnej.


18. Rozwia
z metoda iteracyjna ukad rwnan
T (1) = 1,
T (n) = 8 T ( n2 ) + n2 ,

dla n 1.

Porwnaj z twierdzeniem o rekurencji uniwersalnej.


19. Za pomoca funkcji tworzacej
rozwia
z ukad rwnan
F (0)
= 0,
F (1)
= 1,
F (n + 2) = F (n + 1) + 2F (n).
20. Wypisz w postaci infixowej, prefixowej i postfixowej wyrazenie przedstawione na
rysunku 7.

20

Rozdzia 1. Rekurencja

Rysunek 1.7: Drzewo wyrazenia


+

21. Narysuj drzewo poszukiwan binarnych dla nastepujacego

ciagu
liczb: 30, 43, 13, 8,
50, 40, 20, 19, 22.
22. Narysuj drzewo poszukiwan binarnych dla nastepujacego

ciagu
sw: sowik, wrbel, kos, jaskka, kogut, dziecio, gil, kukuka, szczygie, sowa, kruk, czubatka.
[Fragment wiersza Ptasie radio Juliana Tuwima]
23. Zaprojektuj algorytm wyszukiwania najmniejszego elementu w drzewie poszukiwan binarnych.
24. Zaprojektuj algorytm, ktry dla wierzchoka z wartoscia x wyszukuje w drzewie
poszukiwan binarnych wierzchoka z nastepna wartoscia.

1.15 Problemy
1.15.1 Funkcja Ackermanna
Funkcja Ackermanna okreslona jest, dla liczb naturalnych i, j, k 1, nastepujacymi

rwnaniami:
A(1, j, k)
=j +k
A(i + 1, j, 1)
=j
A(i + 1, j, k + 1) = A(i, j, A(i + 1, j, k))
Funkcja Ackermanna jest przykadem funkcji majacej
dosc prosta definicje, ale jest
praktycznie nieobliczalna z tego powodu, z e jej wartosci szybko rosna.
1. Udowodnij, z e A(2, j, k) = j k oraz A(3, j, k) = j k .
2. Oblicz A(3, j, 1), A(3, j, 2), A(3, j, 3), A(3, j, 4).

1.15. Problemy

21

3. Udowodnij, z e
A(3, j, k) = j

k razy.

4. Oblicz A(4, 2, 1), A(4, 2, 2), A(4, 2, 3).

1.15.2 Wieze Hanoi


1. Udowodnij, z e kazdy algorytm przekadania kra
zkw w wiezach Hanoi wymaga co
najmniej 2n 1 przeozen dla n kra
zkw.
2. Rozwaz nastepujacy
algorytm przekadania kra
zkw na wiezach Hanoi:
Ustawiamy paliki w cykl A, B, C a za nim A.
Powtarzamy dwa nastepujace
ruchy, az do skutku:

najpierw przekadamy najmniejszy krazek

na nastepny cyklicznie palik,

potem wykonujemy jedyny dopuszczalny ruch, ktry nie rusza najmniejszego


kra
zka.
Sprawdz ten algorytm dla n = 2, 3 i 4. Udowodnij, z e po 2n 1 ruchach algorytm
przeozy n kra
zkw na palik B, jezeli n jest nieparzyste, lub na palik C, jezeli n jest
parzyste.

Вам также может понравиться