Algorytm dziel i zwyciężaj

W tym samouczku dowiesz się, jak działa algorytm dziel i rządź. Porównamy również podejście dziel i zwyciężaj z innymi podejściami do rozwiązania problemu rekurencyjnego.

Algorytm dziel i rządź jest strategia rozwiązywania duży problem

  1. podzielenie problemu na mniejsze podproblemy
  2. rozwiązywanie podproblemów i
  3. łącząc je, aby uzyskać pożądany efekt.

Aby użyć algorytmu dziel i zwyciężaj, używana jest rekurencja . Dowiedz się o rekurencji w różnych językach programowania:

  • Rekursja w Javie
  • Rekursja w Pythonie
  • Rekurencja w C ++

Jak działają algorytmy dzielenia i zwyciężania?

Oto wymagane kroki:

  1. Podziel : podziel zadany problem na podproblemy za pomocą rekurencji.
  2. Conquer : rozwiązuj mniejsze podproblemy rekurencyjnie. Jeśli podproblem jest wystarczająco mały, rozwiąż go bezpośrednio.
  3. Połącz: połącz rozwiązania podproblemów, które są częścią procesu rekurencyjnego, aby rozwiązać rzeczywisty problem.

Zrozummy tę koncepcję na przykładzie.

Tutaj posortujemy tablicę stosując metodę dziel i zwyciężaj (tj. Sortowanie przez scalanie).

  1. Niech daną tablicą będzie: Tablica do sortowania przez scalanie
  2. Podziel tablicę na dwie połowy. Podziel tablicę na dwie części.
    Ponownie podziel rekursywnie każdą podczęść na dwie połowy, aż uzyskasz pojedyncze elementy. Podziel tablicę na mniejsze części
  3. Teraz połącz poszczególne elementy w posortowany sposób. Tutaj podbijaj i łącz kroki idą obok siebie. Połącz części podrzędne

Złożoność czasowa

Złożoność algorytmu dziel i zwyciężaj jest obliczana za pomocą twierdzenia głównego.

T (n) = aT (n / b) + f (n), gdzie n = rozmiar wejścia a = liczba podproblemów w rekursji n / b = rozmiar każdego podproblemu. Zakłada się, że wszystkie podproblemy mają ten sam rozmiar. f (n) = koszt pracy wykonanej poza wywołaniem rekurencyjnym, który obejmuje koszt podzielenia problemu i koszt scalenia rozwiązań

Weźmy przykład, aby znaleźć złożoność czasową problemu rekurencyjnego.

W przypadku sortowania przez scalanie równanie można zapisać jako:

 T (n) = aT (n / b) + f (n) = 2T (n / 2) + O (n) Gdzie, a = 2 (za każdym razem problem jest dzielony na 2 podproblemy) n / b = n / 2 (rozmiar każdego problemu podrzędnego to połowa danych wejściowych) f (n) = czas potrzebny na podzielenie problemu i połączenie podproblemów T (n / 2) = O (n log n) (Aby to zrozumieć, zapoznaj się z główne twierdzenie.) Teraz T (n) = 2T (n log n) + O (n) ≈ O (n log n) 

Dziel i zwyciężaj Vs Dynamiczne podejście

Podejście „dziel i rządź” dzieli problem na mniejsze podproblemy; te podproblemy są dalej rozwiązywane rekurencyjnie. Wynik każdego podproblemu nie jest przechowywany do wykorzystania w przyszłości, podczas gdy w podejściu dynamicznym wynik każdego podproblemu jest przechowywany do przyszłego odniesienia.

Użyj metody dziel i rządź, gdy ten sam podproblem nie jest rozwiązywany wiele razy. Skorzystaj z podejścia dynamicznego, jeśli wynik podproblemu ma być używany wielokrotnie w przyszłości.

Zrozummy to na przykładzie. Załóżmy, że próbujemy znaleźć szereg Fibonacciego. Następnie,

Podejście dziel i zwyciężaj:

 fib (n) Jeśli n <2, return 1 Else, return f (n - 1) + f (n -2) 

Dynamiczne podejście:

 mem = () fib (n) Jeśli n in mem: return mem (n) else, If n <2, f = 1 else, f = f (n - 1) + f (n -2) mem (n) = f powrót f 

W podejściu dynamicznym mem przechowuje wynik każdego podproblemu.

Zalety algorytmu dziel i zwyciężaj

  • Złożoność mnożenia dwóch macierzy metodą naiwną wynosi O (n 3 ), podczas gdy przy zastosowaniu podejścia dziel i zwyciężaj (tj. Mnożenia macierzy Strassena) wynosi O (n 2,8074 ). Takie podejście upraszcza również inne problemy, takie jak Wieża Hanoi.
  • To podejście jest odpowiednie dla systemów wieloprocesowych.
  • Efektywnie wykorzystuje pamięci podręczne.

Dziel i podbijaj aplikacje

  • Wyszukiwanie binarne
  • Merge Sort
  • Szybkie sortowanie
  • Mnożenie macierzy Strassena
  • Algorytm Karatsuba

Interesujące artykuły...