算法第五章上机实践报告
1. 请用回溯法的方法分析“最小重量机器设计问题”
n个零件,从第一个开始选1号厂家开始选,判断是否超出价格界限d,不超出这选择,若超出就看下个商家是否满足条件。每次选择一个零件就是在解空间树下了一层,直到到叶节点判断cv(当前选择下的价格),并且如果当前重量小于之前记录的最小质量,则更新最小质量mind的值。然后回溯到选择上一个零件的节点换一个商家。
可以用当前的总重量和价格与之前记录的最小值比较进行剪枝。
#include <iostream> using namespace std; int n,m,d; int x[100]; int bx[100]; int x1[100][100]; int x2[100][100]; int cc=0,cw=0; int minw=10000; void backtrack(int t){ if(t==n){ for(int i=1;i<=m;i++){ cc+=x1[t][i]; cw+=x2[t][i]; x[t]=i; if(cc<=d&&cw<minw){ minw=cw; for(int i=1;i<=n;i++)bx[i]=x[i]; } cc-=x1[t][i]; cw-=x2[t][i]; x[t]=0; } } else for(int i=1;i<=m;i++){ x[t]=i; cc+=x1[t][i]; cw+=x2[t][i]; if(cc<=d&&cw<minw)backtrack(t+1); cc-=x1[t][i]; cw-=x2[t][i]; x[t]=0; } } int main(){ cin>>n>>m>>d; for(int i=1;i<=n;i++) for(int j=1;j<=m;j++)cin>>x1[i][j]; for(int i=1;i<=n;i++) for(int j=1;j<=m;j++)cin>>x2[i][j]; backtrack(1); cout<<minw<<endl; for(int i=1;i<=n;i++) cout<<bx[i]<<" "; return 0; }
1.1 说明“最小重量机器设计问题"的解空间
因为第三个零件都是2的价格,所以第一和第二个零件只能为1,才能满足<=4这个条件。
解空间需满足题目条件,及{【1,3,1】,【1,3,2】,【1,3,3】}
1.2 说明 “最小重量机器设计问题"的解又空间树
解空间树就是总价格不超过d的所有解构成的数。深度为n,除了叶节点每个节点都有m个子节点(m个供应商就有m个选择)。节点记录的值为当前选择下的质量和价格。
1.3 在遍历解空间树的过程中,每个结点的状态值是什么
每个节点的状态值就是当前选择下的质量和价格。
2. 你对回溯算法的理解
我觉得回溯法是一种枚举法,它基于深度优先搜索每次选择,然后判断行不行,行就继续,不行就回退上一个重新选择。
虽算法思想较为好理解,但是对于较多数据选择的时候,时间复杂度就会相当的大了。所以进行剪枝是十分必要的操作。