目录
实验目的
1 理解搜索树与解空间树的区别
2 理解回溯法\分支限界法\穷举搜索的区别
3 理解回溯法的特征(基于解空间树\纵向优先\剪枝) 和 分支限界法的特征(基于解空间树\横向优先\剪枝)
4掌握回溯法的简单实现和时间复杂度分析
实验内容
1 素数环问题
2 0/1背包问题
我的分析
1、 素数环问题:
目的:求1-n个数能否构成一个环使得相邻两个数的和为素数且每个数只能使用一次。
思路:利用回溯法,根据搜索树和隐式约束对数经行减枝,判断相邻两个数不相同且相加为素数,利用回溯法一一搜索,直到找到对应的排列顺序。
2、0/1背包问题:
目的:我们有n种物品,物品j的重量为wj,价格为pj。
我们假定所有物品的重量和价格都是非负的。背包所能承受的最大重量为c。如果限定每种物品只能选择0个或1个,求背包能装的最大价值。
思路:基于回溯法,根据约束条件和限界条件对问题的解进行挑选,关于限界条件老师上课讲了很多种:1.已放入背包 加上 未放入的物品价值 之和 要大于 当前找到的最大背包价值。2. 已放入背包 的价值加上 (剩余容量能装入的价值) 要大于 当前的最大背包价值。。第二个限界条件似乎更好。
问题解决
- 素数环问题:
回溯法:
算法描述:
算法:求解素数环prime_circle()
输入:素数环的大小n
输出:能构成素数环的一种情况
过程:1.定义存放解分量的数组x[]并将每项初始化为0
2.从1开始向下探索,
3.设立check()函数来判断这个点是否符合
4.符合则继续往后搜索,若不符合,尝试其他分治,若遍历完其他分支依旧不符合则经行回溯
5.求解完毕输出解。
算法实现:
运行结果:
时间复杂度:
最坏情况下,需要遍历每一种情况T(n)=n的n次方=O(n的平方)
2、0/1背包问题
算法描述:
算法:求解0/1背包问题bagProblem()
输入:背包的容量C,物品的重量数组w[],物品的价值数组v[],
输出:背包能装下的最大重量。
算法思路(描述不太会):
- 将背包按照性价比排序
- 对每个物品经行搜索,装入则状态为1,不装入状态为0
- 定义max来记录目前背包装入的最大价值
- 通过限界条件:已放入背包 的价值加上 (剩余容量能装入的价值) 要大于 当前的最大背包价值。来经行减枝。
算法实现:
以下是运行结果:
总结(问题归纳)
1、请从你实现的级别中选择一题,按照你的实现绘制搜索树。
2、你觉得回溯法和蛮力搜索有相同点吗?有不同点吗?请举例说明。
有,都是基于尝试探索。不同点:穷举法是要将一个解的全部选项生成后判断是否满足,不满足再去尝试其他解,而回溯法,他的每个解是逐步生成的,会根据约束条件和限界条件来经行减枝和回溯。具体的归纳如下:
相同点:
- 都是穷举搜索:回溯法和蛮力搜索都是通过遍历所有可能的解空间来求解问题,它们不依赖于问题的特定性质或结构,而是通过尝试不同的选择组合来找到解决方案。
- 都可以用于组合优化问题:回溯法和蛮力搜索通常用于解决组合优化问题,其中需要尝试不同的选择组合,直到找到最优解或者确定无解。
不同点:
- 剪枝策略:回溯法通常采用剪枝策略来优化搜索过程,通过判断当前路径是否符合要求,来决定是否继续搜索该路径的子路径。这样可以减少不必要的搜索,提高效率。而蛮力搜索则没有剪枝策略,会遍历所有可能的解空间。
- 可行解的判定:回溯法通常在搜索过程中动态地判断当前路径是否是一个可行解,如果是,则将其加入结果集中。而蛮力搜索则是在搜索结束后统一判断所有遍历到的解是否可行。
举
3、你觉得回溯法能用递归实现吗?如果能,请把你实现的一道题目改为回溯法的递归程序。
可以,本体中的0/1背包问题便是用递归的方式。