计算复杂性之回溯法详解
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
k-ary字符串
问题:生成所有来自0..k-1,n个数字的字符串. 解决方案:用数组A[1..n]来保存当前的k-ary字符串。
目的是调用process(A)一次用数组A[1..n]保存每 个k-ary字符串。 伪代码: procedure string(m) comment process all k-ary strings oflength m if m = 0 then process(A) else for j := 0 to k − 1 do A[m] := j; string(m− 1) 正确性证明:与二进制案例相似。 分析:与二进制案例相似,算法最优
if j consistent with A[m+1..n]
then A[m] := j;generate(m−1)
背包问题The Knapsack Problem
解决方案:给定n个支路,用一个数组A[1…n] 如果支路i被用上,则使得A[i]=1。遍历A[1…n]来寻找合值。 n = 3, s1 = 4, s2 = 5, s3 = 2, L = 6.
回溯法则
回溯通过一个树形结构来寻找解空间。举例来说长度为3的 二进制字符串:
回溯法会在这树上进行前序遍历,处理叶子。
通过修剪法来减少计算时间:跳过没有用的树叶的 节点。找到的是错误的则回到父节点
k-ary字符串的剪切应用
字符串数组填充过程从右到左,string(m,k)可以删除那些对 A[m]而言不容于A[m+1,..n]的选择。 procedure string(m) comment process all k-ary strings of length m if m = 0 then process(A) else for j := 0 to k − 1 do if j is a valid choice for A[m] then A[m] := j; string(m − 1)
1.将A[m]值设为0; 2.调用binary(m-1) 由归纳假设,这会调用process(A)一次,数组A[1..m]包含每 个有m个字符的字符串,以0结束。
然后,binary(m)
1.将A[m]值设为1;
2.调用binary(m-1).
由归纳假设,这会调用process(A)一次,数组A[1..m]包含每 个有m个字符的字符串,以1结束。
因此,binary(m)调用process(A)一次,数组A[1..n]包含每 个有m个字符的字符串。
分析
设T(n)为binary(m)的运行时间.假设程序进程消耗时O(1),则
因此,由上式的递推公式推导出此式子, T(n) = (c + d)2n-1 − d.
因而,T(n)=O(2n),这意味着生成字符串的算法是最优的。
回溯法
回溯法1.概要
• 回溯法是一种选优搜索法,按选优条件向前搜索, 以达到目标。但当探索到某一步时,发现原先选 择并不优或达不到目标,就退回一步重新选择, 这种走不通就退回再走的技术为回溯法,而满足 回溯条件的某个状态的点称为“回溯点”。
回溯法
• 摘要: 利用分治法的方法穷举搜索,分治法将一个问题分解成几个
procedure generate(m)
if m = 0 then process(A)
if m = 0 then process(A)
else for each of a bunch of else for each of a bunch
numbers j do
of numbers j do
A[m] := j; generate(m− 1)
类似的小规模问题,再将子问题的解合成原问题的解。 • 总纲:
1.二进制字符串回溯法 2.K-ary字符串回溯法 3.修剪与删除 4.如何编写回溯法算法 • 应用于: 1.背包问题 2.汉密尔顿路径问题 3.旅行推销员问题
穷举搜索
穷举搜索,顾名思义,就是尝试所求问题的所有可能性。 穷举搜索的时间往往很慢,但也有一些关于标准的工具来帮 助我们使用:生成基本项目的算法,比如: 1.长度为n的二进制字符串共有2n个字符。 2.长度为n的k-ary字符串有kn个字符 3.n!种排列方式 4.在n样事物中选取r件事物,共有n!/r!(n-r)!种组合。 回溯法可以通过“优化修剪”的方法加速穷举搜索。
正确性证明
要求:对任意的m ≥ 1,binary(m)调用process(A)一次,数 组A[1..n]包含每个有m个字符的字符串。
证明:证明关于m使用归纳法。上述要求对于m=0明显成立。 现在假设binary(m-1)调用process(A)一次,数组A[1..m-1]
保存每个有m-1个字符的字符串. 首先,binary(m)
回溯基本问题1、位串wk.baidu.com题
问题:生成含有n个字符的所有字符串。 解题思路:使用分治法。用数组A[1..n]来保存当前的二进制
字符串。目的是调用process(A)一次,用数组A[1..n]保存 每个二进制字符串。 伪代码: Procedure binary(m ) comment process all binary strings of length m if m =0 then process(A ) else A [m ]:=0;binary(m − 1) A [m ]:=1;binary(m − 1)
算法
使用二进制字符串算法。优化剪切:设 l 为剩余长度,
1,A[m]=0时是合适的;
2,A[m]=1时是不合适的,如果sm>l ;优化剪切
程序knapsack(n,L)用长度分别为s1,...,sn的n个枝条输出背包
问题的所有解,背包的长度大小为L。
procedure knapsack(m, l)
创 创造造一一个回个溯回算法溯的算步骤法:
• 选择一个基本对象,如:字符串,排列组合(在本轮文中将是字 符串)
• 用分而治之代码来生成这些基本对象
• 用这个代码测试其性能关于基本的递归
• 在每一次递归调用前优化代码算法
一般形式的生成算法:
一般形式的回溯算法:
procedure generate(m)