background image

Wykład 3 

Metoda „dziel i zwyciężaj” 

background image

Wprowadzenie 

Technika konstrukcji algorytmów

 

dziel i zwyciężaj. 

 

  

przykładowe problemy: 

– Wypełnianie planszy 

– Poszukiwanie (binarne

– Sortowanie (sortowanie przez łączenie - merge sort)

background image

Wypełnianie planszy 

Zadanie: dysponując klockami 

oraz planszą 2

n

x2

n

 z 

brakującym polem: 

Wypełnić plansze w 

całości: 

background image

Wypełnianie planszy: przypadki trywialne (n = 1) 

 Przypadek trywialny (n = 1): 

wypełniamy plansze jednym klockiem: 

Idea dla rozwiązania problemu – doprowadzić 

rozmiar zadania do przypadku trywialnego, który 

umiemy rozwiązać 

background image

Wypełnianie planszy : podział zadania 

Oryginalną planszę dzielimy na 4 części 

Dostajemy problemy o rozmiarze 2

n-1

x2

n-1

 

Ale: trzy z nich nie są podobne do 

oryginalnego (plansze nie mają brakującego 

pola)!  

background image

Wypełnianie planszy : podział zadania 

pomysł: umieszczamy jeden klocek w środku planszy i dokonujemy 

podziału na 4 części 

Teraz otrzymujemy 4 plansze o rozmiarach 2

n-1

x2

n-1

Każda z planszy ma brakujące pole

 

background image

Wypełnianie planszy : algorytm 

INPUTn  

– plansza 2

n

x2

n

– pozycja brakującego pola.  

OUTPUT

wypełniona plansza

 

 
Tile(n, L) 
   if n = 1 then 
      

przypadek trywialny 

      wypełnij jednym klockiem 
      
return 
   umieść jeden klocek w środku planszy   
  podziel planszę na 4 równe części 
  Niech L1, L2, L3, L4 oznaczają pozycje 4 brakujących pól 
   
Tile(n-1, L1) 
   Tile(n-1, L2)  
   
Tile(n-1, L3)  
   
Tile(n-1, L4)  
 

background image

Dziel i zwyciężaj 

Metoda konstrukcji algorytmów „Dziel i zwyciężaj” 

– Jeśli problem jest na tyle mały, że umiesz go rozwiązać  - zrób to. Jeśli nie 

to: 

• Podział: Podziel problem na dwa lub więcej rozdzielnych 

podproblemów 

• Rozwiązanie: Wykorzystaj metodę rekurencyjnie dla rozwiązania tych 

podproblemów 

• Łączenie: połącz rozwiązania podproblemów tak, aby rozwiązać 

oryginalny problem 

background image

Wypełnianie planszy : Dziel i zwyciężaj 

Wypełnianie jest przykładem algorytmu „dziel i zwyciężaj” : 

– w wypadku trywialnym (2x2) – po prostu wypełniamy planszę, lub: 

– Dzielimy planszę na 4 mniejsze części (wprowadzając wypełnione miejsce 

w rogu, przez umieszczenie centralnie jednego klocka) 

– Rozwiązujemy problem rekursywnie stosując tą samą metodę 

– Łączymy części umieszczając klocek w środku planszy 

background image

10 

Odnaleźć 

liczbę w posortowanej tablicy: 

– Przypadek trywialny – tablica jest jednoelementowa 

– Albo dzielimy tablice na dwie równe części i rozwiązujemy zadanie 

osobno dla każdej z

 nich 

 
 

Poszukiwanie binarne 

INPUT: A[1..n] 

– posortowana niemalejąco tablica liczb, s – liczba.  

OUTPUT: indeks 

taki, że A[j] = s. NIL, jeśli 

"

(1

j

n): A[j

 

s 

 

Binary-search(A, p, r, s): 
   if p = r then  
      if 
A[p] = s then return 
      else return NIL  

 

   q



(p+r)/2

 

   ret 

 Binary-search(A, p, q, s) 

   if ret = NIL then  
      return Binary-search
(A, q+1, r, s) 
   else return ret       

background image

11 

Rekurencja 

Czas działania algorytmu z odwołaniami rekursywnymi można opisać poprzez 
rekurencję 

Równanie/nierówność opisująca funkcję poprzez jej wartości dla mniejszego 

argumentu 

 

 

Przykład: poszukiwanie binarne 

 

 

 

 

 

 

Po rozwiązaniu daje to złożoność O(n)! – taką samą jak dla metody naiwnej 

(1)

  if 

1

( )

2 ( / 2)

(1)   if 

1

n

T n

T n

n

 

 

background image

12 

Poszukiwanie binarne (poprawione) 

INPUT: A[1..n] 

– posortowana niemalejąco tablica liczb, s – liczba.  

OUTPUT: indeks 

taki, że A[j] = s. NIL, jeśli 

"

(1

jn): A[j] ≠s  

 
Binary-search(A, p, r, s): 
   if p = r then  
      if A[p] = s then return 
      
else return NIL  

 

   q



(p+r)/2

 

   if A[q] 

 s then return Binary-search(A, p, q, s) 

   else return Binary-search(A, q+1, r, s) 

T(n) = 

(n) – nie lepiej niż dla metody siłowej! 

Poprawa: rozwiązywać zadanie tylko dla jednej połowy tablicy 

 

background image

13 

Czas działania metody 

T(n) = 

(lg n) ! 

(1)

  if 

1

( )

( / 2)

(1)   if 

1

n

T n

T n

n

 

 

background image

14 

 
Sortowanie przez łączenie (merge sort) 

 Podziel

Jeśli posiada przynajmniej dwa elementy (1 lub 0 elementów – 

przypadek trywialny), podziel 

na dwie równe (z dokładnością do 1 

elementu) części S

1

 i S

2

. (tj. S

1

 zawiera pierwsze 

n/2

  

elementów, a S

2

 

kolejne 

n/2

). 

Zwyciężaj: posortuj sekwencje S

1

 i S

2

 

stosując Merge Sort. 

Połącz: Połącz elementy z dwóch posortowanych sekwencji S

1

 i S

2

 w 

sekwencję zachowaniem porządku 

background image

15 

Algorytm 

– Merge Sort   

Merge-Sort(A, p, r) 
   if p < r then 
      q

 

(p+r)/2

 

      Merge-Sort(A, p, q) 
      Merge-Sort(A, q+1, r) 
      Merge(A, p, q, r) 

Merge(A, p, q, r) 
   wybieramy mniejszy z dwóch elementów na początku 
sekwencji
 A[p..q] oraz A[q+1..r] i wkładamy go do 
sekwencji wynikowej, przestawiamy odpowiedni znacznik. 
Powtarzamy to aż do wyczerpania się elementów. 
Rezultat kopiujemy do A[p..r]. 
 

background image

16 

Sortowanie przez łączenie - 1 

background image

17 

Sortowanie przez łączenie - 2 

background image

18 

Sortowanie przez łączenie - 3 

background image

19 

Sortowanie przez łączenie - 4 

background image

20 

Sortowanie przez łączenie - 5 

background image

21 

Sortowanie przez łączenie - 6 

background image

22 

Sortowanie przez łączenie - 7 

background image

23 

Sortowanie przez łączenie - 8 

background image

24 

Sortowanie przez łączenie - 9 

background image

25 

Sortowanie przez łączenie - 10 

background image

26 

Sortowanie przez łączenie - 11 

background image

27 

Sortowanie przez łączenie - 12 

background image

28 

Sortowanie przez łączenie - 13 

background image

29 

Sortowanie przez łączenie - 14 

background image

30 

Sortowanie przez łączenie - 15 

background image

31 

Sortowanie przez łączenie - 16 

background image

32 

Sortowanie przez łączenie - 17 

background image

33 

Sortowanie przez łączenie - 18 

background image

34 

Sortowanie przez łączenie - 19 

background image

35 

Sortowanie przez łączenie - 20 

background image

36 

Sortowanie przez łączenie - 21 

background image

37 

Sortowanie przez łączenie - 22 

background image

38 

Sortowanie przez łączenie – podsumowanie  

 Sortowanie liczb 

– jeśli n=1 – trywialne  

– rekursywnie sortujemy 2 ciągi 

n/2

 i 

n/2

 liczb 

– łączymy dwa ciągi w czasie 

(n

 Strategia  

– Podział problemu na mniejsze, ale 

analogiczne podproblemy 

– Rekursywne rozwiązywanie 

podproblemów 

– Łączenie otrzymanych rozwiązań 

background image

39 

Sortowanie przez łączenie – czas działania 

Czas działania algorytmu może być 
reprezentowany przez następującą 
zależność rekurencyjną: 

 

 

 

 

 

Po rozwiązaniu dostajemy: 

(1)

  if 

1

( )

2 ( / 2)

( )   if 

1

n

T n

T n

n

n

 

 

)

lg

(

)

(

n

n

n

T

background image

40 

Wieże Hanoi 

Mamy 3 wieże oraz stos 64 dysków o zmniejszających się średnicach 
umieszczonych na pierwszej wieży 

Potrzebujemy przenieść wszystkie dyski na inną wieżę 

Zabronione jest położenie dysku  większego na mniejszym 

W każdym kroku wolno mam przenieść tylko jeden dysk 

background image

41 

Wieże Hanoi 

background image

42 

Rozwiązanie rekursywne 

background image

43 

Algorytm rekursywny 

INPUTn  

– ilość dysków , a, b, c – wieże, wieża a zawiera wszystkie dyski.  

OUTPUT: a, b, c 

– wieże, wieża b zawiera wszystkie dyski 

 
Hanoi(n, a, b, c) 
      
if  n = 1 then 
          Move(a,b); 
      
else 
          Hanoi(n-1,a,c,b); 
          
Move(a,b); 
          
Hanoi(n-1,c,b,a); 
 

Poprawność algorytmu łatwo pokazać przez indukcję względem n

background image

44 

Ilość kroków 

 

Ilość kroków M(n) potrzebnych do 
rozwiązania problemu dla 
 dysków 
spełnia zależność rekurencyjną 

M(1) = 1 

M(n) = 2M(n-1) + 1 

 

M(n) 

15 

31 

background image

45 

Ilość kroków 

Rozwijając tę zależność dostajemy 

 

    M(n)   = 2M(n-1) + 1 

       

= 2*[2*M(n-2)+1] + 1 = 2

*

 

M(n-2) + 1+2 

       

= 2

* [2*M(n-3)+1]  + 1 + 2 

       

= 2

*

 

M(n-3) + 1+2 + 2

=… 

 Po k krokach 
 

M(n) = 2

*

 

M(n-k) + 1+2 + 2

+ … + 2

n-k-1 

 

 Dla k = n-1 
 

M(n)  = 2

n-1 

*

 

M(1) + 1+2 + 2

+ … + 2

n-2 

 

 

= 1 + 2 + … + 2

n-1 

= 2

n

-1