算法第五章作业
1.请用回溯法的方法分析“最小重量机器设计问题”
1.1 说明“最小重量机器设计问题"的解空间
对于n种部件,每一种部件有m种不同的供应商供选择,每一个供应商对每一种部件有对应的质量和价值。其解空间由长度为n的0-m向量组成。该解空间包含对变量所有可能的0-m赋值。当n=3,m=3时,其解空间如下:
{(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)}
1.2 说明 “最小重量机器设计问题"的解空间树
对于n个部件,m个供应商,其解空间树如下图所示,第i个节点的数字j表示第i个部件选择了第j个供应商提供的部件。
1.3 在遍历解空间树的过程中,每个结点的状态值是什么
每个结点有两个状态值,分别为当前节点在选择t个供应商后部件的总价值和总重量。
#include <iostream> using namespace std; int n,m,d; int w[31][31],c[31][31],gys[31],x[31]; int weight=0,money=0,minx=100000; bool Quick(int t) { if(money<=d&&weight<=minx) return true; else return false; } void Backtrack(int t) { if(t>n) { if(weight<minx) { minx=weight; for(int i=1;i<=n;i++) { gys[i]=x[i]; } } } else{ for(int i=1;i<=m;i++) { weight+=w[t][i]; money+=c[t][i]; x[t]=i; if(Quick(t)) Backtrack(t+1); weight-=w[t][i]; money-=c[t][i]; } } } int main() { cin>>n>>m>>d; for(int i=1;i<=n;i++) { for(int j=1;j<=m;j++) { cin>>c[i][j]; } } for(int i=1;i<=n;i++) { for(int j=1;j<=m;j++) { cin>>w[i][j]; } } Backtrack(1); cout<<minx<<endl; for(int i=1;i<=n;i++) cout<<gys[i]<<' '; return 0; }
2. 你对回溯算法的理解
回溯法的思路是把问题的解空间转化成了图或者树的结构表示,然后使用深度优先搜索策略进行遍历。首先从根节点出发搜索解空间树,当算法搜索至解空间树的某一节点时,先利用剪枝函数判断该节点是否能得到问题的解。如果不可行,则跳过对该节点为根的子树的搜索,逐层向其祖先节点回溯;否则,进入该子树,继续按深度优先策略搜索。我觉得回溯法和暴力穷举的差别主要在于,回溯算法在搜索过程使用剪枝函数去避免无效的搜索,在一定程度上提高了算法的效率。