蛮力法
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
5 10
40
25 54
12
13 14
{1, 2, 3}
{1, 2, 4} {1, 3, 4}
14
15 16
不可行
不可行 不可行
7
8
{1, 3}
{1, 4}
11
12
不可行
不可行
15
16
{2, 3, 4}
{1, 2, 3, 4}
12
19
不可行
不可行
0/1背包问题算法伪代码描述:
输入:重量{w1, w {v1, v2, …, v,n },背 对于一个具有 n 个元素的集合 其子集数 2, …, wn},价值
包容量C 量是2n,所以,不论生成子集的算法效率有 多高 , 蛮力法都会导致一个 Ω( 2 n ) 的算法 . 输出:装入背包的物品编号 1. 初始化最大价值maxValue=0;结果子集S=Φ; 2. 对集合{1, 2, …, n}的每一个子集,执行下述操作:
2.1 初始化背包的价值value=0;背包的重量weight=0; 2.2 对子集T的每一个元素j
蛮力法求解TSP问题,只能解决问题规模很小的实例。
算法的C++语言描述:
int ClosestPoints(int x[ ], int y[ ], int n) { int index1, index2; //记载最近点对的下标 int d, minDist = 1000; //假设最大距离不超过1000 for (int i = 0; i < n - 1; i++) for (int j = i + 1; j < n; j++) //只考虑i<j的点对 { d = (x[i]-x[j])* (x[i]-x[j]) + (y[i]-y[j])* (y[i]-y[j]); if (d < minDist) { minDist = d; index1 = i; index2 = j; } } cout<<"最近的点对是:"<<index1<<"和"<<index2<<endl; return minDist; }
逻辑清晰,编写程序简洁 对于一些重要的问题(比如:排序、查找、矩阵 乘法和字符串匹配),可以产生一些合理的算法 解决问题的实例很少时,可以花费较少的代价 可以解决一些小规模的问题(使用优化的算法没 有必要,而且某些优化算法本身较复杂) 可以作为其他高效算法的衡量标准
3.1.4 使用蛮力法的几种情况
思考:求所有的三位数,它除以11所得的余数等于 它的三个数字的平方和。——找出枚举范围和约 束条件
分析:
枚举范围:100~999,共900个。 约束条件:设三位数的百位、十位、个位的数字分 别为x,y,z。则有x2+y2+z2≤10,进而1≤x≤3, 0≤y≤3, 0≤z≤3。
解:所求三位数必在以下数中:
3. 如果T中所有字符均比较完毕,则返回本趟匹配的 开始位置;否则返回0。
3.2.2 选择排序——排序
选择排序开始的时候,扫描整个序列,找到整个序列的最 小记录和序列中的第一个记录交换,从而将最小记录放到 它在有序区的最终位置上,然后再从第二个记录开始扫描 序列,找到n-1个序列中的最小记录,再和第二个记录交 换位置。一般地,第i趟排序从第i个记录开始扫描序列, 在n-i+1(1≤i≤n-1)个记录中找到关键码最小的记录,并 和第i个记录交换作为有序序列的第i个记录。 交换
w={7, 3, 4, 5}
序号 1 2 3 子集 Φ {1} {2}
v={42, 12, 40, 25}
重量 0 7 3 价值 0 42 12 序号 9 10 11
C=10
子集 {2, 3} {2, 4} {3, 4} 重量 7 8 9 价值 52 37 65
4
5 6
{3}
{4} {1, 2}
4
i
a b c a b c a c b \0 a b c a c
a b c a b c a c b \0 a b c a c
k
j
k
j
T[j-k]~T[j-1] = S[i-k]~S[i-1]
T[0]~T[k-1] = S[i-k]~S[i-1]
T[0]~T[k-1] = T[j-k]~T[j-1]
,当j=0时 1 next[ j ] Max{k | 0 k j且' p1...pk 1 ' ' p j k 1...p j 1 '} ,当此集合不空时 0 ,其他情况
问题描述:旅行家要旅行n个城市然后回到出发 城市,要求各个城市经历且仅经历一次,并要求 所走的路程最短。该问题又称为货郎担问题、邮 递员问题、售货员问题,是图问题中最广为人知 的问题。 用蛮力法解决TSP问题,可以找出所有可能的旅 行路线,从中选取路径长度最短的简单回路。 求解: 一个加权连通图中的最短哈密顿回路问题。
3.1.2 关于蛮力法的思考
蛮力法(枚举法、穷举法、暴力法)要求设计者 找出所有可能的情况,然后选择其中一种情况, 若该情况不可行(或不是最优解)则试探下一种 可能的情况。 蛮力法是一种直接解决问题的方法,常常直接基 于问题的描述和所设计的概念定义。 “力”——指计算机的能力,而不是人的智力。 蛮力法常常是最容易应用的方法。
求an(n为非负整数) 用连续整数检测算法计算GCD(m, n)
蛮力法不是一个最好的算法(巧妙和高效的算法 很少出自蛮力),但当我们想不出更好的办法时,它 也是一种有效的解决问题的方法。 它可能是惟一一种几乎什么问题都能解决的一般 性方法,常用于一些非常基本、但又十分重要的 算法。
3.1.3 蛮力法的优点
2.2.1 如果weight+wj<C,则 weight=weight+wj;value=value+vj; 2.2.2 否则,转步骤2考察下一个子集;
2.3 如果maxValue<value,则maxValue=value;S=T;
3. 输出子集S中的各元素。
3.2.4 TSP——图问题
TSP问题有着简单的表述、重要的应用、以及和其他NP完全 问题的重要关系,它在近100年的时间里强烈地吸引着计算机 科学工作者。
a 5 c
序号 1 2 3 4 5 6 路径 a→b→c→d→a a→b→d→c→a a→c→b→d→a a→c→d→b→a a→d→b→c→a a→d→c→b→a
2 8
KMP算法的伪代码描述:
输入:主串S,模式T 输出:T在S中的位置
算法的时间复杂性T(n)=O(n)
1. 在串S和串T中分别设置比较的起始下标i=0, j=0; 2. 重复下述操作, 直到S或T的所有字符均比较完毕:
2.1 如果S[i]等于T[j],则继续比较S和T的下一对字符; 2.2 否则,将下标j回溯到next[j]位置,即j=next[j]; 2.3 如果j等于-1,则将下标i和j分别加1,准备下一趟 比较;
100,101,102,103,110,111,112, 120,121,122,130,200,201,202, 211,212,220,221,300,301,310。 不难验证只有100,101两个数符合要求。
3.2 各类问题中的蛮力法
3.2.1 串匹配问题——查找
BF算法
本趟开始位置
KMP算法
本章小结
蛮力法的设计思想:采用一定的策略将待求解问 题的所有元素依次处理一次,从而找出问题的解 。 求解步骤:
找出枚举范围 找出约束条件
课后作业
P53:2~8,按学号完成相应的题பைடு நூலகம்:
学号尾数mod7=1,完成2
学号尾数mod7=2,完成3
学号尾数mod7=3,完成4 学号尾数mod7=4,完成5 学号尾数mod7=5,完成6 学号尾数mod7=6,完成7 学号尾数mod7=0,完成8
r1 ≤r2 … … ≤ri-1 ri ri+1 … rmin … rn
有序区 已经位于最终位置 无序区 rmin为无序区的最小记录
算法描述:
void SelectSort(int r[ ], int n) { for (i=1; i<=n-1; i++) { index=i; for (j=i+1; j<=n; j++) if (r[j]<r[index]) index=j; if (index!=i) r[i]←→r[index]; } }
下一次开始位置 下一次开始位置 i 回溯 ii
S
si
…
模式T j
回溯 回溯next[j]
……
tj
j
BF算法的伪代码描述
输入:主串S(长度为n),模式T(长度为m) 输出:T在S中的位置
1. 初始化主串比较的开始位置index=0; 2. 在串S和串T中设置比较的起始下标i=0, j=0; 3. 重复下述操作, 直到S或T的所有字符均比较完毕:
3.2.3 0/1背包问题——组合
问题描述:给定n个重量为 {w1, w2, … ,wn}、价值为{v1, v2, … ,vn}的物品和一个容 量为 C 的背包,求这些物 品中的一个最有价值的子 集,且要能够装到背包中。
在n个物品中找到所有总重量不超过背包容量的子 集,计算每个可能子集的总价值,然后找到价值 最大的子集。 例如,给定4个物品的重量{7, 3, 4, 5},价值{42, 12, 40, 25},和一个容量为10的背包。蛮力法求解 过程为:
第3章 蛮力法
学习要点:
掌握蛮力法的设计思想 应用蛮力法思想,设计求解问题的算法,并分析算
法时间复杂性
3.1 概述
3.1.1 蛮力法的设计思想
蛮力法是指采用遍历(扫描)技术,即采用一定 的策略将待求解问题的所有元素依次处理一次, 从而找出问题的解。 依次处理所有元素是蛮力法的关键,为了避免陷 入重复试探,应保证处理过的元素不再被处理。
1 7
b 3 d
路径长度 18 11 23 11 23 18 是否最短 否 是 否 是 否 否
用蛮力法求解TSP问题存在的问题:
注意到图中有3对不同的路径,对每对路径来说,不同的 只是路径的方向,因此,可以将这个数量减半,则可能 的解有(n-1)!/2个。随着n的增长,TSP问题的可能解也在 迅速地增长。 一个10城市的TSP问题有大约180,000个可能解。 一个20城市的TSP问题有大约 60,000,000,000,000,000个可能解。 一个50城市的TSP问题有大约1062个可能解,而一个行 星上也只有1021升水。
搜索所有的解空间 搜索所有的路径 直接计算 模拟和仿真
一个简单的例子——百元买百鸡问题
3.1.5 蛮力法解题步骤
用蛮力法解决问题,通常可以从两个方面进行算 法设计:
找出枚举范围:分析问题所涉及的各种情况。 找出约束条件:分析问题的解需要满足的条件,并
用逻辑表达式表示。
3.1 如果S[i]等于T[j],则继续比较S和T的下一对字符; 3.2 否则,下一趟匹配的开始位置index++,回溯下标 i=index, j=0;
4. 如果T中所有字符均比较完,则返回匹配的开始位 置index;否则返回0。
S=‘aaaaaaaaaaab’ T=‘aaab’
KMP算法
i
40
25 54
12
13 14
{1, 2, 3}
{1, 2, 4} {1, 3, 4}
14
15 16
不可行
不可行 不可行
7
8
{1, 3}
{1, 4}
11
12
不可行
不可行
15
16
{2, 3, 4}
{1, 2, 3, 4}
12
19
不可行
不可行
0/1背包问题算法伪代码描述:
输入:重量{w1, w {v1, v2, …, v,n },背 对于一个具有 n 个元素的集合 其子集数 2, …, wn},价值
包容量C 量是2n,所以,不论生成子集的算法效率有 多高 , 蛮力法都会导致一个 Ω( 2 n ) 的算法 . 输出:装入背包的物品编号 1. 初始化最大价值maxValue=0;结果子集S=Φ; 2. 对集合{1, 2, …, n}的每一个子集,执行下述操作:
2.1 初始化背包的价值value=0;背包的重量weight=0; 2.2 对子集T的每一个元素j
蛮力法求解TSP问题,只能解决问题规模很小的实例。
算法的C++语言描述:
int ClosestPoints(int x[ ], int y[ ], int n) { int index1, index2; //记载最近点对的下标 int d, minDist = 1000; //假设最大距离不超过1000 for (int i = 0; i < n - 1; i++) for (int j = i + 1; j < n; j++) //只考虑i<j的点对 { d = (x[i]-x[j])* (x[i]-x[j]) + (y[i]-y[j])* (y[i]-y[j]); if (d < minDist) { minDist = d; index1 = i; index2 = j; } } cout<<"最近的点对是:"<<index1<<"和"<<index2<<endl; return minDist; }
逻辑清晰,编写程序简洁 对于一些重要的问题(比如:排序、查找、矩阵 乘法和字符串匹配),可以产生一些合理的算法 解决问题的实例很少时,可以花费较少的代价 可以解决一些小规模的问题(使用优化的算法没 有必要,而且某些优化算法本身较复杂) 可以作为其他高效算法的衡量标准
3.1.4 使用蛮力法的几种情况
思考:求所有的三位数,它除以11所得的余数等于 它的三个数字的平方和。——找出枚举范围和约 束条件
分析:
枚举范围:100~999,共900个。 约束条件:设三位数的百位、十位、个位的数字分 别为x,y,z。则有x2+y2+z2≤10,进而1≤x≤3, 0≤y≤3, 0≤z≤3。
解:所求三位数必在以下数中:
3. 如果T中所有字符均比较完毕,则返回本趟匹配的 开始位置;否则返回0。
3.2.2 选择排序——排序
选择排序开始的时候,扫描整个序列,找到整个序列的最 小记录和序列中的第一个记录交换,从而将最小记录放到 它在有序区的最终位置上,然后再从第二个记录开始扫描 序列,找到n-1个序列中的最小记录,再和第二个记录交 换位置。一般地,第i趟排序从第i个记录开始扫描序列, 在n-i+1(1≤i≤n-1)个记录中找到关键码最小的记录,并 和第i个记录交换作为有序序列的第i个记录。 交换
w={7, 3, 4, 5}
序号 1 2 3 子集 Φ {1} {2}
v={42, 12, 40, 25}
重量 0 7 3 价值 0 42 12 序号 9 10 11
C=10
子集 {2, 3} {2, 4} {3, 4} 重量 7 8 9 价值 52 37 65
4
5 6
{3}
{4} {1, 2}
4
i
a b c a b c a c b \0 a b c a c
a b c a b c a c b \0 a b c a c
k
j
k
j
T[j-k]~T[j-1] = S[i-k]~S[i-1]
T[0]~T[k-1] = S[i-k]~S[i-1]
T[0]~T[k-1] = T[j-k]~T[j-1]
,当j=0时 1 next[ j ] Max{k | 0 k j且' p1...pk 1 ' ' p j k 1...p j 1 '} ,当此集合不空时 0 ,其他情况
问题描述:旅行家要旅行n个城市然后回到出发 城市,要求各个城市经历且仅经历一次,并要求 所走的路程最短。该问题又称为货郎担问题、邮 递员问题、售货员问题,是图问题中最广为人知 的问题。 用蛮力法解决TSP问题,可以找出所有可能的旅 行路线,从中选取路径长度最短的简单回路。 求解: 一个加权连通图中的最短哈密顿回路问题。
3.1.2 关于蛮力法的思考
蛮力法(枚举法、穷举法、暴力法)要求设计者 找出所有可能的情况,然后选择其中一种情况, 若该情况不可行(或不是最优解)则试探下一种 可能的情况。 蛮力法是一种直接解决问题的方法,常常直接基 于问题的描述和所设计的概念定义。 “力”——指计算机的能力,而不是人的智力。 蛮力法常常是最容易应用的方法。
求an(n为非负整数) 用连续整数检测算法计算GCD(m, n)
蛮力法不是一个最好的算法(巧妙和高效的算法 很少出自蛮力),但当我们想不出更好的办法时,它 也是一种有效的解决问题的方法。 它可能是惟一一种几乎什么问题都能解决的一般 性方法,常用于一些非常基本、但又十分重要的 算法。
3.1.3 蛮力法的优点
2.2.1 如果weight+wj<C,则 weight=weight+wj;value=value+vj; 2.2.2 否则,转步骤2考察下一个子集;
2.3 如果maxValue<value,则maxValue=value;S=T;
3. 输出子集S中的各元素。
3.2.4 TSP——图问题
TSP问题有着简单的表述、重要的应用、以及和其他NP完全 问题的重要关系,它在近100年的时间里强烈地吸引着计算机 科学工作者。
a 5 c
序号 1 2 3 4 5 6 路径 a→b→c→d→a a→b→d→c→a a→c→b→d→a a→c→d→b→a a→d→b→c→a a→d→c→b→a
2 8
KMP算法的伪代码描述:
输入:主串S,模式T 输出:T在S中的位置
算法的时间复杂性T(n)=O(n)
1. 在串S和串T中分别设置比较的起始下标i=0, j=0; 2. 重复下述操作, 直到S或T的所有字符均比较完毕:
2.1 如果S[i]等于T[j],则继续比较S和T的下一对字符; 2.2 否则,将下标j回溯到next[j]位置,即j=next[j]; 2.3 如果j等于-1,则将下标i和j分别加1,准备下一趟 比较;
100,101,102,103,110,111,112, 120,121,122,130,200,201,202, 211,212,220,221,300,301,310。 不难验证只有100,101两个数符合要求。
3.2 各类问题中的蛮力法
3.2.1 串匹配问题——查找
BF算法
本趟开始位置
KMP算法
本章小结
蛮力法的设计思想:采用一定的策略将待求解问 题的所有元素依次处理一次,从而找出问题的解 。 求解步骤:
找出枚举范围 找出约束条件
课后作业
P53:2~8,按学号完成相应的题பைடு நூலகம்:
学号尾数mod7=1,完成2
学号尾数mod7=2,完成3
学号尾数mod7=3,完成4 学号尾数mod7=4,完成5 学号尾数mod7=5,完成6 学号尾数mod7=6,完成7 学号尾数mod7=0,完成8
r1 ≤r2 … … ≤ri-1 ri ri+1 … rmin … rn
有序区 已经位于最终位置 无序区 rmin为无序区的最小记录
算法描述:
void SelectSort(int r[ ], int n) { for (i=1; i<=n-1; i++) { index=i; for (j=i+1; j<=n; j++) if (r[j]<r[index]) index=j; if (index!=i) r[i]←→r[index]; } }
下一次开始位置 下一次开始位置 i 回溯 ii
S
si
…
模式T j
回溯 回溯next[j]
……
tj
j
BF算法的伪代码描述
输入:主串S(长度为n),模式T(长度为m) 输出:T在S中的位置
1. 初始化主串比较的开始位置index=0; 2. 在串S和串T中设置比较的起始下标i=0, j=0; 3. 重复下述操作, 直到S或T的所有字符均比较完毕:
3.2.3 0/1背包问题——组合
问题描述:给定n个重量为 {w1, w2, … ,wn}、价值为{v1, v2, … ,vn}的物品和一个容 量为 C 的背包,求这些物 品中的一个最有价值的子 集,且要能够装到背包中。
在n个物品中找到所有总重量不超过背包容量的子 集,计算每个可能子集的总价值,然后找到价值 最大的子集。 例如,给定4个物品的重量{7, 3, 4, 5},价值{42, 12, 40, 25},和一个容量为10的背包。蛮力法求解 过程为:
第3章 蛮力法
学习要点:
掌握蛮力法的设计思想 应用蛮力法思想,设计求解问题的算法,并分析算
法时间复杂性
3.1 概述
3.1.1 蛮力法的设计思想
蛮力法是指采用遍历(扫描)技术,即采用一定 的策略将待求解问题的所有元素依次处理一次, 从而找出问题的解。 依次处理所有元素是蛮力法的关键,为了避免陷 入重复试探,应保证处理过的元素不再被处理。
1 7
b 3 d
路径长度 18 11 23 11 23 18 是否最短 否 是 否 是 否 否
用蛮力法求解TSP问题存在的问题:
注意到图中有3对不同的路径,对每对路径来说,不同的 只是路径的方向,因此,可以将这个数量减半,则可能 的解有(n-1)!/2个。随着n的增长,TSP问题的可能解也在 迅速地增长。 一个10城市的TSP问题有大约180,000个可能解。 一个20城市的TSP问题有大约 60,000,000,000,000,000个可能解。 一个50城市的TSP问题有大约1062个可能解,而一个行 星上也只有1021升水。
搜索所有的解空间 搜索所有的路径 直接计算 模拟和仿真
一个简单的例子——百元买百鸡问题
3.1.5 蛮力法解题步骤
用蛮力法解决问题,通常可以从两个方面进行算 法设计:
找出枚举范围:分析问题所涉及的各种情况。 找出约束条件:分析问题的解需要满足的条件,并
用逻辑表达式表示。
3.1 如果S[i]等于T[j],则继续比较S和T的下一对字符; 3.2 否则,下一趟匹配的开始位置index++,回溯下标 i=index, j=0;
4. 如果T中所有字符均比较完,则返回匹配的开始位 置index;否则返回0。
S=‘aaaaaaaaaaab’ T=‘aaab’
KMP算法
i