📜  分而治之算法

📅  最后修改于: 2020-09-27 17:06:31             🧑  作者: Mango

在本教程中,您将学习分而治之算法的工作原理。此外,您将发现分而治之方法与其他解决递归问题的方法之间的比较。

分而治之算法是一种通过以下方法解决大问题的策略

  1. 将问题分解为较小的子问题
  2. 解决子问题,以及
  3. 合并它们以获得所需的输出。

要使用分治法,需要使用递归 。了解不同编程语言中的递归:

  • Java中的递归
  • Python的递归
  • C++中的递归

分而治之算法如何工作?

涉及的步骤如下:

  1. 除法 :使用递归将给定的问题分为子问题。
  2. 征服 :递归解决较小的子问题。如果子问题足够小,则直接解决。
  3. 合并:合并子问题的解决方案,这是递归过程的一部分,以获取实际问题的解决方案。

让我们借助示例来理解这个概念。

在这里,我们将使用分而治之的方法(即合并排序)对数组进行排序。

  1. 让给定数组为:
    initial array for merge sort
    合并排序数组
  2. 划分阵列分为两半。
    Divide the array into two subparts
    将数组分为两个子部分

    同样,将每个子部分递归地分为两半,直到获得单个元素。

    Divide the array into smaller subparts
    将阵列分成较小的子部分
  3. 现在,以排序的方式组合各个元素。在这里, 征服合并的步骤并存。
    Combine the subparts
    合并子部分

复杂

使用主定理计算分而治之算法的复杂度。

T(n) = aT(n/b) + f(n),
where,
n = size of input
a = number of subproblems in the recursion
n/b = size of each subproblem. All subproblems are assumed to have the same size.
f(n) = cost of the work done outside the recursive call, which includes the cost of dividing the problem and cost of merging the solutions

让我们举一个例子来发现递归问题的时间复杂度。

对于合并排序,等式可以写成:

T(n) = aT(n/b) + f(n)
     = 2T(n/2) + O(n)
Where, 
a = 2 (each time, a problem is divided into 2 subproblems)
n/b = n/2 (size of each sub problem is half of the input)
f(n) = time taken to divide the problem and merging the subproblems
T(n/2) = O(n log n) (To understand this, please refer to the master theorem.)

Now, T(n) = 2T(n log n) + O(n)
          ≈ O(n log n)

分而治之与动态方法

分而治之的方法将一个问题分成较小的子问题,这些子问题可以递归进一步解决。每个子问题的结果都不存储以供将来参考,而在动态方法中,每个子问题的结果均存储以供将来参考。

当同一子问题没有多次解决时,请使用分而治之的方法。当将来要多次使用子问题的结果时,请使用动态方法。

让我们通过一个例子来理解这一点。假设我们试图找到斐波那契数列。然后,

分而治之的方法:

fib(n)
    If n < 2, return 1
    Else , return f(n - 1) + f(n -2)

动态方法:

mem = [ ]
fib(n)
    If n in mem: return mem[n] 
    else,     
        If n < 2, f = 1
        else , f = f(n - 1) + f(n -2)
        mem[n] = f
        return f

在动态方法中, mem存储每个子问题的结果。


分而治之算法的优势
  • 使用朴素方法将两个矩阵相乘的复杂度为O(n 3 ) ,而使用分而治之方法(即Strassen矩阵乘法)的复杂度为O(n 2.8074 ) 。这种方法还简化了诸如河内塔之类的其他问题。
  • 这种方法适用于多处理系统。
  • 它有效地利用了内存缓存。

分治法
  • 二元搜寻
  • 合并排序
  • 快速排序
  • Strassen的矩阵乘法
  • 唐津算法