算法第五章作业
1、我对回溯算法的理解
(1)基本概念:
回溯法可以系统地搜索一个问题的所有解或任一解,它是一个既带有系统性又带有跳跃性的搜索算法。具体指在问题的解空间树中,按深度优先策略,从根结点出发搜索解空间树,算法搜索至解空间树的任一结点时,先判断该结点是否包含问题的解——如果肯定不包含,则跳过对以该结点为根的子树的搜索,逐层向其祖先结点回溯;否则,进入该子树,继续按深度优先策略搜索。
(2)基本思想:
回溯法对任一解的生成,一般采用逐步扩大解的方式。每前进一步,都尝试在当前部分解的基础上扩大该部分解。它在问题的状态空间树中,从开始结点(根结点)出发,以深度优先策略搜索整个状态空间。这个开始结点成为活结点,同时也成为当前的扩展结点。在当前扩展结点处,搜索向纵深方向移至一个新结点。这个新结点成为新的活结点,并成为当前扩展结点。如果在当前扩展结点处不能再向纵深方向移动,则当前扩展结点就成为死结点。此时,应往回移动(回溯)至最近的活结点处,并使这个活结点成为当前扩展结点。回溯法以这种工作方式递归地在状态空间中搜索,直到找到所要求的解或解空间中已无活结点时为止。
2、“子集和”问题的解空间结构和约束函数
(1)解空间结构
正整数集合S={x1,x2,…,xn}对应的的一个子集S1,S1中的元素之和为c。
(2)约束函数
其约束函数为 if (sum + a[t] <= c)/ else ,如果加上当前结点的值小于问题所要求的子集和目标值,则向右子树深度优先搜索,否则向左子树深搜。
代码实现部分:
int sum_of_subset(int t,int *x) { static int sum=0; int left,right; if(sum==c) return t-1; if(t>n) return 0; rest-=a[t]; if(sum+a[t]<=c) { x[t]=1; sum+=a[t]; right=sum_of_subset(t+1,x); if(right) return right; sum-=a[t]; } if(sum+rest>=c) { x[t]=0; left=sum_of_subset(t+1,x); if(left) return left; } rest+=a[t]; return 0; }
3、在本章学习过程中遇到的问题及结对编程的情况
本章学习过程中遇到的比较明显的问题是对着部分题目不知道如何在短时间内写出相应的剪枝方式,例如,虽然有看过老师在课上演示的代码自己也动手认认真真做了,不过还是不太能理解和应用约束函数和限制函数。
这次结队编程我主要负责编写代码,恬萌和伟严主要负责梳理代码实现的思路,上机实践课整体完成度还不错。学习了回溯法之后,虽然我理解了这个算法的基本思路,看例题也能看懂,不过轮到自己实际操作的时候才发现想要在短时间内写出回溯法还真的挺难的,主要是平时练习编程的次数太少,以后仍要继续注重实践能力,忙着完成大作业的同时也要注重期末的复习和对所学知识的回顾,温故而知新。
浙公网安备 33010602011771号