王晓东_算法整理
算法设计与分析(王晓东)

a b a b
(2)方法重载:Java允许方法重载,即允许定义有不同签名的同名方法。
上述方法ab可重载为:
public static double ab(double a, double b) { return (a+b+Math.abs(a-b))/2.0; } 12
4.异常
1.3 描述算法
6
1.2 表达算法的抽象机制
2.抽象数据类型
抽象数据类型是算法的一个数据模型连同定义在该模型上 并作为算法构件的一组运算。
抽象数据类型带给算法设计的好处有:
(1)算法顶层设计与底层实现分离; (2)算法设计与数据结构设计隔开,允许数据结构自由选择; (3)数据模型和该模型上的运算统一在ADT中,便于空间和时间耗费的折衷; (4)用抽象数据类型表述的算法具有很好的可维护性; (5)算法自然呈现模块化; (6)为自顶向下逐步求精和模块化提供有效途径和工具; (7)算法结构清晰,层次分明,便于算法正确性的证明和复杂性的分析。
中国计算机学会 “21世纪大学本科计算机专业系列教材”
算法设计与分析
王晓东 编著
1
主要内容介绍
• • • • • • 第1章 第2章 第3章 第4章 第5章 第6章 算法引论 递归与分治策略 动态规划 贪心算法 回溯法 分支限界法
算法设计与分析王晓东

习题2-1 求下列函数的渐进表达式:3n^2+10n; n^2/10+2n; 21+1/n; logn^3; 10 log3^n 。
解答:3n^2+10n=O(n^2),n^2/10+2^n=O(2^n),21+1/n=O(1),logn^3=O(logn),10log3^n=O(n).习题2-3 照渐进阶从低到高的顺序排列以下表达式:n!,4n^2,logn,3^n,20n,2,n^2/3。
解答:照渐进阶从高到低的顺序为:n!、3^n、4n^2 、20n、n^2/3、logn、2习题2-4(1)假设某算法在输入规模为n时的计算时间为T(n)=3*2^n。
在某台计算机上实现并完成该算法的时间为t秒。
现有另外一台计算机,其运行速度为第一台计算机的64倍,那么在这台新机器上用同一算法在t秒内能解输入规模为多大的问题?(2)若上述算法的计算时间改进为T(n)=n^2,其余条件不变,则在新机器上用t秒时间能解输入规模多大的问题?(3)若上述算法的计算时间进一步改进为,其余条件不变,那么在新机器上用t秒时间能解输入规模多大的问题?解答:(1)设能解输入规模为n1的问题,则t=3*2^n=3*2^n/64,解得n1=n+6(2)n1^2=64n^2得到n1=8n(3)由于T(n)=常数,因此算法可解任意规模的问题。
习题2-5 XYZ公司宣称他们最新研制的微处理器运行速度为其竞争对手ABC公司同类产品的100倍。
对于计算复杂性分别为n,n^2,n^3和n!的各算法,若用ABC公司的计算机能在1小时内能解输入规模为n的问题,那么用XYZ公司的计算机在1小时内分别能解输入规模为多大的问题?解答:n'=100nn'^2=100n^2得到n'=10nn'^3=100n^3得到n'=4.64nn'!=100n!得到n'<n+log100=n+6.64习题2-6对于下列各组函数f(n)和g(n),确定f(n)=O(g(n))或f(n)=Ω(g(n))或f(n)=θ(g(n)),并简述理由。
算法设计与分析王晓东

习题2-1 求下列函数的渐进表达式:3n^2+10n; n^2/10+2n; 21+1/n; logn^3; 10 log3^n 。
解答:3n^2+10n=O(n^2),n^2/10+2^n=O(2^n),21+1/n=O(1),logn^3=O(logn),10log3^n=O(n).习题2-3 照渐进阶从低到高的顺序排列以下表达式:n!,4n^2,logn,3^n,20n,2,n^2/3。
解答:照渐进阶从高到低的顺序为:n!、3^n、4n^2 、20n、n^2/3、logn、2习题2-4(1)假设某算法在输入规模为n时的计算时间为T(n)=3*2^n。
在某台计算机上实现并完成该算法的时间为t秒。
现有另外一台计算机,其运行速度为第一台计算机的64倍,那么在这台新机器上用同一算法在t秒内能解输入规模为多大的问题?(2)若上述算法的计算时间改进为T(n)=n^2,其余条件不变,则在新机器上用t秒时间能解输入规模多大的问题?(3)若上述算法的计算时间进一步改进为,其余条件不变,那么在新机器上用t秒时间能解输入规模多大的问题?解答:(1)设能解输入规模为n1的问题,则t=3*2^n=3*2^n/64,解得n1=n+6(2)n1^2=64n^2得到n1=8n(3)由于T(n)=常数,因此算法可解任意规模的问题。
习题2-5 XYZ公司宣称他们最新研制的微处理器运行速度为其竞争对手ABC公司同类产品的100倍。
对于计算复杂性分别为n,n^2,n^3和n!的各算法,若用ABC公司的计算机能在1小时内能解输入规模为n的问题,那么用XYZ公司的计算机在1小时内分别能解输入规模为多大的问题?解答:n'=100nn'^2=100n^2得到n'=10nn'^3=100n^3得到n'=4.64nn'!=100n!得到n'<n+log100=n+6.64习题2-6对于下列各组函数f(n)和g(n),确定f(n)=O(g(n))或f(n)=Ω(g(n))或f(n)=θ(g(n)),并简述理由。
计算机算法设计与分析(王晓东第4版)第8章

Department of Electronic Information
30
Fun Time
z
=
9
+
21x2
−
3 4
x4
−
2x5,
s.t.
x3
−
1 2
x2
+
41x4
=
3
x1 x6
+ −
5 2
x2
5 2
x2
+ −
41x4 43x4
+ +
2x5 = 10 +8x5 = 1
• 选出使目标函数增加的非基本变量作为入基变量 • z 行中的正系数非基本变量都满足要求
Department of Electronic Information
24
单纯形表
max z = −x2 + 3x3 − 2x5,
s.t.
x1
+
3x2
−
x3
+
2x5
=
7
x4 − 2x2 + 4x3 = 12
x2 x3 x5
z 0 -1 3 -2 x1 7 3 -1 2 x4 12 -2 4 0 x6 10 -4 3 8
Department of Electronic Information
23
单纯形算法的第 1 步–选取入基变量
• 查看单纯形表的第 1 行(也称之为 z 行)中标有非 基本变量的各列中的值
2x2 − 7x4 ≤ 0 x1 + x2 + x3 + x4 = 9
x2 − x3 + 2x4 ≥ 1 xi ≥ 0, i = 1, 2, 3, 4
《算法分析与设计》说课

8
8
8
10
S4
贪心算法
6
6
S5
回溯法
6
8
S6
分支限界
6
8
S7
随机化算法 总学时数
4 40
6 48
说课程教学大纲
5、课外学习内容 分支 限界 算法 设计 分治 分治 最强大脑—数独 阶乘 递归 兔子问题 会场安排问题 国王分财产
银行最优服务次序
回溯 法 贪心 贪心 算法 算法
矩阵连乘 租用游艇 排序问题
•难点模块
分治策略
动态规划 贪心算法
•难点内容
分治策略的应用
分解最优解结构 构造递归关系
回溯法
分支限界法
判断是否满足贪心性质
回溯法--剪枝函数 解空间树
说课导航
说课程教学大纲
说教学资源 说教学方法与手段 说学情与学法指导 说教学过程设计
说考核评价
说教学资源
1、教材选用原则
国家级规划教材 原则
具有先进性、适用性、时效性
汽车加油行驶 网球循环赛比赛日程
动态 规划
充分体现案例驱动、实践导向的设计思想
说课程教学大纲
6、课程重点
•重点模块
递归与分治策略
动态规划算法 贪心算法
•重点内容
二分搜索与排序
矩阵连乘 最长公共子序列
回溯法
分支限界法
最大字段和
0-
说课程教学大纲
7、课程难点
经典教材
说教学资源
王晓东教授编著的 《计算机算法设计与分析》 (C++描述)
说教学资源
2、网络资源
课外学习网站:
/JudgeOnline/problemtypelist.php
计算机算法设计与分析(王晓东) 第5章 回溯法

n=3时的0-1背包问题用完全二叉树表示的解空间
5
生成问题状态的基本方法
扩展结点:一个正在产生儿子的结点称为扩展结点 活结点:一个自身已生成但其儿子还没有全部生成的节点称 做活结点 死结点:一个所有儿子已经产生的结点称做死结点 深度优先的问题状态生成法:如果对一个扩展结点R,一旦 产生了它的一个儿子C,就把C当做新的扩展结点。在完成 对子树C(以C为根的子树)的穷尽搜索之后,将R重新变 成扩展结点,继续生成R的下一个儿子(如果存在) 宽度优先的问题状态生成法:在一个扩展结点变成死结点 之前,它一直是扩展结点 回溯法:为了避免生成那些不可能产生最佳解的问题状态, 要不断地利用限界函数(bounding function)来处死那些实际 上不可能产生所需解的活结点,以减少问题的计算量。具 有限界函数的深度优先生成法称为回溯法
}
18
n后问题
在n×n格的棋盘上放置彼此不受攻击的n个皇后。按照国际象 棋的规则,皇后可以攻击与之处在同一行或同一列或同一斜线 上的棋子。n后问题等价于在n×n格的棋盘上放置n个皇后,任 何2个皇后不放在同一行或同一列或同一斜线上。
1 2 3 4 5 6 7 8 Q Q Q Q Q Q Q
void backtrack (int i) {// 搜索第i层结点 if (i > n) // 到达叶结点 更新最优解bestx,bestw; return; r -= w[i]; if (cw + w[i] <= c) {// 搜索左子树 x[i] = 1; cw += w[i]; backtrack(i + 1); cw -= w[i]; } if (cw + r > bestw) { x[i] = 0; // 搜索右子树 backtrack(i + 1); } r += w[i];
计算机算法设计与分析(第4版) 王晓东习题解答

第一章作业1.证明下列Ο、Ω和Θ的性质1)f=Ο(g)当且仅当g=Ω(f)证明:充分性。
若f=Ο(g),则必然存在常数c1>0和n0,使得∀n≥n0,有f≤c1*g(n)。
由于c1≠0,故g(n) ≥ 1/ c1 *f(n),故g=Ω(f)。
必要性。
同理,若g=Ω(f),则必然存在c2>0和n0,使得∀n≥n0,有g(n) ≥ c2 *f(n).由于c2≠0,故f(n) ≤ 1/ c2*f(n),故f=Ο(g)。
2)若f=Θ(g)则g=Θ(f)证明:若f=Θ(g),则必然存在常数c1>0,c2>0和n0,使得∀n≥n0,有c1*g(n) ≤f(n) ≤ c2*g(n)。
由于c1≠0,c2≠0,f(n) ≥c1*g(n)可得g(n) ≤ 1/c1*f(n),同时,f(n) ≤c2*g(n),有g(n) ≥ 1/c2*f(n),即1/c2*f(n) ≤g(n) ≤ 1/c1*f(n),故g=Θ(f)。
3)Ο(f+g)= Ο(max(f,g)),对于Ω和Θ同样成立。
证明:设F(n)= Ο(f+g),则存在c1>0,和n1,使得∀n≥n1,有F(n) ≤ c1 (f(n)+g(n))= c1 f(n) + c1g(n)≤ c1*max{f,g}+ c1*max{f,g}=2 c1*max{f,g}所以,F(n)=Ο(max(f,g)),即Ο(f+g)= Ο(max(f,g))对于Ω和Θ同理证明可以成立。
4)log(n!)= Θ(nlogn)证明:∙由于log(n!)=∑=n i i 1log ≤∑=ni n 1log =nlogn ,所以可得log(n!)= Ο(nlogn)。
∙由于对所有的偶数n 有,log(n!)= ∑=n i i 1log ≥∑=n n i i 2/log ≥∑=nn i n 2/2/log ≥(n/2)log(n/2)=(nlogn)/2-n/2。
当n ≥4,(nlogn)/2-n/2≥(nlogn)/4,故可得∀n ≥4,log(n!) ≥(nlogn)/4,即log(n!)= Ω(nlogn)。
《计算机算法设计与分析》第二版王晓东“最大m字段和优化函数”——P57注释

《计算机算法设计与分析》第二版王晓东“最大m字段和优化函数”——P57注释之所以想到要注释一下,没别的意思,只是因为几个月前刚学DP,完全看不懂,前几天费了几个小时终于看懂了,注释下来,能使自己整理一下思路,也作为自己的一篇日记。
当时我能看懂时间和空间均为O(MN^2)的函数,但可能由于自己看书是直接从动态规划一章看起,书上对于经过优化的函数也没有更多的解析,当时看起来完全不知所云。
前几天看的时候,是对着方程结合书上的几句话自己去理解,尝试自己动手去写,但错了。
看书上代码,都要自己去理解那些变量数组是干什么用的,感觉也是非常吃力。
1,我觉得理解那个优化函数,必须先要充分理解那个二维的DP方程:b[i][j]=max(b[i][j-1]+a[j],max(b[i-1][t])+a[j]) (i-1<=t<j)b[i][j]表示的是第i段在前j项(含第j项)的最大值。
对于b[i][j]含有第j项必须要理解好!则方程的意思是:对于a[j]项,要么将它加到第i段,要么它自己作为新的一段。
注意到方程外层的max选择,都要加上a[j]这一项。
这里可能很容易产生一个疑问,如果a[j]是一个负数,为什么还要加上a[j]呢?回到b[i][j]所表示的意义上解释,由于b[i][j]表示的是含有第j项的最大值,所以a[j]是肯定要加进来的。
假使a[j]是一个负数,它加进来了也不会影响在第i段中前j-1项的最大值。
所以第m段的最大值,并不是b[m][n],而是b[m][m~n]之间的最大值。
同样道理,第i-1段的最大值是b[i-1][t],(i-i<=t<j)。
2,理解了上述的DP方程后,再来考虑优化,正如书上所说的,由于在第i段中,只用到第i段和第i-1段的值。
如果采用一维数组存储b[],只要在计算第i段的时候,没有去改变第i-1段保留下来的值即可。
再考虑到,内层max选择,需要用到第i-1段在i-1到j-1位置的最大值,不但要进行重复计算,也影响到b[j]的计算,因为j前面的值既要用作b[j]的计算,也要更新作为下一段i+1计算时所用。
大学_计算机算法设计与分析第4版(王晓东著)课后答案下载

计算机算法设计与分析第4版(王晓东著)课后答
案下载
计算机算法设计与分析第4版内容简介
第1章算法概述
1.1 算法与程序
1.2 算法复杂性分析
1.3 NP完全性理论
算法分析题1
算法实现题1
第2章递归与分治策略
2.1 递归的概念
2.2 分治法的基本思想
2.3 二分搜索技术
2.4 大整数的乘法
2.5 Strassen矩阵乘法
2.6 棋盘覆盖
2.7 合并排序
2.8 快速排序
2.9 线性时间选择
2.10 最接近点对问题
第3章动态规划
第4章贪心算法
第5章回溯法
第6章分支限界法
第7章随机化算法
第8章线性规划与网络流
附录A C++概要
参考文献
计算机算法设计与分析第4版目录
本书是普通高等教育“十一五”__规划教材和国家精品课程教材。
全书以算法设计策略为知识单元,系统介绍计算机算法的设计方法与分析技巧。
主要内容包括:算法概述、递归与分治策略、动态规划、贪心算法、回溯法、分支限界法、__化算法、线性规划与网络流等。
书中既涉及经典与实用算法及实例分析,又包括算法热点领域追踪。
为突出教材的`可读性和可用性,章首增加了学习要点提示,章末配有难易适度的算法分析题和算法实现题;配套出版了《计算机算法设计与分析习题解答(第2版)》;并免费提供电子课件和教学服务。
算法分析课件 王晓东 第二版

分治法的设计思想是,将一个难以直接解决的大问题, n = T(n) 分割成一些规模较小的相同问题,以便各个击破, 分而治之。 凡治众如治寡,分数是也。 n/2 n/2 n/2 ----孙子兵法 n/2
T(n/4)T(n/4)T(n/4)T(n/4) T(n/4)T(n/4)T(n/4)T(n/4) T(n/4)T(n/4)T(n/4)T(n/4) T(n/4)T(n/4)T(n/4)T(n/4
T(n)
n/2
=
n/2
n
n/2 n/2
T(n/4)T(n/4)T(n/4)T(n/4) T(n/4)T(n/4)T(n/4)T(n/4) T(n/4)T(n/4)T(n/4)T(n/4) T(n/4)T(n/4)T(n/4)T(n/4)
算法总体思想
将求出的小规模的问题的解合并为一个更大规模的问题 的解,自底向上逐步求出原来问题的解。
public static void T (n) 2T (n / 2) O(n) n a[], int left, int right) mergeSort(Comparable 1
}
合并排序
算法mergeSort的递归过程可以消去。
初始序列
[49] [38] [65] [97] [76] [13] [27]
每执行一次算法的 while循环, 待搜索数 组的大小减少一半。因 此,在最坏情况下, while循环被执行了 O(logn) 次。循环体内 运算需要O(1) 时间, 因此整个算法在最坏情 况下的计算时间复杂性 为O(logn) 。
思考题:给定a,用二分法设计出求an的算法。
合并排序
基本思想:将待排序元素分成大小大致相同的2个子集合,分 别对2个子集合进行排序,最终将排好序的子集合合并成为所 要求的排好序的集合。 复杂度分析 O(1) n 1 { T(n)=O(nlogn) 渐进意义下的最优算法 if (left<right) {//至少有2个元素 int i=(left+right)/2; //取中点 mergeSort(a, left, i); mergeSort(a, i+1, right); merge(a, b, left, i, right); //合并到数组b copy(a, b, left, right); //复制回数组a }
计算机算法设计与分析(第5版)第1章

算法渐近复杂性
• T(n) , as n ; • (T(n) - t(n) )/ T(n) 0 ,as n; • t(n)是T(n)的渐近性态,为算法的渐近复杂性。 • 在数学上, t(n)是T(n)的渐近表达式,是T(n)略去低阶
问题求解(Problem Solving)
理解问题 精确解或近似解
选择数据结构 算法设计策略
设计算法 证明正确性
分析算法 设计程序
算法复杂性分析
• 算法复杂性 = 算法所需要的计算机资源 • 算法的时间复杂性T(n); • 算法的空间复杂性S(n)。 • 其中n是问题的规模(输入大小)。
算法的时间复杂性
项留下的主项。它比T(n) 简单。
渐近分析的记号
• 在下面的讨论中,对所有n,f(n) 0,g(n) 0。 • (1)渐近上界记号O • O(g(n)) = { f(n) | 存在正常数c和n0使得对所有n n0有:
0 f(n) cg(n) } • (2)渐近下界记号 • (g(n)) = { f(n) | 存在正常数c和n0使得对所有n n0有:
• (1)最坏情况下的时间复杂性 • Tmax(n) = max{ T(I) | size(I)=n } • (2)最好情况下的时间复杂性 • Tmin(n) = min{ T(I) | size(I)=n } • (3)平均情况下的时间复杂性
• Tavg(n) = p(I )T (I ) size(I )n
•
for x > -1,
x ln(1 x) x 1 x
•
for any a > 0,
Hale Waihona Puke log b nlim
计算机算法设计与分析 王晓东第 版

School of Computer and Communication Engineer
19
Fun Time
考虑如下活动集合 S:
i 1 2 3 4 5 6 7 8 9 10 11 si 1 3 0 5 3 5 6 8 8 2 12 fi 4 5 6 7 9 9 10 11 12 14 16
• 子集 {a3, a9, a11} 为一相容活动集合 • 计算最大相容活动集合?
最优解.
School of Computer and Communication Engineer
14
0/1 背包问题动态规划求解
• 贪心选择无法保证最终能将背包装满, 部分闲置的背 包空间使物品单位重量的价值发生变化
• 应比较选择该物品和不选择该物品所导致的最终方 案, 然后再作出最好选择(重叠子问题)
为了选择最多的相容活动, 每次选择 fi 最小的相容活 动, 即, 使以后可选更多的活动—“贪心(Greedy)”.
School of Computer and Communication Engineer
26
活动选择问题贪心算法
考虑如下活动集合 S: i 1 2 3 4 5 6 7 8 9 10 11 si 1 3 0 5 3 5 6 8 8 2 12 fi 4 5 6 7 9 9 10 11 12 14 16
• 贪心算法: 每一步做出一个选择, 该选择不依赖于子 问题的解
* 一个问题是否具有贪心选择性需要证明
School of Computer and Communication Engineer
7
最优子结构
定义 2. 若一个优化问题的最优解包括它的子问题的最 优解, 则称其具有最优子结构. • 动态规划: 最优子结构, 子问题重叠性 • 贪心算法: 最优子结构, 贪心选择性
算法设计与分析 第1章

例1 f(n) = 2n + 3 = O(n) 当n≥3时,2n+3≤3n,所以,可选c = 3,n0 = 3。对于n≥n0,f(n) = 2n + 3≤3n,所以,f(n) = O(n),即2n + 3O(n)。这意味着,当n≥3 时,例1的程序步不会超过3n,2n + 3 = O(n)。
例2 f(n) = 10n2 + 4n + 2 = O(n2) 对于n≥2时,有10n2 + 4n + 2≤10n2 + 5n,并 且当n≥5时,5n≤n2,因此,可选c = 11, n0 = 5;对于n≥n0,f(n) = 10n2 + 4n + 2≤11n2,所 以f(n) = O(n2)。
算法设计与分析
湖南人文科技学院计算机系 授课:肖敏雷
邮箱:minlei_xiao@
关于本课程
课程目的:计算机算法设计与分析导引
不是一门试验或程序设计课程 也不是一门数学课程
教材:计算机算法设计与分析-王晓东 前导课:数据结构+程序设计 参考资料:
算法设计与分析—C++语言描述 陈慧南编 电子工业出版社 计算机算法基础(第三版) 余祥宣 华中科技大学
渐近时间复杂度 使用大O记号及下面定义的几种渐近表示法 表示的算法时间复杂度,称为算法的渐近时间复 杂度(asymptotic complexity)。 只要适当选择关键操作,算法的渐近时间复 杂度可以由关键操作的执行次数之和来计算。一 般地,关键操作的执行次数与问题的规模有关, 是n的函数。 关键操作通常是位于算法最内层循环的语句。
当 n≥n0 时 , 有 f(n)≥cg(n) , 则 记 做 f(n)=Ω
计算机算法设计与分析(第3版)王晓东__第6章

(2)将剩余的集装箱装上第二艘轮船。
11
6.3 装载问题
2. 队列式分支限界法
在算法的while 循环中,首先检测当前扩展结点的左儿子 结点是否为可行结点。如果是则将其加入到活结点队列中。然 后将其右儿子结点加入到活结点队列中 (右儿子结点一定是可 行结点)。2个儿子结点都产生后,当前扩展结点被舍弃。
6
6.2 单源最短路径问题
1. 问题描述
下图是用优先队列式分支限界法解有向图G的单源最短路径问 题产生的解空间树。其中,每一个结点旁边的数字表示该结点所对 应的当前路长。
7
6.2 单源最短路径问题
2. 算法思想
解单源最短路径问题的优先队列式分支限界法用一极小堆来 存储活结点表。其优先级是结点所对应的当前路长。 算法从图G的源顶点s和空优先队列开始。结点s被扩展后,它 的儿子结点被依次插入堆中。此后,算法从堆中取出具有最小当 前路长的结点作为当前扩展结点,并依次检查与当前扩展结点相 邻的所有顶点。如果从当前扩展结点i到顶点j有边可达,且从源 出发,途经顶点i再到顶点j的所相应的路径的长度小于当前最优 路径长度,则将该顶点作为活结点插入到活结点优先队列中。这 个结点的扩展过程一直继续到活结点优先队列为空时为止。
9
6.2 单源最短路径问题
while (true) { for (int j = 1; j <= n; j++) if ((c[E.i][j]<inf)&&(E.length+c[E.i][j]<dist[j])) { // 顶点i到顶点j可达,且满足控制约束 dist[j]=E.length+c[E.i][j]; 顶点I和j间有边,且此 prev[j]=E.i; 路径长小于原先从原点 // 加入活结点优先队列 到j的路径长 MinHeapNode<Type> N; N.i=j; N.length=dist[j]; H.Insert(N);} try {H.DeleteMin(E);} // 取下一扩展结点 catch (OutOfBounds) {break;} // 优先队列空 } }
计算机算法设计与分析第1章王晓东(第三版)第4章

计算机算法设计与分析第1章王晓东(第三版)第4章第4章贪心算法学习要点理解贪心算法的概念。
掌握贪心算法的基本要素(1)最优子结构性质(2)贪心选择性质理解贪心算法与动态规划算法的差异理解贪心算法的一般理论通过应用范例学习贪心设计策略。
(1)活动安排问题;(2)最优装载问题;(3)哈夫曼编码;(4)单源最短路径;(5)最小生成树;(6)多机调度问题。
顾名思义,贪心算法总是作出在当前看来最好的选择。
也就是说贪心算法并不从整体最优考虑,它所作出的选择只是在某种意义上的局部最优选择。
当然,希望贪心算法得到的最终结果也是整体最优的。
虽然贪心算法不能对所有问题都得到整体最优解,但对许多问题它能产生整体最优解。
如单源最短路经问题,最小生成树问题等。
在一些情况下,即使贪心算法不能得到整体最优解,其最终结果却是最优解的很好近似。
4.1活动安排问题活动安排问题就是要在所给的活动集合中选出最大的相容活动子集合,是可以用贪心算法有效求解的很好例子。
该问题要求高效地安排一系列争用某一公共资源的活动。
贪心算法提供了一个简单、漂亮的方法使得尽可能多的活动能兼容地使用公共资源。
4.1活动安排问题设有n个活动的集合E={1,2,…,n},其中每个活动都要求使用同一资源,如演讲会场等,而在同一时间内只有一个活动能使用这一资源。
每个活动i都有一个要求使用该资源的起始时间i和一个结束时间fi,且i<fi如果选择了活动i,则它在半开时间区间[i,fi)内占用资源。
若区间[i,fi)与区间[j,fj)不相交,则称活动i与活动j是相容的。
也就是说,当i≥fj或j≥fi时,活动i与活动j相容。
4.1活动安排问题下面给出解活动安排问题的贪心算法GreedySelector:template<claType>voidGreedySelector(intn,Type[],Typef[],boolA[]){A[1]=true;intj=1;for(inti=2;i<=n;i++){if([i]>=f[j]){A[i]=true;j=i;}eleA[i]=fale;}}各活动的起始时间和结束时间存储于数组和f中且按结束时间的非减序排列4.1活动安排问题由于输入的活动以其完成时间的非减序排列,所以算法greedySelector每次总是选择具有最早完成时间的相容活动加入集合A中。
计算机算法设计与分析第版王晓东电子优选文档

问题求解(Problem Solving)
理解问题 精确解或近似解
选择数据结构 算法设计策略
设计算法 证明正确性
分析算法 设计程序
算法复杂性分析
• 算法复杂性=算法所需要的计算机资源 • 算法的时间复杂性T(n); • 算法的空间复杂性S(n)。 • 其中n是问题的规模(输入大小)。
算法的时间复杂性
default: statement sequence;
}
(2)迭代语句:
• (2.1) for循环: • for (init;condition;inc) statement; • (2.2) while循环: • while (condition) statement; • (2.3) do-while循环: • do{ • statement; • } while (condition);
(6.3)运算符delete:
• 当动态分配的存储空间已不再需要时应及时释放所占 用的空间。
• 用运算符delete来释放由new分配的空间。 • 例: • delete y; • delete [ ]x; • 分别释放分配给 y的空间和分配给一维数组x的空间。
(3)跳转语句:
• (3.1) return语句: • return expression; • (3.2) goto语句: • goto label; • • label:
(4)函数:
return-type function name(para-list) {
body of the function }
• >0使得对所有n n0有:0 f(n)<cg(n) } 等价于f(n) /g(n) 0,asn 。
•
• (4非紧下界记号) • (g(n)) = {f(n) |对于任何正常数c>0,存在正数和n0
计算机算法设计与分析(王晓东第4版)第4章

23
最优解代价公式
c[i, j ]: Sij 最优解的大小 c[i, j ] = 0 if Sij = φ maxak ∈Sij {c[i, k ] + c[k, j ] + 1} if Sij = φ
School of Computer and Communication Engineer
24
活动选择问题动态规划方法
schoolcommunicationengineer一步一步构建问题的最优解决方案其中每一步只考虑眼前的最佳选择对解空间进行搜索时在局部范围内进行择优选取决定下一步搜索方向不是为了找到全部解而只是找出一种可行解在一定的情况下贪心算法找出的可行解将是最优解schoolcommunicationengineer42贪贪贪心心心算算算法法法基基基本本本要要要素素素算法包含一系列步骤每一步都有一组选择做出在当前看来最好的选择一个贪心算法是否产生最优解需要严格证明schoolcommunicationengineer最优子结构schoolcommunicationengineer贪贪贪心心心选选选择择择性性性质质质定定定义义义若若若一个优化问题的全局最优解可以通过局部最优选择得到则该问题称为具有贪贪贪心心心选选选择择择性性性
School of Computer and Communication Engineer 4
4.2 贪 心 算 法 基 本 要 素
• 算法包含一系列步骤, 每一步都有一组选择, 做出在 当前看来最好的选择 • 希望通过作出局部最优选择达到全局最优选择 • 一个贪心算法是否产生最优解, 需要严格证明
School of Computer and Communication Engineer
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
递归与分治算法1.递归插入排序Void insert_sort(type A[ ],int n){int k;type a;n=n-1;if (n>0){ insert_sort(A,n);a=A[n];k=n-1;while (k>=0)&&A[k]>a)){ A[k+1]=A[k];k=k-1;}A[k+1]=a;}}2.合并排序public static void mergeSort(Comparable a[], int left, int right) {if (left<right) {//至少有2个元素int i=(left+right)/2; //取中点mergeSort(a, left, i);mergeSort(a, i+1, right);merge(a, b, left, i, right); //合并到数组bcopy(a, b, left, right); //复制回数组a}}template <class Type>void merge(Type c[],Type d[],int l,int m,int r){int i = l,j = m + 1,k = l;while((i<=m)&&(j<=r)){if(c[i]<=c[j]){d[k++] = c[i++];}else{d[k++] = c[j++];}}if(i>m){for(int q=j; q<=r; q++){d[k++] = c[q];}}else{for(int q=i; q<=m; q++){d[k++] = c[q];}}}3.快速排序private static void qSort(int p, int r){if (p<r) {int q=partition(a,p,r); //以a[p]为基准元素将a[p:r]划分成3段//a[p:q-1],a[q]和a[q+1:r],使得a[p:q-1]中任何元素小于等于a[q],//a[q+1:r]中任何元素大于等于a[q]。
下标q在划分过程中确定。
qSort (p,q-1); //对左半段排序qSort (q+1,r); //对右半段排序}}int partition (int s[], int l, int r) //返回调整后基准数的位置{int i = l, j = r;int x = s[l]; //s[l]即s[i]就是第一个坑while (i < j){// 从右向左找小于x的数来填s[i]while(i < j && s[j] >= x)j--;if(i < j){s[i] = s[j]; //将s[j]填到s[i]中,s[j]就形成了一个新的坑i++;}// 从左向右找大于或等于x的数来填s[j]while(i < j && s[i] < x)i++;if(i < j){s[j] = s[i]; //将s[i]填到s[j]中,s[i]就形成了一个新的坑j--;}}//退出时,i等于j。
将x填到这个坑中。
s[i] = x;return i;}4.整数划分public static int divide(int n, int m){if(n < 1|| m < 1) {return0;} else if(n == 1|| m == 1) {return1;} else if(n == m) {return1+ divide(n, n - 1);} else if(n < m) {return divide(n, n);} else{return divide(n, m - 1) + divide(n - m, m);}}分治1.最大数最小数Void maxmin(int A[ ], int &e_max, int &e_min, int low, int high)int mid, x1,y1,x2,y2;if ((high-low)<=1) {if (A[high]>A[low]) {e_max=A[high];e_min=A[low];}else {e_max=A[low];e_min=A[high];}}else {mid=(high+low)/2;maxmin(A,x1, y1, low, mid)maxmin(A,x2,y2, mid+1, high);e_max=max(x1,x2);e_min-min(y1,y2);}}2.二进制大整数乘法function MULT(X,Y,n); {X和Y为2个小于2n的整数,返回结果为X和Y的乘积XY}beginS:=SIGN(X)*SIGN(Y); {S为X和Y的符号乘积}X:=ABS(X);Y:=ABS(Y); {X和Y分别取绝对值}if n=1 thenif (X=1)and(Y=1) then return(S)else return(0)else beginA:=X的左边n/2位;B:=X的右边n/2位;C:=Y的左边n/2位;D:=Y的右边n/2位;ml:=MULT(A,C,n/2);m2:=MULT(A-B,D-C,n/2);m3:=MULT(B,D,n/2);S:=S*(m1*2n+(m1+m2+m3)*2n/2+m3);return(S);end;end;3.线性时间选择1.Type select(Type A[], int n, int k){2.int i,j,s,t;3.Type m,*p,*q,*r;4.if(n<38){ // 如果元素个数小于38:则直接排序5.sort(A,A+n);6.return A[k-1];7. }8.p = new Type[3*n/4];9.q = new Type[3*n/4];10.r = new Type[3*n/4];11.for( i=0; i<n/5; i++){ // 五个一组,把每组的中值元素存放进数组p12.mid(A,i,p);13. }14.m = select(p, i, i/2+i%2); // 递归调用,取得中值元素存入m15.i = j = s = 0;16.for( t=0; t<n; i++){ // 按<m、=m、>m把数组分成三组17.if(A[t]<m){18.p[i++] = A[t];19. }else{20.if(A[t]==m){21.q[j++] = A[t];22. }else{23.r[s++] = A[t];24. }25.26. }27. }28.if(i>k){ // 若k<i,则该元素就在数组p中,进入p继续查找29.return select(p,i,k);30. }else{31.if(i+j>=k){ // 若i<k<i+j,则该元素在q数组中,即值为m32.return m;33. }else{ // 若k>i+j,则该元素在r数组中,进入r继续寻找34.return select(r,s,k-i-j);35. }36. }37.}动态规划1.货郎担#include<iostream>#include<iomanip>using namespace std;int n;int cost[20][20]={};bool done[20]={1};int start = 0; //从城市0开始int imin(int num, int cur){if(num==1) //递归调用的出口return cost[cur][start]; //所有节点的最后一个节点,最后返回最后一个节点到起点的路径int mincost = 10000;for(int i=0; i<n; i++){cout<<i<<" i:"<<done[i]<<endl;if(!done[i] && i!=start) //该结点没加入且非起始点{if(mincost <= cost[cur][i]+cost[i][start]){continue; //其作用为结束本次循环。
即跳出循环体中下面尚未执行的语句。
区别于break}done[i] = 1; //递归调用时,防止重复调用int value = cost[cur][i] + imin(num-1, i);if(mincost > value){mincost = value;}done[i] = 0;//本次递归调用完毕,让下次递归调用}}return mincost;}int main(){// cin >> n;n=4;int cc[4][4]={{0 ,4, 1, 3},{4 ,0 ,2, 1},{1 ,2 ,0, 5},{3 ,1, 5, 0}};for(int i=0; i<n; i++){for(int j=0; j<n; j++){//cin >> cost[i][j];cost[i][j]=cc[i][j];}}cout << imin(n, start) << endl;return 0;}2.多段图的最短路径void fgraph(int cost[],int path[],int d[]) {int r,j,temp,min;for(j=0;j<=n;j++)cost[j]=0;for(j=n-1;j>=1;j--){temp=0;min=c[j][temp]+cost[temp];for(r=0;r<=n;r++){if(c[j][r]!=MAX){if((c[j][r]+cost[r])<min){min=c[j][r]+cost[r];temp=r;}}}cost[j]=c[j][temp]+cost[temp];d[j]=temp;}path[1]=1;path[k]=n;for(j=2;j<k;j++)path[j]=d[path[j-1]];}3.最长公共子序列Algorithm lcsLength(x,y,b)m←x.length-1;n←y.length-1;c[i][0]=0; c[0][i]=0;for (int i = 1; i <= m; i++)for (int j = 1; j <= n; j++)if (x[i]==y[j])c[i][j]=c[i-1][j-1]+1;b[i][j]=1;else if (c[i-1][j]>=c[i][j-1])c[i][j]=c[i-1][j];b[i][j]=2;elsec[i][j]=c[i][j-1];b[i][j]=3;构造最长公共子序列Algorithm lcs(int i,int j,char [] x,int [][] b){if (i ==0 || j==0) return;if (b[i][j]== 1){lcs(i-1,j-1,x,b);System.out.print(x[i]);}else if (b[i][j]== 2) lcs(i-1,j,x,b);else lcs(i,j-1,x,b);}4.0-1背包问题动态规划法O(nc)m(i,j)是背包容量为j,可选择物品为i,i+1,…,n时0-1背包问题的最优值。