设计技术作为问题求解的一般性策略
目录
1. 绪论
2. 算法效率分析基础
3. 蛮力法
4. 减治法
5. 分治法
6. 变治法
7. 时空权衡
8. 动态规划
9. 贪婪技术
10. 迭代改进
11. 算法能力的极限
12. 超越算法能力的极限
13. 附录A 算法分析的实用公式
14. 附录B 递推关系简明指南
15. 参考文献
习题1.2-1
农夫A 狼B 羊C 白菜D
1. AC go: BD/AC
2. A back: ABD/C
3. AD go: B/ACD
4. AC back: ABC/D
5. AB go: C/ABD
6. A back: AC/BD
7. AC go: /ABCD
8. finish
习题1.2-2
甲 A 1、乙 B 2、丙 C 5、丁 D 10
1. AB go: CD/AB 2
2. A back: ACD/B 3
3. CD go: A/BCD 13
4. B back: AB/CD 15
5. AB go: /ABCD 17
6. finish
习题1.2-3
a
习题1.2-4
if b^2-4ac>0:
x1 = [-b+sqrt(b^2-4ac)]/2a
x2 = [-b+sqrt(b^2-4ac)]/2a
else if b^2-4ac==0:
x = [-b+sqrt(b^2-4ac)]/2a
else if b^2-4ac<0:
print("no solution")
习题1.2-5
array M =[]
C=1
while C != 0:
B=A/2
C=A%2
M.unshift(M)
return M
习题1.2-6
1. 读卡
2. 输入密码,如果输入密码与原始密码不正确,退出
3. 输入金额,如果输入金额超过卡中余额,退出
4. 提取现金输出
习题1.2-7
a 不能
习题1.2-8
排列算法:快排、归并 nlog(n)
习题1.2-9
MinDistance(A[0…n-1])
//输入:数字数组A[0…n-1]
//输出:数组中两个大小相差最少得元素得差值
dmin⬅∞
B⬅[]
kuaipai(A)
for j⬅0 to n-2 do
D = A[j+1]-A[j]
if D < dmin
dmin = D
return dmin
习题1.2-10
乔治·波利亚 《怎样解题:数学思维得新方法》
怎样解题
第一步:弄清问题
1.未知数是什么?已知数据是什么?条件是什么?满足条件是否可能?要确定未知数,条件是否充分?或者它是否不充分?或者是多余的?或者是矛盾的?
2.画张图,并引入适当的符号。
3.把条件的各部分分开,并把它们写下来。
第二步:拟订计划
1.考虑以前是否见过它? 是否见过相同的问题而形式稍有不同? 你是否知道一个可能用得上的定理?
2.考虑具有相同未知数或相似未知数的熟悉的问题。
3.能否利用它的结果或方法?为了利用它,是否引入某些辅助元素?
4.能否用不同的方法重新叙述它?
5.回到定义去。
6.如果你不能解决所提出的问题,可先解决一个与此有关的问题。
7.是否利用了所有的已知数据?是否利用了所有条件?是否考虑了包含在问题中的所有必要的概念?
第三步:实现计划
1.实现你的求解计划,检验每一步骤。
2.你能否清楚地看出这一步骤是正确的?你能否证明这一步骤是正确的? (www.fwsir.com)你能否说出你所写的每一步的理由?.
第四步:回顾
1. 能否检验这个论证?
2. 你能否用别的方法导出结果?
3. 能不能一下子看出它来?
4.能不能把这结果或方法用于其他问题?
排列问题:
1 是否稳定(相等元素排列后顺序不变)
2 是否在位(不需要额外储存空间)
查找问题:
对于查找、添加和删除的特大型数据集合来说,如何组织其结构是一个不同寻常的挑战,而这对实际应用具有非常重要的意义
字符串处理:
字符串匹配问题
图问题:
基本的图算法包括图的遍历算法(如何能一次访问到网络中的所有节点)、最短路线算法(两个城市之间的最佳路线是哪条?)以及有向图的拓扑排列(一系列课程的预备课程是相互一致的,还是相互矛盾的?)
旅行商问题、图填色问题
组合问题:
从更抽象的角度来看,旅行商问题和图填色问题都是组合问题的特例。有一些问题要求(明确地或者隐含地)寻找一个组合对象,例如一个排列、一个组合或者一个子集,这些对象能够满足特定的条件并具有我们想要的特性,如价值最大化或成本最小化。
计算领域最难的问题,原因第一:通常随着问题规模的增大,组合对象的数量增长极快,即使是中等规模的实例,其组合的规模也会达到不可思议的数量级。第二:还没有一种已知 算法能在可接受的时间内,精确地解决绝大多数这类问题。
几何问题:
如今的几何问题有:计算机图形学、机器人技术和断层X摄影技术等
最近对问题:求的是给定平面上的n个点中,距离最近的两个点
凸包问题:要求找一个能把给定集合中所有点都包含再里面的最小凸多边形
数值问题:
解决连续性数学问题,工程与科学中的重要角色。
习题1.3-1
a 应用代码
//js代码
A = [60,35,81,98,14,47];
function Comparision(A){
let Count = [];
let length = A.length;
let S=[];
for(let i = 0; i < length-1; i++){
Count[i]=0
}
for(let i = 0; i < length-2; i++){
for(let j = i+1; j < length-1; j++){
if(A[i]1;
}else{
Count[i]=Count[i]+1;
}
}
}
for(let i = 0; i < length-1; i++){
S[Count[i]]=A[i];
}
return S;
}
Comparision(A);
b 算法稳定 c 不在位
习题1.3-2
顺序查找 二次查找
习题1.3-3
字符串匹配
1. 先将匹配规则拆分,如:“CAT”拆成[‘C’,’A’,’T’]
2. 先顺序查找C
3. 找到后在此处往后依次对应A,T,如果对应,则记录C的位置;如不对应继续从C的下一位继续查找C;
4. 直至C查找结束
习题1.3-4
七桥问题
a 各位置的联通路径各为 3 5 3 3 只有在仅有两个奇数时才可一次走通;仅在没奇数时可一次走通回到原点;
b 2座桥
习题1.3-5
这个随便走
习题1.3-6
构建一个图模型,每个点代表站点,每条边代表所用时间/距离/所耗费的路费,遍历寻找最优路径
习题1.3-7
瞎写的,不会了
a 寻找一个路径组合,相邻路径相互连通,且从初始点联通到终点,组合之和路径最小
b 寻找一个颜色组合使得相邻色块颜色不同且颜色数量最少
习题1.3-8
a 我是逐个填色,这问题只有遍历解吧
a 1 、b 2 、c 3 、e 2 、d 1 、f 4
b
4种
习题1.3-9
首先任取三点,计算出圆心,计算其他点同圆心距离,如果等于半径那就是在同一圆周线上
习题1.3-10
可以先解两个直线方程交点,然后判断交点是否在两个线段上
AB
(y2-y1)x+(x1-x2)y+x2y1-x1y2=0
CD
(y4-y3)x+(x3-x4)y+x4y3-x3y4=0
解得 E(x,y)
E判断是否在两个线段上
(重点要考虑平行、精度问题)
另一种两步法:
1. 快速排斥实验
2. 跨立实验
两种最重要的基本数据结构是:数组、链表;基本操作:元素的查找、插入和删除;
列表包括:栈、队列、优先队列;
通俗的说,图可以看作平面上的“顶点”或者“节点”构成的集合,某些顶点被称为“边”或者“弧”的线段连接。图G = < V,E >由两个集合定义,顶点V 边E;
1. 图的表示方法:邻接矩阵、邻接链表;
2. 加权图:权重矩阵;
3. 路径与环:连通性(如果对于图中的每一对顶点u和v,都有一条从u到v 的路径,我们说该图是连通的)、无环性(不包括回路的图称为无环图);
自由树就是连通无回路图;无回路但不一定连通的图称为森林;树的边数总比它的顶点数少1;
1. 有根树!
状态空间树强调两种重要的算法技术:回溯和分支界限。
2. 有序树
有序树是一棵有根树,树中每一顶点的所有子女都是有序的;
集合:它是互不相同项的无序组合(可以为空),这些项被称为集合的元素。
抽象数据类型(ADT):由一个表示数据项的抽象对象集合和一系列对这些对象所做的操作构成,类
习题-
2.1 通用框架 2.2 三种符号 2.3 非递归算法分析 2.4 递归算法分析 2.5、2.6和2.7 经验分析和算法可视化
时间复杂度、空间复杂度
1. 输入规模的度量
2. 运行时间的度量单位
统计基本操作的时间;基本操作:通常是算法最内层循环中最费时的操作;
算法分析框架:对于输入的规模为n的算法,我们可以统计它的基本操作执行次数。
3. 增长次数
对于n的较大者来说,有意义的是其函数的增长次数
对于
4. 算法的最优、最差和平均效率
最优效率、最差效率、平均效率
摊销效率
5. 分析框架概要
算法的时间效率和空间效率都用输入规模的函数进行度量;
我们用算法基本操作的执行次数来度量算法的时间效率。通过计算算法消耗的额外储存单元的数量来度量空间效率;
在输入规模相同的情况下,有些算法的效率会有明显的差异。对于这样的算法,我们需要区分最差效率、平均效率和最优效率;本框架主要关心得一点:当算法得输入规模趋向于无限大时,它的运行时间(消耗的额外空间)函数的增长次数;
2.1 习题-
O(g(n)):是增长次数小于等于g(n)(及其常数倍,n趋向于无穷大)的函数集合。
Ω(g(n)):代表增长次数大于等于g(n)(及其常数倍,n趋向于无穷大)的函数集合。
Θ(g(n)):是增长次数等于g(n)(及其常数倍,n趋向于无穷大)的函数集合。
2.2 习题-
分析非递归算法效率的通用方案
(1)决定用哪个(那些)参数表示输入规模
(2)找出算法的基本操作(作为一个规律,它总是位于算法的最内层循环中)。
(3)检查基本操作的执行次数是否只依赖于输入规模。如果它还依赖于一些其他的特性,则最差效率、平均效率以及最优效率(如有必要)需要分别研究。
(4)建立一个算法基本操作执行次数的求和表达式。
(5)利用求和运算的标准公式和法则来建立一个操作次数的闭合公式,或者至少确定它的增长次数。
2.3习题-
分析递归算法时间效率的通用方案
(1)决定用哪个参数作为输入规模的度量标准。
(2)找出算法的基本操作
(3)检查一下,对于相同规模的不同输入,基本操作的执行次数是否可能不同。如果有这种可能,则必须对最差效率、平均效率以及最优效率做单独研究
(4)对于算法基本操作的执行次数,建立一个递归关系以及相应的初始条件
(5)解这个递推式,或者至少确定它的解的增长次数
2.4习题-
二阶常系数线性递推式!
ax(n)+bx(n-1)+cx(n-2)=0
F(n)=1/sqrt(5)*(m^n-(1/m)^n); m=(1+sqrt(5))/2
对算法效率做经验分析的通用方案
(1)了解实验目的
(2)决定用来度量效率的度量标准M和度量单位(操作次数还是直接用时间)
(3)决定输入样本的特性(它的范围和大小等)
(4)为实验准备算法(或者若干算法)的程序实现
(5)生成输入样本
(6)对输入样本运行算法(或者若干算法),并记录观察到的实验数据
(7)分析获得的实验数据
常常涉及到生产伪随机数;
数学分析和经验分析的基本区别。数学分析的主要优势是它并不依赖于特定的输入,但它的主要缺点是适应性不强,这一点对于研究平均效率来说尤其明显。经验分析的主要优点是它能够用于任何算法,但它的结论依赖于实验中使用的特定样本实例和计算机。
2.6习题-
静态算法可视化和动态算法可视化
3.1习题
1. a. 归并排列 b. 背包问题
2. a. O(n) O(2^(bit(n)) b. 先找到a^m>m,a^m mod m; 然后根据n与m的倍数,求a^n mod m
3. 待答
4.
a.
输入a[a0,a1,…,an], n, x0
i=0;
p=0;
for i to n:
v=a[i]
for j=0 to i:
v = v*x0
p=p+v
输出p
O(n^2)
b.
输入a[a0,a1,…,an], n, x0
p=0
xn=1/x0
for i=0 to n:
v=a[i]
xn = xn*x0
v = v*xn
p=p+v
输出p
不能,因为有n个系数要乘
5. 能
i=1,j=1
all_line = true
one_line = false
for i to n:
one_line_mark = true
for j to n:
if A[i,j] == 0:
all_line = false
one_line_mark = false
if one_line_mark == true:
one_line = true
O(n^2)
6. abcd
7. 如果可以放在一起称 O(log(n)) 二分法, log(n);不能就是O(n), 1次
8.
EXAMPLE
AXEMPLE
AEXMPLE
AEEMPLX
AEELPMX
AEELMPX
9. 稳定
10. 能
11.
EXAMPLE
EAXMPLE
EAMXPLE
EAMPXLE
EAMPLXE
EAMPLEX
AEMPLEX
AEMLPEX
AEMLEPX
AELMEPX
AELEMPX
AEELMPX
12. 有列表ABCDEFG,如果冒泡一遍后没有交换位置说明: A
3.2习题
1. a. n+1 b. p(n+1)/2+(1-p)(n+1)
2.
最近对
n(n-1)
凸包问题
凸集合:对于平面上的一个点集合(有限的或无限的),如果以集合中任意两点p和q为端点的线段都属于该集合,我们说这个集合是凸的。
凸包:直观地来讲,对于平面上n个点的集合,它的凸包就是包含所有这些点(或者在内部、或者在边界上)的最小凸多边形。
凸包问题:是为一个有n个点的集合构造凸包的问题。
单纯形法、线性规划
(n-2)*n(n-1)/2
3.3习题-