第四讲分治策略PPT课件
合集下载
分治法 “分”而治之.ppt
第4章 分治法
—— “分”而治之
2020-6-17
谢谢阅读
1
主要内容
1. 一般方法 2. 二分检索 3. 找最大和最小元素 4. 归并分类 5. 快速分类 6. 选择问题 7. 斯特拉森矩阵乘法
2020-6-17
谢谢阅读
2
3.1 一般方法
❖ 对大规模问题的求解 ❖ 利用分治法求解大规模问题
1.基本思想 分而治之方法与软件设计的模块化方法非常相似。
11
分治求解策略分析:
❖ 定义问题的形式描述:I=(n, a1, a2, …,an,x) ❖ 问题分解:选取下标k,由此将I分解为3个子问题:
I1=(k-1, a1, a2, …,ak-1,x) I2=(1, ak,x) I3=(n-k, ak+1, ak+2, …,an,x) ➢ 对于I2,若ak=x,则有解k,对I1、I3不用再求解;否则, ➢ 若x<ak,则只在I1中求解,对I3不用求解; ➢ 若x>ak,则只在I3中求解,对I1不用求解;
mid ←(low high)/2
qk
a2
...
ak
子结果 A
合并
通常,子问题与原始问题“同质”
2020-6-17
谢谢阅读
4
例1 [找伪币] 假设16 枚金币中有一枚是伪造的,真假金
币的区别仅是重量不同,利用一个没有砝码的天平作工具, 找出这枚伪造的金币。
例2 [金块问题]有一个老板有一袋金块。每个月将有两
名雇员会因其优异的表现分别被奖励一个金块。按规矩, 排第一的雇员将得到袋中最重的金块,排名第二的雇员 将得到袋中最轻的金块。根据这种方式,除非有新金块 快加入袋中,否则第一名雇员所得到的金块总是比第二 名雇员所得到的金块重,如果有新的金块周期性的加入 袋中,则每个月都必须找出最重和最轻的金块。假设有 一台比较重量的仪器,希望用最少的比较次数找出最重 和最轻的金块。
—— “分”而治之
2020-6-17
谢谢阅读
1
主要内容
1. 一般方法 2. 二分检索 3. 找最大和最小元素 4. 归并分类 5. 快速分类 6. 选择问题 7. 斯特拉森矩阵乘法
2020-6-17
谢谢阅读
2
3.1 一般方法
❖ 对大规模问题的求解 ❖ 利用分治法求解大规模问题
1.基本思想 分而治之方法与软件设计的模块化方法非常相似。
11
分治求解策略分析:
❖ 定义问题的形式描述:I=(n, a1, a2, …,an,x) ❖ 问题分解:选取下标k,由此将I分解为3个子问题:
I1=(k-1, a1, a2, …,ak-1,x) I2=(1, ak,x) I3=(n-k, ak+1, ak+2, …,an,x) ➢ 对于I2,若ak=x,则有解k,对I1、I3不用再求解;否则, ➢ 若x<ak,则只在I1中求解,对I3不用求解; ➢ 若x>ak,则只在I3中求解,对I1不用求解;
mid ←(low high)/2
qk
a2
...
ak
子结果 A
合并
通常,子问题与原始问题“同质”
2020-6-17
谢谢阅读
4
例1 [找伪币] 假设16 枚金币中有一枚是伪造的,真假金
币的区别仅是重量不同,利用一个没有砝码的天平作工具, 找出这枚伪造的金币。
例2 [金块问题]有一个老板有一袋金块。每个月将有两
名雇员会因其优异的表现分别被奖励一个金块。按规矩, 排第一的雇员将得到袋中最重的金块,排名第二的雇员 将得到袋中最轻的金块。根据这种方式,除非有新金块 快加入袋中,否则第一名雇员所得到的金块总是比第二 名雇员所得到的金块重,如果有新的金块周期性的加入 袋中,则每个月都必须找出最重和最轻的金块。假设有 一台比较重量的仪器,希望用最少的比较次数找出最重 和最轻的金块。
2023年高中信息技术教学课件 分治算法 PPT
• 其中L_ans,R_ans是与计算ans相同类型的子问题, 递归计算即可。主要考虑(i,j)分立两侧的逆序对数 C_ans:
• 结论:对两半段的数分别排序, (i 在左半段,j 在右 半段,排在不同位置不影响先后关系) ,C_ans 不变
• 例如:对于A=[3 2 5 1 4],分成两段A1 = [3 2 5], A2 = [1 4],对A1 和A2 进行排序,A’ = [2 3 5 1 4], C_ans 仍 然为4(3>1,2>1, 5>1, 5>4)
• 此时把原问题分解成4个结构与原问题一样的子问题, 棋盘的大小(边长)每次减半,最终会出现边长为1的 情况,直接求解即可。
经典问题1—棋盘覆盖
• 定义cover(x,y,len,x0,y0)表示求解左上角格子在(x,y)边长为len,其中(x0,y0)不能 覆盖的棋盘覆盖方案。
• 根据黑色格子的位置分为以下四种情况: • 情况1:黑点位于左上部分
• 考虑第一段中两个数A[i],A[j],如果i<j,则A[i] 肯定 比A[j] 要早出现
• 策略:比较两个序列最小的数, 谁小谁在前; 重复比 较直到没有数为止。时间复杂度为O(n)。
1356
2478
12
3
456
7
8
经典问题2—归并排序—代码
• void merge(l,m,r)// 合并操作
=4*(2*F(n’/8)+n’/4)+2*n’=8*F(n’/8)+3*n’ =……=2^k*F(1)+k*n’=2^k+k*2^k=n’+n’*lgn’ • 设n’<=n<2*n’,则有F(n’)<=F(n)<F(2*n’) • n’+n’lgn’<=F(n)<=2*n’+2*n’*lg(2*n’) • n’+n’lgn’<=F(n)<=2*n’+2*n’*lg2+2*n’*lgn’ • 所以F(n)=O(nlgn)。
• 结论:对两半段的数分别排序, (i 在左半段,j 在右 半段,排在不同位置不影响先后关系) ,C_ans 不变
• 例如:对于A=[3 2 5 1 4],分成两段A1 = [3 2 5], A2 = [1 4],对A1 和A2 进行排序,A’ = [2 3 5 1 4], C_ans 仍 然为4(3>1,2>1, 5>1, 5>4)
• 此时把原问题分解成4个结构与原问题一样的子问题, 棋盘的大小(边长)每次减半,最终会出现边长为1的 情况,直接求解即可。
经典问题1—棋盘覆盖
• 定义cover(x,y,len,x0,y0)表示求解左上角格子在(x,y)边长为len,其中(x0,y0)不能 覆盖的棋盘覆盖方案。
• 根据黑色格子的位置分为以下四种情况: • 情况1:黑点位于左上部分
• 考虑第一段中两个数A[i],A[j],如果i<j,则A[i] 肯定 比A[j] 要早出现
• 策略:比较两个序列最小的数, 谁小谁在前; 重复比 较直到没有数为止。时间复杂度为O(n)。
1356
2478
12
3
456
7
8
经典问题2—归并排序—代码
• void merge(l,m,r)// 合并操作
=4*(2*F(n’/8)+n’/4)+2*n’=8*F(n’/8)+3*n’ =……=2^k*F(1)+k*n’=2^k+k*2^k=n’+n’*lgn’ • 设n’<=n<2*n’,则有F(n’)<=F(n)<F(2*n’) • n’+n’lgn’<=F(n)<=2*n’+2*n’*lg(2*n’) • n’+n’lgn’<=F(n)<=2*n’+2*n’*lg2+2*n’*lgn’ • 所以F(n)=O(nlgn)。
《分治策略》课件
分治策略的原理
总结词
分治策略的原理是将问题分解为若干个较小的子问题,解决 这些子问题,然后将子问题的解决方案组合起来,形成对整 个问题的解决方案。
详细描述
分治策略的核心是将问题分解为若干个子问题,这些子问题 应该尽可能地简单、独立,并且能够被有效地解决。解决这 些子问题后,将它们的解决方案组合起来,形成对整个问题 的解决方案。
项目管理
在项目管理中,分治策略有助于将一个复杂的项目分解为多个子项目,分别进行管理和推 进,提高项目的管理效率。
决策分析
在决策分析中,分治策略有助于将一个复杂的问题分解为多个子问题,分别进行评估和决 策,提高决策的科学性和准确性。
问题解决
在日常生活中,分治策略有助于将一个复杂的问题分解为多个小问题,逐一解决,最终找 到问题的解决方案。例如,在解决家庭纠纷、组织活动等场景中都可以运用分治策略。
THANKS。
高解决问题的速度。
简化问题
将复杂问题分解为更小、更易 于处理的部分,有助于理解和
解决每个子问题。
资源优化
分治策略可以更有效地分配资 源,例如计算资源和人力资源 ,从而提高资源利用效率。
提高准确性
通过分别解决子问题,可以减 少全局解决方案中的错误和误
差。
分治策略的缺点
数据传输成本
合并子问题的复杂性
在解决分治问题时,子问题之间可能需要 进行大量数据传输和通信,这可能导致额 外的计算和通信开销。
问题的目的。
组合数学
在组合数学中,分治策略常用于 解决一些与排列、组合、概率等 相关的问题。通过将问题分解为 多个子问题,简化问题的难度,
从而找到解决方案。
几何学
在几何学中,分治策略常用于解 决一些与面积、体积、最值等相 关的问题。通过将大问题分解为 小问题,逐一解决,最终找到问
算法-分治法演示课件
//对应情况①,递归求解 rightsum=MaxSum(a, center+1, right);
//对应情况②,递归求解
2020/6/28
30
s1=0; lefts=0;
//以下对应情况③,先求解s1
for (i=center; i>=left; i--)
{
lefts+=a[i];
if (lefts>s1) s1=lefts;
}
s2=0; rights=0;
//再求解s2
for (j=center+1; j<=right; j++)
{
rights+=a[j];
if (rights>s2) s2=rights;
}
sum=s1+s2;
//计算情况③的最大子段和
if (sum<leftsum) sum=leftsum;
//合并,在sum、leftsum和rightsum中取较大者
2020/6/28
15
[ r1 … … ri-1 ] ri [ ri+1 … … rn ] 均≤ri 轴值 均≥ri 位于最终位置
❖归并排序按照记录在序列中的位置对序列进行划分, ❖快速排序按照记录的值对序列进行划分。
2020/6/28
16
以第一个记录作为轴值,对待排序序列进行划分的过程为: (1)初始化:取第一个记录作为基准,设置两个参数i,j;
2020/6/28
13
算法4.4——合并有序子序列
void Merge(int r[ ], int r1[ ], int s, int m, int t) {
i=s; j=m+1; k=s; while (i<=m && j<=t) {
//对应情况②,递归求解
2020/6/28
30
s1=0; lefts=0;
//以下对应情况③,先求解s1
for (i=center; i>=left; i--)
{
lefts+=a[i];
if (lefts>s1) s1=lefts;
}
s2=0; rights=0;
//再求解s2
for (j=center+1; j<=right; j++)
{
rights+=a[j];
if (rights>s2) s2=rights;
}
sum=s1+s2;
//计算情况③的最大子段和
if (sum<leftsum) sum=leftsum;
//合并,在sum、leftsum和rightsum中取较大者
2020/6/28
15
[ r1 … … ri-1 ] ri [ ri+1 … … rn ] 均≤ri 轴值 均≥ri 位于最终位置
❖归并排序按照记录在序列中的位置对序列进行划分, ❖快速排序按照记录的值对序列进行划分。
2020/6/28
16
以第一个记录作为轴值,对待排序序列进行划分的过程为: (1)初始化:取第一个记录作为基准,设置两个参数i,j;
2020/6/28
13
算法4.4——合并有序子序列
void Merge(int r[ ], int r1[ ], int s, int m, int t) {
i=s; j=m+1; k=s; while (i<=m && j<=t) {
算法设计与分析-第四章1-常用算法策略迭代蛮力分治PPT课件
.
4
数学建模:y1=y2=1,yn=yn-1+yn-2,n=3,4,5,……。
算法1:
main( ) { int i,a=1,b=1;
print(a,b); for(i=1;i<=10;i++)
{ c=a+b; print (c); a=b; b=c;
} }
.
5
算法2:
表4-1 递推迭代表达式
12 3
.
21
【例2】牛顿迭代法 牛顿迭代法又称为切线法,它比一般的迭代法有更高的收敛速度,如图 4-5所示。首先, 选择一个接近函数f(x)零点的x0, 计算相应的f(x0)和 切线斜率f‘(x0)(这里f ’表示函数f的导数)。然后我们计算穿过点 (x0,f (x0))且斜率为f ‘(x0)的直线方程为:
{a[1]=a[i]=1; for (j=i-1,j>1,j=j-1) a[j]=a[j]+a[j-1];
for (j=1;j<=i;j=j+1) print(a[j]); print(“换行符”);
} }
.
13
【例3】穿越沙漠问题 用一辆吉普车穿越1000公里的沙漠。吉普车的总装油量为500加仑, 耗油率为1加仑/公里。由于沙漠中没有油库,必须先用这辆车在 沙漠中建立临时油库。该吉普车以最少的耗油量穿越沙漠,应在 什么地方建油库,以及各处的贮油量。
问题分析:题目中要求用一个一维数组即完成。 1 4 6 4 1
数组空间一定是由下标从小到大利用的,这 ……………
样其实杨辉三角形是按下图4-2形式存储的。 图4-1 杨辉三角形
若求n层,则数组最多存储n个数据。
算法设计:
A[1] = A[i]=1 A[j] = A[j] + A[j-1] i行 i-1行 i-1行
算法分析与设计PPT教学课件 Algorithms Chapter 4 分治法
n>1
Memory 冒泡 合并 Time
15
Example of merge sort
Example of merge sort sorting a list of random numbers
16
练习 p98-11 Tromino谜题
如何将右图中L型瓦片覆盖到一个缺了一 个方块的2n × 2n的棋盘?
//输入:两个有序数组B[0..p-1]和C[0..q-1]
//输出:非降序列数组A-0..p+q-1] i0; j0; k0; while (i<p and j<q do){
if (n>1){
copy A[0.. [n/2]-1] to B[0..[n/2]-1] ; copy A[[n/2]..n-1] to C[0..[n/2]-1]; Mergesort(B[0..[n/2]-1]);
5
分治法的抽象化控制
1. 2. 3. 4. 5. 6. 7. Divide-and-Conquer(P) if |P|≤n0 判断输入规模是否足够的小 then return(ADHOC(P))//直接解小规模的问题P 将P分解为较小的子问题 P1 ,P2 ,...,Pk for i←1 to k do yi ← Divide-and-Conquer(Pi)//递归解决Pi T ← MERGE(y1,y2,...,yk) // 合并子问题 return(T)
...... ......
I2=(n-[n/2], A[[n/2]-1…n-1])
...... ......
Ih=(1,A[0])
Ii=(1,A[1])
Ij=(1,A[m])
Ik=(1,A[n])
递归与分治策略讲义课件(ppt 65页)
int prev,now,next,j; if (n<=1) return(1);
else {
prev=1; now=1; for(j=2;j<=n;j++) {
next=prev+now; prev=now; now=next; } return(next); } }
具有编译递归程序能力的程 序设计语言有:C、Pascal 、 ALGOL、 PL/A 、 ADA、 QBASIC等,不具有编译递归 程序能力的程序设计语言有: FORTRAN、 COBOL、BASIC、 低级语言。
Hanio(3,A,B,C) Hanio(2,A,C,B)
Move (A,C)
Hanio(2,B,A,C)
结束
Hanio(2,A,C,B)
Hanio(1,A,B,C) Move (A,B)
Hanio(1,C,A,B)
Hanio(1,A,B,C) Move (A,C)
Hanio(1,C,A,B) Move (C,B)
例3 Hanoi塔问题
设x,y,z是3个塔座。开始时,在塔座x上有一叠共n个圆盘,这 些圆盘自下而上,由大到小地叠在一起。各圆盘从小到大编号 为1,2,…,n,现要求将塔座x上的这一叠圆盘移到塔座z上,并仍 按同样顺序叠置。在移动圆盘时应遵守以下移动规则:
规则1:每次只能移动1个圆盘;
规则2:任何时刻都不允许将较大的圆盘压在较小的圆盘之上;
(1)运行开始时,首先为递归调用建立一个工作栈,其结 构包括值参、局部变量和返回地址;
(2)每次执行递归调用之前,把递归函数的值参和局部变 量的当前值以及调用后的返回地址压栈;
(3)每次递归调用结束后,将栈顶元素出栈,使相应的值 参和局部变量恢复为调用前的值,然后转向返回地址指定 的位置继续执行。
else {
prev=1; now=1; for(j=2;j<=n;j++) {
next=prev+now; prev=now; now=next; } return(next); } }
具有编译递归程序能力的程 序设计语言有:C、Pascal 、 ALGOL、 PL/A 、 ADA、 QBASIC等,不具有编译递归 程序能力的程序设计语言有: FORTRAN、 COBOL、BASIC、 低级语言。
Hanio(3,A,B,C) Hanio(2,A,C,B)
Move (A,C)
Hanio(2,B,A,C)
结束
Hanio(2,A,C,B)
Hanio(1,A,B,C) Move (A,B)
Hanio(1,C,A,B)
Hanio(1,A,B,C) Move (A,C)
Hanio(1,C,A,B) Move (C,B)
例3 Hanoi塔问题
设x,y,z是3个塔座。开始时,在塔座x上有一叠共n个圆盘,这 些圆盘自下而上,由大到小地叠在一起。各圆盘从小到大编号 为1,2,…,n,现要求将塔座x上的这一叠圆盘移到塔座z上,并仍 按同样顺序叠置。在移动圆盘时应遵守以下移动规则:
规则1:每次只能移动1个圆盘;
规则2:任何时刻都不允许将较大的圆盘压在较小的圆盘之上;
(1)运行开始时,首先为递归调用建立一个工作栈,其结 构包括值参、局部变量和返回地址;
(2)每次执行递归调用之前,把递归函数的值参和局部变 量的当前值以及调用后的返回地址压栈;
(3)每次递归调用结束后,将栈顶元素出栈,使相应的值 参和局部变量恢复为调用前的值,然后转向返回地址指定 的位置继续执行。
第4章 分治策略课件
X = a 2n/2 + b Y = c 2n/2 + d
XY = ac 2n + (ad+bc) 2n/2 + bd
4次整数乘法、3次整数加法、 2次移位
大整数的乘法
请设计一个有效的算法,可以进行两个n位大整数的乘法运算
小学的方法:O(n2)
效率太低
分治复法杂:度分析
XY = acT (2n)n=+3T((and/O2+()1b) Oc)(n2) nnn/2>=+11 bd
➢Hopcroft和Kerr已经证明(1971),计算2个2×2矩阵的乘积, 7次乘法是必要的。因此,要想进一步改进矩阵乘法的时间复 杂性,就不能再基于计算2×2矩阵的7次乘法这样的方法了。 或许应当研究3×3或5×5矩阵的更好算法。
➢在Strassen之后又有许多算法改进了矩阵乘法的计算时间复 杂性。目前最好的计算时间上界是 O(n2.376)
(3)合并:把各个子问题的解合并起来,合并的代价因情 况不同有很大差异,分治算法的有效性很大程度上依赖于合并 的实现。
例:计算an,应用分治技术得到如下计算方法:
分析时 间性能
an
a
=
a
n
2
a n 2
34
如果 n = 1 如果 n > 1
32
32
分解问题
31
31
31
31
求解每个子问题
3
3
3
3
9
C12 = M1 M 2 C21 = M 3 M 4
M 6 = ( A12 A22 )(B21 B22 ) M 7 = ( A11 A21 )(B11 B12 )
分治算法PPT
第一步
[38 49] [65 97] [13 76] [27]
第二步 第三步
[38 49 65 97]
[13 27 76]
18
[13 27 38 49 65 76 97]
归并排序主函数
void mergesort(int A[], int l, int r, int T[]) {
if(l < r) { int mid = (l + r) / 2; //二分 mergesort(A, l, mid, T);//继续对左子序列递归排序 mergesort(A, mid+1, r, T);//继续对右子序列递归排序 merge(A, l, mid, r, T); //合并
8
方法1
假设袋中有n个金块。可以通过n-1次比较找到最重 的金块。然后可以从余下的n-1个金块中用类似的方 法通过n-2次比较找出最轻的金块。这样,比较的总 次数为2n-3。具体的实现方法如下:
max = a[1]; min = a[1]; for(i=2; i<=n; i++) //2n-2次比较 {
问题,最后合并其结果就得到原问题的解。当分解(Divide):将原问题分成一系列子问题。 解决(Conquer):递归地解各子问题。若子问题
足够小,则可直接求解。 合并(combine);将子问题的结果合并成原问题
的解。
14
分治思想
问题的分解
方法1:每枚硬币都至少进行了一次比较,而有一枚硬 币进行了15次比较
方法2:每一枚硬币只进行了一次比较 方法3:将硬币分为两组后一次比较可以将硬币的范
围缩小到了原来的一半,这样充分地利用了只有1枚 伪币的基本性质。
第四讲分治策略28页PPT
12.11.2019
5
假设袋中有n 个金块。通过n-1次比较找到最重的金块。 找到最重的金块后,可以从余下的n-1个金块中用类似 的方法通过n-2次比较找出最轻的金块。这样,比较的 总次数为2n-3。
n≤2时,识别出最重和最轻的金块,做一次比较。
n>2时,
第一步,把这袋金块平分成两个小袋A和B。
最多次数为4。一般地有:当 n2k1,2k时,
一次成功的折半搜索至多做k次比较,而 一次不成功的折半搜索或者做k-1次比较, 或者做k次比较。
12.11.2019
25
二分搜索的时间复杂度
最坏情况下的成功检索计算时间Θ(logn) 最坏情况下的不成功检索计算时间Θ(logn) 最好情况下的成功检索计算时间Θ(1) 最好情况下的不成功检索计算时间Θ(logn) 每种不成功的检索时间都为Θ(logn)
判断输入规模p是 否足够的小
if (|P|<=n0) Adhoc(P);
解该规模问 题的函数
divide P into smaller subinstances
P1,P2,···,Pk;
分割函数
for(i=1;i<=k;i++)
分治解决
yi=Divide-and-Conquer (Pi);
return Merge(y1,···,yk); 合并得到
12.11.2019
26
二分检索在各种情况下的检索时间
12.11.2019
27
T(n)表示分治法的解规模为|P|=n的问题 所需的计算时间
12.11.2019
12
计算时间分析
由上可得
O(1)
n=1
T(n)=
第四讲分治策略
如果只允许进行元素间的比较而不允许 对它们进行其它的运算,则所设计的算法称为 以比较为基础的算法。
2019/4/5 14
1 线性搜索
任何以比较为基础的搜索算法的执行过程都可以用一棵二元 比较树来描述。每次可能的比较用一个内顶点表示,对应于 不成功的结果有一个外顶点与之对应。 线性搜索二元比较树如下:
x:A[1] 不成功
x:A[2]
不成功 x:A[n]
X>A[n]
A[n-1]<x<A[n]
2019/4/5
不成功
不成功
15
线性算法复杂度
该方法没有很好利用已经排好序这个条件, 顺序搜索方法平均需要 O(n)次比较。
2019/4/5
16
2 二分搜索方法
基本思想 取一个中间元素做比较元素,如果x等于它,则 结束,如果小于,去左半部查找,否则去右半 部搜索 将问题表示为:I=(n,a1,…,an,x) 选取一个下标k,可得到三个子问题:
2019/4/5
27
2019/4/5
3
一种方式 两两对比,找到轻者,最差比较8次 另外一种 1)将16个硬币分成A、B两半; 2)将A放仪器的一边,B放另一边,如果A 袋轻,则表明伪币在A,解子问题A即可, 否则,解子问题B。
4
2019/4/5
例2-5 金块问题
有一个老板有一袋金块。每个月将有两名雇员 会因其优异的表现分别被奖励一个金块。按规 矩,排名第一的雇员将得到袋中最重的金块, 排名第二的雇员将得到袋中最轻的金块。根据 这种方式,除非有新的金块加入袋中,否则第 一名雇员所得到的金块总是比第二名雇员所得 到的金块重。如果有新的金块周期性的加入袋 中,则每个月都必须找出最轻和最重的金块。 假设有一台比较重量的仪器,我们希望用最少 的比较次数找出最轻和最重的金块。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
将问题表示为:I=(n,a1,…,an,x) 选取一个下标k,可得到三个子问题:
I1=(k-1,a1,…,ak-1,x) I2=(1,ak,x) I3=(n-k,ak+1,…,an,x)
19.09.2020
a[k]
17
二元比较树
含9个元素的情况
4
1
6
0
2
5
7
3
8
19.09.2020
18
二元比较树
第4讲 分治策略
19.09.2020
1
主要内容
分治法基本思想 二分搜索算法 合并排序算法 快速排序算法 线性时间选择
19.09.2020
2
4.1 分治法的基本思想
例:[找伪币问题]给你一个装有1 6个硬币的 袋子。1 6个硬币中有一个是伪造的,并 且那个伪造的硬币比真的硬币要轻一些。 你的任务是找出这个伪造的硬币。为了帮 助你完成这一任务,将提供一台可用来比 较两组硬币重量的仪器,利用这台仪器, 可以知道两组硬币的重量是否相同。
如果只允许进行元素间的比较而不允许 对它们进行其它的运算,则所设计的算法称为
以比较为基础的算法。
19.09.2020
14
1 线性搜索
任何以比较为基础的搜索算法的执行过程都可以用一棵二元 比较树来描述。每次可能的比较用一个内顶点表示,对应于 不成功的结果有一个外顶点与之对应。
线性搜索二元比较树如下:
x:A[(n-1)/2]
x:A[(n-3)/4]
x:A[(3n-1)/4]
x:A[0]
x:A[(n-1)/2-1] x:A[(n-1)/2+1]
x:A[n-1]
不成 功
不成 不 成
功
功
19.09.2020
不成不成
功
功
不成 功
不 成不 成
功
功
19
例2-6 在[9,12,15,27,39]中分别查找27,12,14
最后结果
}19.09.2020
10
问题
应把原问题分为多少个子问题才较适宜? 每个子问题是否规模相同或怎样才为适当?
19.09.2020
11
分治法计算效率
原问题规模——n
分成k个子问题,每个规模——n/m
设分解阈值n0=1,Adhoc解规模为1的 问题耗费1个单位时间
设分解原问题及用Merge将k个子问题的 解合并需要f(n)个单位时间
时,可知c(n) = 3n/ 2 - 2。
使用分而治之方法比逐个比较的方法少用 了2 5%的比较次数。
19.09.2020
7
4.1 分治法的基本思想
分而治之方法与软件设计的模块化方法非 常相似。为了解决一个大的问题,可以:
1) 把它分成两个或多个更小的问题; 2) 分别解决每个小问题; 3) 把各小问题的解答组合起来,即可得到
19.09.2020
3
一种方式
两两对比,找到轻者,最差比较8次 另外一种
1)将16个硬币分成A、B两半; 2)将A放仪器的一边,B放另一边,如果 A袋轻,则表明伪币在A,解子问题A即 可,否则,解子问题B。
19.09.2020
4
例2-5 金块问题
有一个老板有一袋金块。每个月将有两名雇员
会因其优异的表现分别被奖励一个金块。按规 矩,排名第一的雇员将得到袋中最重的金块, 排名第二的雇员将得到袋中最轻的金块。根据 这种方式,除非有新的金块加入袋中,否则第 一名雇员所得到的金块总是比第二名雇员所得 到的金块重。如果有新的金块周期性的加入袋 中,则每个月都必须找出最轻和最重的金块。 假设有一台比较重量的仪器,我们希望用最少 的比较次数找出最轻和最重的金块。
原问题的解答。小问题通常与原问题相 似,可以递归地使用分而治之策略来解 决。
19.09.2020
8
原问题 子问题1 子问题2
相 同
子问题k 类
型
子问题1‘ 子问题2’ 子问题3‘
不可再 分,直 接求解
19.09.2020
9
分治法流程
用P表示问题的输入。
Divide-and-Conquer(P) {
0
1Hale Waihona Puke 91223
15
27
4 mid = (left+right)/2
39
=(0+4)/2=2
left
9
12
mid
15
27
9
left mid
9
12
right
12
mid left
15
27
15
27
left mid right
判断输入规模p是 否足够的小
if (|P|<=n0) Adhoc(P);
解该规模问 题的函数
divide P into smaller subinstances
P1,P2,···,Pk;
分割函数
for(i=1;i<=k;i++)
分治解决
yi=Divide-and-Conquer (Pi);
return Merge(y1,···,yk); 合并得到
T(n)表示分治法的解规模为|P|=n的问题 所需的计算时间
19.09.2020
12
计算时间分析
由上可得
O(1)
n=1
T(n)=
kT(n/m)+f(n) n>1
解上式得到
lom gn1
T(n)nlom gk kjf(n/mj) j0
19.09.2020
13
4.2 二分搜索技术
问题提出
给定已排好序的n个元素a[0:n-1],现要在这n个 元素中找出一特定元素x,找到则将其位置赋于变 量j中,否则j置-1。
第二步,分别找出在A和B中最重和最轻的金块。HA 与LA,HB 和LB。
第三步,通过比较HA 和HB,可以找到所有金块中最 重的;通过比较LA 和LB,可以找到所有金块中最轻的。
19.09.2020
6
复杂度
设c(n)为比较次数。假设n是2的幂。
当n= 2时,c(n) = 1; 当n>2时,c(n) = 2c(n/ 2 ) + 2。当n是2的幂
x:A[1]
不成功
x:A[2]
19.09.2020
不成功
x:A[n]
X>A[n]
A[n-1]<x<A[n]
不成功
不成功 15
线性算法复杂度
该方法没有很好利用已经排好序这个条件, 顺序搜索方法平均需要 O(n)次比较。
19.09.2020
16
2 二分搜索方法
基本思想
取一个中间元素做比较元素,如果x等于它,则 结束,如果小于,去左半部查找,否则去右半 部搜索
19.09.2020
5
假设袋中有n 个金块。通过n-1次比较找到最重的金块。 找到最重的金块后,可以从余下的n-1个金块中用类似 的方法通过n-2次比较找出最轻的金块。这样,比较的 总次数为2n-3。
n≤2时,识别出最重和最轻的金块,做一次比较。
n>2时,
第一步,把这袋金块平分成两个小袋A和B。
I1=(k-1,a1,…,ak-1,x) I2=(1,ak,x) I3=(n-k,ak+1,…,an,x)
19.09.2020
a[k]
17
二元比较树
含9个元素的情况
4
1
6
0
2
5
7
3
8
19.09.2020
18
二元比较树
第4讲 分治策略
19.09.2020
1
主要内容
分治法基本思想 二分搜索算法 合并排序算法 快速排序算法 线性时间选择
19.09.2020
2
4.1 分治法的基本思想
例:[找伪币问题]给你一个装有1 6个硬币的 袋子。1 6个硬币中有一个是伪造的,并 且那个伪造的硬币比真的硬币要轻一些。 你的任务是找出这个伪造的硬币。为了帮 助你完成这一任务,将提供一台可用来比 较两组硬币重量的仪器,利用这台仪器, 可以知道两组硬币的重量是否相同。
如果只允许进行元素间的比较而不允许 对它们进行其它的运算,则所设计的算法称为
以比较为基础的算法。
19.09.2020
14
1 线性搜索
任何以比较为基础的搜索算法的执行过程都可以用一棵二元 比较树来描述。每次可能的比较用一个内顶点表示,对应于 不成功的结果有一个外顶点与之对应。
线性搜索二元比较树如下:
x:A[(n-1)/2]
x:A[(n-3)/4]
x:A[(3n-1)/4]
x:A[0]
x:A[(n-1)/2-1] x:A[(n-1)/2+1]
x:A[n-1]
不成 功
不成 不 成
功
功
19.09.2020
不成不成
功
功
不成 功
不 成不 成
功
功
19
例2-6 在[9,12,15,27,39]中分别查找27,12,14
最后结果
}19.09.2020
10
问题
应把原问题分为多少个子问题才较适宜? 每个子问题是否规模相同或怎样才为适当?
19.09.2020
11
分治法计算效率
原问题规模——n
分成k个子问题,每个规模——n/m
设分解阈值n0=1,Adhoc解规模为1的 问题耗费1个单位时间
设分解原问题及用Merge将k个子问题的 解合并需要f(n)个单位时间
时,可知c(n) = 3n/ 2 - 2。
使用分而治之方法比逐个比较的方法少用 了2 5%的比较次数。
19.09.2020
7
4.1 分治法的基本思想
分而治之方法与软件设计的模块化方法非 常相似。为了解决一个大的问题,可以:
1) 把它分成两个或多个更小的问题; 2) 分别解决每个小问题; 3) 把各小问题的解答组合起来,即可得到
19.09.2020
3
一种方式
两两对比,找到轻者,最差比较8次 另外一种
1)将16个硬币分成A、B两半; 2)将A放仪器的一边,B放另一边,如果 A袋轻,则表明伪币在A,解子问题A即 可,否则,解子问题B。
19.09.2020
4
例2-5 金块问题
有一个老板有一袋金块。每个月将有两名雇员
会因其优异的表现分别被奖励一个金块。按规 矩,排名第一的雇员将得到袋中最重的金块, 排名第二的雇员将得到袋中最轻的金块。根据 这种方式,除非有新的金块加入袋中,否则第 一名雇员所得到的金块总是比第二名雇员所得 到的金块重。如果有新的金块周期性的加入袋 中,则每个月都必须找出最轻和最重的金块。 假设有一台比较重量的仪器,我们希望用最少 的比较次数找出最轻和最重的金块。
原问题的解答。小问题通常与原问题相 似,可以递归地使用分而治之策略来解 决。
19.09.2020
8
原问题 子问题1 子问题2
相 同
子问题k 类
型
子问题1‘ 子问题2’ 子问题3‘
不可再 分,直 接求解
19.09.2020
9
分治法流程
用P表示问题的输入。
Divide-and-Conquer(P) {
0
1Hale Waihona Puke 91223
15
27
4 mid = (left+right)/2
39
=(0+4)/2=2
left
9
12
mid
15
27
9
left mid
9
12
right
12
mid left
15
27
15
27
left mid right
判断输入规模p是 否足够的小
if (|P|<=n0) Adhoc(P);
解该规模问 题的函数
divide P into smaller subinstances
P1,P2,···,Pk;
分割函数
for(i=1;i<=k;i++)
分治解决
yi=Divide-and-Conquer (Pi);
return Merge(y1,···,yk); 合并得到
T(n)表示分治法的解规模为|P|=n的问题 所需的计算时间
19.09.2020
12
计算时间分析
由上可得
O(1)
n=1
T(n)=
kT(n/m)+f(n) n>1
解上式得到
lom gn1
T(n)nlom gk kjf(n/mj) j0
19.09.2020
13
4.2 二分搜索技术
问题提出
给定已排好序的n个元素a[0:n-1],现要在这n个 元素中找出一特定元素x,找到则将其位置赋于变 量j中,否则j置-1。
第二步,分别找出在A和B中最重和最轻的金块。HA 与LA,HB 和LB。
第三步,通过比较HA 和HB,可以找到所有金块中最 重的;通过比较LA 和LB,可以找到所有金块中最轻的。
19.09.2020
6
复杂度
设c(n)为比较次数。假设n是2的幂。
当n= 2时,c(n) = 1; 当n>2时,c(n) = 2c(n/ 2 ) + 2。当n是2的幂
x:A[1]
不成功
x:A[2]
19.09.2020
不成功
x:A[n]
X>A[n]
A[n-1]<x<A[n]
不成功
不成功 15
线性算法复杂度
该方法没有很好利用已经排好序这个条件, 顺序搜索方法平均需要 O(n)次比较。
19.09.2020
16
2 二分搜索方法
基本思想
取一个中间元素做比较元素,如果x等于它,则 结束,如果小于,去左半部查找,否则去右半 部搜索
19.09.2020
5
假设袋中有n 个金块。通过n-1次比较找到最重的金块。 找到最重的金块后,可以从余下的n-1个金块中用类似 的方法通过n-2次比较找出最轻的金块。这样,比较的 总次数为2n-3。
n≤2时,识别出最重和最轻的金块,做一次比较。
n>2时,
第一步,把这袋金块平分成两个小袋A和B。