算法第五章作业
1.问题描述
7-2 最小重量机器设计问题 (25 分)
设某一机器由n个部件组成,每一种部件都可以从m个不同的供应商处购得。设wij是从供应商j 处购得的部件i的重量,cij是相应的价格。 试设计一个算法,给出总价格不超过d的最小重量机器设计。
1 #include<iostream>
2 #include<iomanip>
3 #include<cmath>
4 using namespace std;
5
6 int n, m, d;
7 int w1,c1;
8 int ans[100]; //记录结果
9 int w[100][100];
10 int c[100][100];
11 int min_w = 10000000;
12 int t; // 节点
13 int x[100]; //记录选择的商家
14
15 void backtrack(int t)
16 {
17
18 //遍历完所有部件
19 if(t > n)
20 {
21 //更新最小值
22 if(w1 < min_w)
23 {
24 min_w = w1;
25 //记录选择的商家
26 for(int i = 1; i <= n; i++)
27 {
28 ans[i] = x[i];
29 }
30 }
31 return;
32 }
33
34 //遍历第t个部件应该使用哪一个商家的
35 for(int i = 1; i <= m; i++)
36 {
37 x[t] = i;
38 w1 += w[t][i];
39 c1 += c[t][i];
40 //约束条件:1、价格不超过d 2、价值总和小于等于现在的最小值
41 if(c1 <= d && w1 <= min_w)
42 {
43 //如果第i个商家符合条件,则开始遍历下一个部件的商家
44 backtrack(t+1);
45 }
46 //恢复父节点(上一个部件的选择)
47 w1 -= w[t][i];
48 c1 -= c[t][i];
49 }
50 }
51
52 int main()
53 {
54 cin >> n >> m >> d;
55 //输入价值
56 for(int i = 1; i <= n; i ++)
57 {
58 for(int j = 1; j <= m; j++)
59 {
60 cin >> c[i][j];
61 }
62 }
63 //输入重量
64 for(int i = 1; i <= n; i ++)
65 {
66 for(int j = 1; j <= m; j++)
67 {
68 cin >> w[i][j];
69 }
70 }
71 //开始回溯
72 backtrack(1);
73 cout << min_w << endl;
74 for(int i= 1;i <= n; i++)
75 {
76 cout << ans[i] << " ";
77 }
78 }
2 回溯法方法分析“最小重量机器设计问题”
2.1 用回溯法的方法分析“最小重量机器设计问题”
解空间-----穷举搜索空间(包含所有可能解)
以题目为样例写出解空间:
(1,1,1)(1,1,2)(1,1,3)
(1,2,1)(1,2,2)(1,2,3)
(1,3,1)(1,3,2)(1,3,3)
(2,1,1)(2,1,2)(2,1,3)
(2,2,1)(2,2,2)(2,2,3)
(2,3,1)(2,3,2)(2,3,3)
(3,1,1)(3,1,2)(3,1,3)
(3,2,1)(3,2,2)(3,2,3)
(3,3,1)(3,3,2)(3,3,3)
ps:(1,1,1)表示第1个部件选择第1个供应商,第2个部件选择第1个供应商,第3个部件选择第1个供应商
2.2 说明 “最小重量机器设计问题"的解空间树
2.3 在遍历解空间树的过程中,每个结点的状态值是什么
每个结点的状态值包括:该结点的重量weight、该结点的价格count
3.对回溯算法的理解
回溯法基本思想:
构建问题的解空间树,在其解空间树中,从根节点出发,进行深度优先搜索。在搜索过程中,对解空间树的每个结点进行判断,判断该结点是否包含问题的解,若肯定不包含,则跳过对以该结点为根的子树的搜索,逐层向其祖先结点回溯。否则,则进入该子树,继续按深度优先策略搜索。
3.1步骤:
①针对所给问题,定义其解空间;
②确定易于搜索的解空间结构;
③深度优先搜索其解空间,并在搜索过程中用剪枝函数避免无效搜索。
3.2回溯法:
按选优条件向前搜索,以达到目标。但当探索到某一步时,发现原先选择并不优或达不到目标,就退回一步重新选择,这种走不通就退回再走的技术为回溯法。
回溯算法解决问题:旅行售货员、n皇后问题、0-1背包问题。
3.3剪枝函数:
用 约束函数 在扩展结点处剪去不满足约束的子树
用 上界函数 剪去得不到最优解的子树