434
社区成员




1. 请用回溯法的方法分析“最小重量机器设计问题”
1.1 说明“最小重量机器设计问题"的解空间
有n个部件,每个部件有m个供应商可选。那么解空间的大小为m^n,即每个部件有m种选择,总共n个部件,所以总的可能性为m^n。
1.2 说明 “最小重量机器设计问题"的解空间树
解空间树的每一个节点代表一个部件的选择,如根节点代表第一个部件选择。解空间树的深度等于部件的数量,每个节点的子节点的数量等于供应商的数量。
在解空间树中,每条从根节点到叶子节点的路径代表一个机器设计方案,路径上经过的节点表示每个部件的供应商选择。
1.3 在遍历解空间树的过程中,每个结点的状态值是什么
当前解的价格cc
当前解的重量cw
w[t][i]代表第t层树的一个部件选择了i的供应商的重量
c[t][i]代表第t层树的一个部件选择了i的供应商的价格
1.4 如何利用限界函数进行剪枝
通过条件判断语句if(cw+w[t][i]<MinW&&cc+c[t][i]<=d)剪枝
即两个限制条件
1、当前解的重量加上添加部件的重量要小于当前最优的总重量
2、当前解的价格加上添加部件的价格一定要小于等于总价格d
代码如下
#include <iostream>
#include <cmath>
using namespace std;
const int INF=0x3f3f3f3f;
int n,m,d;
int MinW=INF;
int cw,cc;
int w[100][100];
int c[100][100];
int bests[100];
int s[100];
//t为零件,i为商家
void backtrack(int t)
{
if(t>n)
{
MinW=cw;
for(int i=1;i<=n;i++)
{
bests[i]=s[i];
}
}
else
{
for(int i=1;i<=m;i++)
{
s[t]=i;
if(cw+w[t][i]<MinW&&cc+c[t][i]<=d)
{
cw+=w[t][i];
cc+=c[t][i];
backtrack(t+1);
cw-=w[t][i];
cc-=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<<MinW<<endl;
for(int i=1;i<=n;i++)
{
cout<<bests[i]<<" ";
}
return 0;
}
2. 你对回溯算法的理解
一种穷举的方法,通过试探和回溯来遍历解空间,找到满足问题约束的解。时间复杂度通常很高,需要通过剪枝和限界函数约束。
一般解题步骤
(1)定义问题解空间(画出解空间树)至少包含问题一个最优解;
(2)确定易于搜索的解空间结构,用回溯法能方便搜索整个解空间;
(3)用深度优先搜索(DFS)搜索解空间,并在搜索过程中用剪枝函数避免无效搜索