代码改变世界

算法第五章作业

2019-12-15 13:27  绮罗生  阅读(122)  评论(0)    收藏  举报

1.什么是回溯法?

回溯法,顾名思义就是回到曾经的结点的一种算法。在我的理解当中,回溯法就是我们在列出一系列解时,需要有抉择,假设我现在有两条路可以选择,我选择了第一条后发现这条路并不一定比第二条好,所以用回溯法返回到上一次选的的路径,然后再继续进行下去。

回溯法如果要遍历一遍的话效率会很低,所以为了提高效率我们要适当地使用“剪枝”地方法使得它能够在面对某些情况时少走一些“冤枉路”,剪枝又分为宽松型和严格型,都能提高回溯法的效率,只不过严格回溯效率会更高。在解决某一个问题时如果可以使用回溯法,也可以使用动态规划,具体问题具体分析,看使用哪一种方法效率更高。

 

2.请说明“子集和”问题的解空间结构和约束函数。

解空间结构:

正整数集合S={x1,x2,…,xn}对应的的一个子集S1,S1中的元素之和为c。

约束函数:

其约束函数为 if (sum + a[t] <= c)/ else ,如果加上当前结点的值小于问题所要求的子集和目标值,则向右子树深度优先搜索,否则向左子树深搜。

 

代码实现:

 1 #include<iostream>
 2 using namespace std;
 3 
 4 #define N 10000
 5 
 6 int n, c, rest = 0;
 7 
 8 int a[N];
 9 int x[N];
10 int sum = 0;
11 
12 int backtrack(int t)
13 {    
14     if (sum == c) return t; 
15     //若当前结点的累计值为c,说明当前结点的路径就是相应子集,返回当前结点深度 
16     
17     if(t > n) return 0; 
18     //sum!=c && 到达叶子结点,说明该叶子的路径不是我们要找的子集 ,故返回0 
19     
20     rest -= a[t];//rest=a[t+1:n]     
21     if(sum + a[t] <= c) //1号分支 
22     {
23         x[t] = 1;
24         sum += a[t];
25         int level = backtrack(t + 1);
26         if (level > 0) return level;
27         sum -= a[t];
28     }
29     
30     if( sum + rest >= c ) //0号分支 
31     {
32          x[t]=0;
33         int level = backtrack(t + 1);
34         if (level > 0) return level; 
35         //level只有两种情况:0、非0
36         //0表示该分支的所有遍历都找不到相应的子集
37         //非0表示在该分支找到子集了,故往上层函数返回level值,以让上层函数继续往上层返回,达到马上结束递归的作用。 
38     }
39     rest += a[t];
40     
41     return 0;
42 }
43 
44 int main()
45 {    
46     cin >>n >> c;
47 
48     for (int i = 1; i <= n; i++) 
49     {
50         cin >> a[i];
51         rest += a[i];
52     }
53     for (int i = 0; i <= n; i++)
54         x[i] = 0;
55     sum = 0;
56     int level = backtrack(1);
57     if(level > 0) //若level非0,说明找到了相应子集,该子集的路径深度为level
58     {
59         for(int i = 1; i < level; i++) 
60            if (x[i]) cout << a[i] << " ";
61         cout << endl;
62     }
63     else cout << "No Solution!";
64     return 0;
65 }

 

3.请说明在本章学习过程中遇到的问题及结对编程的情况。

在理解回溯法的时候觉得很简单,但自己亲手实践发现还是有困难。尤其是自己实现“剪枝”算法的时候觉得并没有想象中那么容易。

结对编程和伟严卓蓉一起,还是感觉从她们身上学到了很多。