• Nie Znaleziono Wyników

Rozdzial 07 - Rekurencja

N/A
N/A
Protected

Academic year: 2021

Share "Rozdzial 07 - Rekurencja"

Copied!
13
0
0

Pełen tekst

(1)

Matematyka Dyskretna

Andrzej Szepietowski

25 czerwca 2002 roku

(2)
(3)

Rozdział 1

Rekurencja

1.1

Wie˙ze Hanoi

Rekurencja jest to zdolno´s´c podprogramu (procedury lub funkcji) do wywoływania

sa-mego siebie. Zacznijmy od przykładu wie˙z Hanoi. Przypu´s´cmy, ˙ze mamy trzy wie˙ze lub trzy paliki: , i . Na pierwszym paliku, , znajduj¸a si¸e trzy kr¸a˙zki ró˙znej wielko´sci,

nanizane w porz¸adku od najwi¸ekszego na dole do najmniejszego na górze. Paliki i

s¸a na pocz¸atku puste. Nale˙zy przenie´s´c wszystkie kr¸a˙zki z palika na , posługuj¸ac si¸e

w razie potrzeby palikiem , według nast¸epuj¸acych reguł:



mo˙zna przenosi´c po jednym kr¸a˙zku z jednego palika na inny,



nie mo˙zna umieszcza´c wi¸ekszego kr¸a˙zka na mniejszym.

Rozwi¸azaniem tej łamigłówki dla trzech kr¸a˙zków jest nast¸epuj¸acy ci¸ag siedmiu przeło-˙ze´n:                  gdzie zapis 

oznacza przeniesienie szczytowego kr¸a˙zka z palika na palik



. Chodzi nam teraz o algorytm, który dla dowolnej liczby  kr¸a˙zków wypisze ci¸ag

operacji potrzebnych do przeło˙zenia kr¸a˙zków z palika na palik .

Algorytm przekładania kr¸a˙zków



je˙zeli , to przekładamy ten jeden kr¸a˙zek 

 ,



je˙zeli  , to:



przekładamy kr¸a˙zków z na pomocniczy palik (posługuj¸ac si¸e w

razie potrzeby palikiem ),



przekładamy -ty kr¸a˙zek z na ,



przekładamy kr¸a˙zków z na (za pomoc¸a palika ).

(4)

Nietrudno zauwa˙zy´c, ˙ze je˙zeli proces przekładania  kr¸a˙zków jest prawidłowy, to

cały proces te˙z jest prawidłowy, poniewa˙z obecno´s´c najwi¸ekszego kr¸a˙zka na dole palika nie przeszkadza w przekładaniu  mniejszych kr¸a˙zków.

Powy˙zszy algorytm opiszmy teraz za pomoc¸a rekurencyjnej procedury przenie´s, któ-ra odwołuje si¸e sama do siebie i wypisuje ci¸ag instrukcji przeniesienia kr¸a˙zków z palika na palik



.

procedura przenie´s( kr¸a˙zków z na

 , za pomoc¸a ):  je˙zeli  , to wypisz   ,  je˙zeli , to  przenie´s( kr¸a˙zków z na  , za pomoc¸a  ),  wypisz   ,  przenie´s( kr¸a˙zków z  na  , za pomoc¸a ).

Rysunek 1.1: Schemat działania procedury przenie´s dla wie˙z Hanoi z trzema kr¸a˙zkami

                                  

Na rysunku 8.1 zilustrowano działanie procedury przenie´s dla

 . Skrót    

oznacza wywołanie procedury przenie´s( kr¸a˙zków z na



, za pomoc¸a



). Strzałki w dół oznaczaj¸a wywołanie procedury, strzałki w gór¸e powroty po wykonaniu procedu-ry, a strzałki poziome odpowiadaj¸a nast¸epstwu instrukcji w ramach jednego wykonania procedury.

(5)

1.2. Algorytm Euklidesa, wersja rekurencyjna 5

1.2

Algorytm Euklidesa, wersja rekurencyjna

Innym przykładem algorytmu rekurencyjnego mo˙ze by ´c rekurencyjna wersja algorytmu Euklidesa, który oblicza najwi¸ekszy wspólny dzielnik dwóch dodatnich liczb naturalnych

i : fun¯kcja NWD(a,b):  je˙zeli   , to     ,  je˙zeli   , to           ,  je˙zeli  , to          .

W j¸ezyku Pascal powy˙zsz¸a procedur¸e mo˙zemy zapisa´c w nast¸epuj¸acy sposób:

function NWD(a,b:integer):integer; begin

if a=b then NWD:=a else if 



then NWD:=NWD(a-b,b) else NWD:=NWD(a,b-a) end;

Rysunek 1.2: Schemat działania rekurencyjnej wersji algorytmu Euklidesa NWD(5,3):=1

NWD(2,3):=1

NWD(2,1):=1

NWD(1,1):=1

Na rysunku 8.2 przedstawiono proces obliczania funkcji NWD(7,3).

1.3

Funkcje rekurencyjne

Czasami wygodnie jest zdefiniowa´c funkcje za pomoc¸a wzoru rekurencyjnego. Na przy-kład funkcj¸e silnia definiuje si¸e zwykle za pomoc¸a nast¸epuj¸acych dwóch równa ´n:

             

(6)

Podobnie mo˙zna definiowa´c inne funkcje ze zbioru liczb naturalnych w zbiór liczb natu-ralnych. Definicja taka zawiera przepis, jak policzy´c warto´s´c funkcji dla warto´sci pocz¸atkowych, oraz drugi przepis, jak wyliczy´c warto´s´c dla argumentu

za pomoc¸a warto´sci funkcji dla mniejszych argumentów.

1.4

Funkcja (ci¸ag) Fibonacciego

Nast¸epnym przykładem rekurencyjnego definiowania funkcji jest funkcja Fibonacciego, okre´slona równaniami:                           !

Kolejne warto´sci funkcji Fibonacciego to:

             !!!

Udowodnimy teraz przez indukcj¸e, ˙ze

          (1.1) gdzie           "  oraz           " 

Równo´s´c (1.1) zachodzi dla   i



  . Załó˙zmy teraz, ˙ze zachodzi dla wszystkich

argumentów mniejszych od

. Zauwa˙zmy, ˙ze

oraz s¸a rozwi¸azaniami równania       , mamy wi¸ec      oraz    a tak˙ze          oraz        

. Łatwo teraz mo˙zna pokaza´c, ˙ze 

                    . Poniewa˙z   , mamy      , wi¸ec warto´s´c    jest równa !

 po zaokr¸agleniu do najbli˙zszej liczby naturalnej i funkcja Fibonacciego ro´snie

wykładniczo.

1.5

Funkcja Ackermanna

Funkcja Ackermanna okre´slona jest, dla liczb naturalnych

#"  , nast¸epuj¸acymi rów-naniami:   $"   &%  "                     #"         $"       $" "!

Funkcja Ackermanna jest przykładem funkcji maj¸acej do´s´c prost¸a definicj¸e, ale jest prak-tycznie nieobliczalna z tego powodu, ˙ze jej warto´sci szybko rosn¸a. Na przykład:

   ) +*

(7)

1.6. Algorytm sortowania przez scalanie 7      ) )     '   ) ) )  i ogólnie          )   !

1.6

Algorytm sortowania przez scalanie

Zajmijmy si¸e teraz pewnym prostym rekurencyjnym algorytem sortowania ci¸agu. Dla prostoty załó˙zmy, ˙ze długo´s´c ci¸agu jest pot¸eg¸a dwójki.

Algorytm sortowania



je˙zeli ci¸ag ma długo´s´c jeden, to jest ju˙z posortowany,



je˙zeli ci¸ag jest dłu˙zszy, to:



dzielimy go na połowy,



sortujemy te połowy,



ł¸aczymy posortowane połowy w jeden posortowany ci¸ag.

Istota pomysłu polega na tym, ˙ze mo˙zna szybko poł¸aczy ´c dwa posortowane ci¸agi w jeden posortowany ci¸ag. Algorytm ł¸aczenia wyja´snijmy na przykładzie. Przypu´s´cmy, ˙ze mamy dwa ci¸agi:            '    

i ˙ze chcemy je poł¸aczy´c w posortowany ci¸ag  . Na pocz¸atku ci¸ag jest pusty.

Usta-wiamy dwa wska´zniki po jednym na pocz¸atku ka˙zdego ci¸agu (wskazane elementy b¸ed¸a oznaczone daszkiem):              '         !

Porównujemy wskazane elementy. Mniejszy z porównanych elementów przepisujemy na ci¸ag i przesuwamy wska´znik w tym ci¸agu, z którego był wzi¸ety element do ci¸agu  .

W wyniku otrzymamy:              '          !

Powtarzamy ten proces tak długo, a˙z w jednym z ci¸agów ostatni element zostanie zabrany do ci¸agu .             '                        '                          '              '                '              '        

(8)

W takiej sytuacje pozostałe elementy tego drugiego ci¸agu przenosimy do ci¸agu :            '              '      !

Liczba porówna ´n potrzebna do scalenia ci¸agów nie jest wi¸eksza od sumy długo´sci tych ci¸agów.

Algorytm merge-sort (inaczej — sortowanie przez scalanie), który sortuje ci¸ag , mo˙zna rekurencyjnie opisa´c tak (rysunek 8.3):

merge-sort(S):



je˙zeli ma tylko jeden element, to koniec,



je˙zeli ma wi¸ecej elementów, to:



dzielimy ci¸ag na połowy  i

 ,  merge-sort(  ),  merge-sort(  ),  ł¸aczymy  i  .

Rysunek 1.3: Schemat działania algorytmu merge-sort dla ci¸agu 3, 7, 5, 2, 6, 1, 8, 4 3752|6186 37|52 61|84 3|7 5|2 6|1 8|4 3 7 5 2 6 1 8 4 37 25 16 48 2357 1468 12345678

Algorytm merge-sort jest przykładem algorytmu typu „dziel i zwyci¸e˙zaj”, którego ogólny schemat wygl¸ada tak:



(9)

1.7. Rozwi¸azywanie równa ´n i nierówno´sci rekurencyjnych 9



je˙zeli problem jest du˙zy, to:



dzielimy problem na podproblemy,



rozwi¸azujemy podproblemy,



ł¸aczymy rozwi¸azania podproblemów w rozwi¸azanie całego problemu.

1.7

Rozwi¸azywanie równa ´

n i nierówno´

sci rekurencyjnych

Oszacujmy teraz czas działania algorytmu sortowania przez scalanie. Niech 





oznacza liczb¸e operacji porównania potrzebn¸a do posortowania ci¸agu długo´sci

. Mamy nast¸epuj¸ace oszacowania:       (1.2)        ! (1.3)

Druga zale˙zno´s´c wynika st¸ad, ˙ze aby posortowa´c ci¸ag długo´sci

, sortujemy dwa ci¸agi długo´sci

, a nast¸epnie potrzebujemy

porówna ´n, aby scali´c te dwie połówki. Dla pro-stoty rozwa˙za ´n zakładamy tutaj, ˙ze

jest pot¸eg¸a dwójki,





dka jakiego´s naturalnego



.

Istnieje wiele sposobów wyliczania lub szacowania funkcji okre´slonej rekurencyjnie. Przedstawimy teraz dwa najprostsze z nich: metod¸e podstawiania i metod¸e iteracji.

1.8

Metoda podstawiania

W metodzie podstawiania odgadujemy rozwi¸azanie albo jego oszacowanie, a nst¸epnie pokazujemy, ˙ze jest ono poprawne. Poka˙zemy działanie tej metody szacuj¸ac zło˙zono´s´c czasow¸a merge-sortu okre´slon¸a rekurencj¸a (1.2)-(1.3). Zgadujemy, ˙ze

      

dla jakiej´s stałej



  i udowodnimy przez indukcj¸e, ˙ze powy˙zsza nierówno´s´c

zacho-dzi dla ka˙zdego pot¸egi dwójki

 . Zachodzi ona dla



  . Zakładamy teraz, ˙ze

           i podstawiamy do nierówno´sci (1.3)                                 

Ostatnia nierówno´s´c jest spełniona, je˙zeli



 .

Metoda podstawiania została zastosowana w podrozdziale o funkcji Fibonacciego do pokazania, ˙ze          (1.4)

(10)

ale tam odgadni¸eto dokładne rozwi¸azanie. Teraz poka˙zemy jak doj´s´c do rozwi¸aznia zaczynaj¸ac od ogólniejszej postaci. Zacznijmy od równania

             ! (1.5)

Sprawd´zmy, jakie funkcje postaci 







,

spełniaj¸a to równanie. Po podstawieniu do równania (1.5) mamy           

Po podzieleniu stromnami przez

 , otrzymamy      "!

Jest to równanie kwadratowe z dwoma rozwi¸azaniami       oraz    

, czyli dwie funkcje 

      oraz       spełniaj¸a równanie (1.5). Zauwa˙zmy, ˙ze tak˙ze ka˙zda funkcja postaci

                gdzie  i  

to stałe, spełnia równanie (1.5). Sprawd´zmy teraz, dla jakich stałych  i





funkcja spełnia zale˙zno´sci 



  i 



  . Otrzymujemu układ równo´sci               

Powy˙zszy układ jest spełniony dla

                   

Tak wi¸ec otrzymujemy wzór na funkcj¸e Fibonacciego

          (1.6)

1.9

Metoda iteracyjna

Moteda iteracyjna polega na rozwijaniu rekursji. Jako pierwszy przykład rozwa˙zmy za-le˙zno´s´c.             '  

Dla uproszczenia zakładamy, ˙ze

jest pot¸eg¸a  '



, dla jakiego´s

naturalnego. Funkcj¸e rozwijamy w nast¸epuj¸acy sposób:

      

(11)

1.10. Metoda rekurencji uniwersalnej 11       '     ,        '     ,      '        '    ,      '  !!!      '    ,  !!!    ' 

Iteracj¸e powtarzamy, a˙z ostatni składnik b¸edzie zawierał 

 , czyli gdy      *  . Otrzymamy wtedy         '    ,  !!!             '       '           Skorzystali´smy tu z równo´sci        

oraz z faktu, ˙ze   *

  i        .

Jako drugi przykład rozwa˙zmy rekursj¸e

             

Jak b¸edziemy j¸a rozwija´c, to otrzymamy

                 '           '                    !!!        !!!     Dla      . Otrzymamy wtedy        )        )                  (1.7)

1.10

Metoda rekurencji uniwersalnej

Przypu´s´cmy, ˙ze mamy równanie rekurencyjne

          (1.8)

(12)

gdzie  i



  . Równanie takie otrzymamy szacuj¸ac czas działania algorytmu

rekurencyjnego, który metod¸a "dziel i rz¸ad´z" dzieli problem na podproblemów rozmiaru

  . Funkcja   

opisuje czas potrzebny na podzielenie problemu na podproblemy i na poł¸aczenie rozwi¸aza ´n podproblemów w rozwi¸azanie całego problemu.

Na koniec podamy bez dowodu twierdzenie mówi¸ace jak mo˙zna szacowa ´c funkcj¸e







okre´slon¸a równaniem (1.8).

Twierdzenie 1.1 (o rekurencji uniwersalnej) Niech 





b¸edzie okre´slone dla nieujem-nych liczb całkowitych równaniem rekurencyjnym

      "       gdzie  ,   i  " oznacza   " lub    . Wtedy  Je˙zeli             

dla pewnej stałej   , to 

        .  Je˙zeli            , to                .  Je˙zeli            

dla pewnej stałej   oraz

           dla pewnej stałej   , to           .

1.11

Zadania

1. Napisz program, który rekurencyjnie oblicza: a) funkcj¸e silnia, b) funkcj¸e Fibonac-ciego, c) funkcj¸e wykładnicz¸a 

.

2. Napisz program, który oblicza symbol Newtona: a) według wzoru rekurencyjnego

                b) według wzoru                  ! Porównaj te programy.

3. Napisz program, który rekurencyjnie oblicza funkcj¸e:

                       ! 4. Oblicz    ' 

według rekurencyjnego algorytmu Euklidesa. 5. Według algorytmu ł¸aczenia poł¸acz ci¸agi  

           i        '       .

(13)

1.11. Zadania 13 6. Stosuj¸ac algorytm merge-sort posortuj ci¸ag słów: słowik, wróbel, kos, jaskółka,

kogut, dzi¸ecioł, gil, kukułka, szczygieł, sowa, kruk, czubatka. [Fragment wiersza Ptasie radio Juliana Tuwima]

7. Dana jest funkcja  

  :                 "! Oblicz    . Co oblicza funkcja ?

8. Dana jest funkcja   

  :                    ! Oblicz '    . Co oblicza funkcja ?

9. Wypisz ci¸ag przeło˙ze ´n potrzebnych do przeniesienia czterech kr¸a˙zków na wie˙zach Hanoi.

10. Udowodnij, ˙ze algorytm opisany w podrozdziale 8.1 wymaga



  przeło˙ze´n do

przeniesienia

Obraz

Rysunek 1.1: Schemat działania procedury przenie´s dla wie˙z Hanoi z trzema kr¸a˙zkami
Rysunek 1.2: Schemat działania rekurencyjnej wersji algorytmu Euklidesa NWD(5,3):=1
Rysunek 1.3: Schemat działania algorytmu merge-sort dla ci¸agu 3, 7, 5, 2, 6, 1, 8, 4

Cytaty

Powiązane dokumenty

Podaj denicj¦ relacji równowa»no±ci, wyja±niaj¡c u»yte w denicji poj¦cia..

Opisa¢ na czym polega test Bartletta dla wielu

Kiedy my´slimy, ˙ze funkcja nie b¸edzie ci¸ ag la lub nie wiemy wcale co mo˙ze si¸e zdarzy´ c, naj latwiej b¸edzie sprawdzi´ c kilka warunk´ ow koniecznych dla ci¸ ag

Coraz czêœciej do pomiarów wielkoœci geometrycznych s¹ stoso- wane metody cyfrowej analizy obrazu [1, 2, 6, 7]. Znane dotychczas metody optyczne takie jak mikroskopy pomiarowe

Je˙zeli budujemy ci¸ag bez powt´orze´ n, to na pierwszy element ci¸agu mo˙zemy wybra´c ka˙zdy z n element´ow zbioru A, na drug¸a pozycj¸e w ci¸agu mo˙zemy wybra´c ju˙z

[r]

Do wystawienia oceny z przedmiotu brany jest wynik ostatniego zaliczenia wyk ladu (albo suma punkt´ow z obu cz¸e´sci zaliczenia je´sli student zalicza l na raty i nie poprawia l).

Do liczby punkt´ow uzyskanych na egzaminie ustnym (max. 60 punkt´ow) doliczana jest liczba punkt´ow punkt´ow uzyskanych na egzaminie pisemnym albo, w przypadku niezdawania