分治法
- 以下为本人整理课程笔记
- 课程地址:b站搬运
- github:还有除了算法导论外一些基础知识的笔记
步骤
- 分解,将问题划分成一些子问题,子问题的形式与原问题一样,只是规模更小
- 解决,递归的解决每个子问题
- 合并,将子问题的解组合成原问题的解
例子
归并排序
- 分解:将数组一分为二
- 解决:递归处理每一个子数组
- 合并:将排序好的子数组进行合并
分析其递归式
- 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次方
- 要考虑n如果是奇数
- 解决:递归处理
- 合并:相乘
斐波那契数列:
f(n) = f(n-1) + f(n-2) n>1
解决办法
自下而上处理
- 从f_0、f_1、…计算到f_n
- 只需要线性的时间
朴素平方递归
- 使用数列性质 f_n = ()_n/根号5 理论机器->现有条件下无法
平方递归方法
- 利用定理
- Θ(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)