算法分析设计部分知识点期末复习
第一章 算法概述
1.什么是算法
“PCP问题”没有算法([S])
“3n+1问题”目前不知道有没有算法
有些问题被解决了 (找最大数)有些问题没有被解决 (3n+1问题)有些问题没有解决方案 (PCP问题)
当需证某问题无算法时, 仅有直观定义不够, 需要给算法严格定义
我们将在计算理论中通过图灵机严格定义算法。
2.算法的复杂性分析 🔴
- 复杂度的度量:
要素: 输入, 时间, 空间
时间和空间复杂度, T(N,I,A) 规模, 输入, 算法
T(N,I,A) 简化为 T(N,I)
希望进一步将形式简化为T(N)?
最坏时间复杂度, 平均时间复杂度
输入有很多不同形式:数列, 图, 大数等?所以需要约定输入规模的度量
实测?系统不同,缓存大小不同等诸多影响因素
理论计算: 需要约定计数哪些步
- 找最大数问题
记录当前最大数,当前数跟当前最大数比较即可
以比较次数计算时间复杂度比较合理
时间复杂度: T(N) = N-1
- 找最大次大数问题
方法一
记录当前最大数和次大数,当前数成为最大数,只需比较一次,否则需比较两次
对所有规模N输入, N-1 <= T(N,I) <= 2(N-2)+1=2N-3
方法二:分治
方法三:(Manber)【算法引论】
复杂度小结:
T(N)
- 合理指定输入规模指标
- 合理指定复杂度计量指标
- 最坏情况, 所有规模N输入的最大耗费
- 可改进
什么是高效的算法?
运行速度和占用空间可以用来度量效率
时间复杂度的分析技巧
直接估计、递推关系
提高估计精细程度
均摊分析([C])
累计法
记账法,势能法
复杂度f(n)的渐近记法
称g(n)是f(n)的渐进上界, 即f(n) = O(g(n)), 若 c>0, N>0, n>N, f(n) c g(n) 例: n2+10000n = O(n3), n2+10000n = O(n2)
称g(n)是f(n)的渐进下界, 即f(n) = (g(n)), 若 c>0, N>0, n>N, f(n) c g(n)例: n2+10000n = (n), n2+10000n = (n2)
f(n) = (g(n)) 渐近同阶 ([王], [C]), 若 f(n) = O(g(n)) 且 f(n) = (g(n)) 例: n2+10000n = (n2)
注: n>0, n2 n2+10000n 10001n2.
3.P问题与NP完全问题
可能用到的符号和公式
第二章 递归与分治
1. 递归函数
递归算法: 直接或间接地调用自身的算法
递归函数: 用函数自身给出定义的函数
边界条件与递归方程是递归函数的两要素
保障在有限次计算后得出结果
Ackerman函数A(n): 增长很快
Ackerman函数的反函数: 增长很慢
2. 分治原理, 主定理, 二分法
- 分治基本过程:
分: 将问题分解成若干个子问题
治: 递归求解子问题
合:由子问题解合并得到原问题解 - 分治原则
子问题相互独立(为什么), 无重复 ==
若有大量重复子问题, 改用动态规划==
子问题规模(n/b)大致相等(平衡思想)
子问题和原问题类似, 可递归求解
子问题解合并能得到原问题解
设分解出的子问题有a 个, 时间复杂度T(n),分解+合并时间f(n) :
分治主定理
二分法
3. 大整数乘法
1952, Kolmogorov猜两n位整数相乘时间耗费为Ω(n2)
1960, Kolmogorov在一个讨论班上提出这个猜测
一周后23岁的Karatsuba给出O(nlog3)算法
**Karatsuba算法:**
>Mt(X,Y,n)
>1. 若 n=1, 则 返回 X*Y
>2. 分解 X=[A,B],Y=[C,D], k=n/2
>3. 计算 a=Mt(A,C,k), d=Mt(B,D,k), c=Mt(A->B,C-D,k)
>4. 返回 a2n+(a+d-c)2k+d
计算过程:
矩阵乘法
4. 排序算法
冒泡排序, 插入排序: Θ(n2)
堆排序 Θ(nlogn) (后面章节)
合并(归并)排序: Θ(nlogn) 分少, 合多; 额外空间和复制.
快速排序: 最坏 Θ(n2) 平均 Θ(nlogn), 分多合少比简
通过比较进行排序的算法为 Ω(nlogn).
快速排序:
1.划分部分Partition();(随机分解)
1. i=Ramdom(p,r) //在p:r中随机选择一个数i
2. 交换 a[i] 与 a[p] //将a[i]换到左端点
3. 执行Partition(a,p,r)
2.排序部分QuickSort();
QuickSort(a, p, r) //排序a[p:r]
{ middle=RamdomizePartition(a,p,r);
QuickSort(a, p, middle-1); //排序a[p:middle-1]
QuickSort(a, middle+1, r); //排序a[middle+1,r]
}
分解和分治时间多, 合并不需要时间
时间复杂度:
使用随机分解的快速排序([M,C]),其平均时间复杂度是 T(n) = O( nlogn )
5. 线性时间选择
- 最小问题:
比较次数是n-1次,达到问题的下界,因此它是最优算法- 求第二小元素
一般情况下2n-3次比较
第2小元素一定存在于同最小元素比较过的元素之中
- 找第k小数问题
方法一: 先排序, 再找第k小的数. O(nlogn)时间.
分析: 若k=1, 则直接找最小, O(n)时间.
若k<n/logn, 先建最小堆, O(n)时间([M]p100).再弹出k个元素, O( k logn )
方法二: 使用快速排序方法, 最多对一段继续分解 ,最坏时间O(n2), 平均时间O(n) ([C])
方法三: 改进, 最坏O(n)时间算法([王,C]) —线性时间选择
随机选择: 随机选基准, 划分, 继续随机选择
通过修改基准, 设计新的选择算法Select:
- 将n个数划分成n/5组, 取出每组中位数(共不超过n/5个),
- 使用Select找这n/5个数的中位数
- 以这个数为基准划分
- 选一个部分继续执行Select
假设所有数互不相同
当n充分大, 至少有1/4的数<新基准, 1/4的数>新基准
6. 最接近点对问题
7fg ,.,