算法导论系列笔记之分治法

分治法

步骤

  • 分解,将问题划分成一些子问题,子问题的形式与原问题一样,只是规模更小
  • 解决,递归的解决每个子问题
  • 合并,将子问题的解组合成原问题的解

例子

归并排序

  • 分解:将数组一分为二
  • 解决:递归处理每一个子数组
  • 合并:将排序好的子数组进行合并
分析其递归式
  • T(n) = 2T(n/2) + Θ(n) n>1
  • T(n) = Θ(1) n=1

二分查找法

  • 分解:将x与排序数组的中间一个数进行比较
  • 解决:在符合条件的一个子数组中递归处理
  • 合并:不用做什么
分析
  • T(n) = T(n/2) + Θ(1)

乘方问题

给一个数x,给一个正整数n,要求计算x^n

  • 分解:考虑x的n/2次方
    • 要考虑n如果是奇数
      • 考虑x的(n-1)/2次方
  • 解决:递归处理
  • 合并:相乘

斐波那契数列:

f(n) = f(n-1) + f(n-2) n>1

解决办法
自下而上处理
  • 从f_0、f_1、…计算到f_n
  • 只需要线性的时间
朴素平方递归
  • 使用数列性质 f_n = ()_n/根号5 理论机器->现有条件下无法
平方递归方法
  • 利用定理

( f ( n + 1 ) f ( n ) f ( n ) f ( n 1 ) ) = ( 1 1 1 0 ) n (\begin{matrix} f(n+1) & f(n) \\ f(n) & f(n-1) \\ \end{matrix}) = (\begin{matrix} 1 & 1 \\ 1 & 0 \\ \end{matrix})^n

  • Θ(logn)

矩阵乘法

给两个矩阵A和B,求A*B的

  • 线性时间的计算的伪代码 【Θ(n^3)】

  • 合并:求和,得到最终矩阵

分析
  • 矩阵相加 Θ(n^2)

  • 复杂度:T(n) = 8T(n/2) + Θ(n^2)

  • 并没有更快

分治解决方法2 - Strassen算法
  • 将8次递归降低到7次递归
步骤
  • 将输入矩阵A、B和输出矩阵C分解为n/2×n/2的子矩阵。采用下标法只要θ(1)
  • 创建10个n/2×n/2的矩阵,每个矩阵包括第一步创建的两个字矩阵的和或差
  • 用步骤一和步骤2创建的矩阵递归计算7个矩阵积
  • 用7个矩阵的不同组合进行加减,计算出结果
分析
  • T(n) = 7T(n/2) +Θ(n^2)
  • Θ(2.81)

VLSI 问题【超大规模继承电路

有一些电路,假设电路是完全二叉树,想在网格上,放入芯片布局,使在网格上占据最小空间

解决方法
朴素算法
  • 自下向上画
  • H(n) = H(n/2) + Θ(1) Θ(logn)
  • W(n) = W(n/2) + O(1) O(n)
  • 面积是Θ(nlgn)
改进【想法很值得学习

算法远远不止是代码,算法是生活

  • 先通过主方法计算考虑可能的划分子问题

  • 想要的子问题规模是n/4

  • 使用H型布局【tql]】

  • L(n) = 2L(n/4) + Θ(1)

  • 从主方法分析递归式,进而优化布局

  • 面积是Θ(n)

发布了28 篇原创文章 · 获赞 1 · 访问量 1730

猜你喜欢

转载自blog.csdn.net/doordiev/article/details/104281978