算法第五章作业
算法第五章作业
1. 请用回溯法的方法分析“最小重量机器设计问题”
设某一机器由n个部件组成,每一种部件都可以从m个不同的供应商处购得。设wij是从供应商j 处购得的部件i的重量,cij是相应的价格。 试设计一个算法,给出总价格不超过d的最小重量机器设计。
输入格式:
第一行有3 个正整数n ,m和d, 0<n<30, 0<m<30, 接下来的2n 行,每行n个数。前n行是c,后n行是w。
输出格式:
输出计算出的最小重量,以及每个部件的供应商
输入样例:
3 3 4 1 2 3 3 2 1 2 2 2 1 2 3 3 2 1 2 2 2 结尾无空行
输出样例:
在这里给出相应的输出。例如:
4 1 3 1
1.1 说明“最小重量机器设计问题"的解空间
n个部件,m个不同的供应商,该问题的解空间由长度为n的 0 - 1向量组成。
1.2 说明 “最小重量机器设计问题"的解空间树
第t层到第t+1层代表第t个部件的供应商的选择,每个非叶子节点都有m个分支。
1.3 在遍历解空间树的过程中,每个结点的状态值是什么
cw: 当前的重量
cp: 当前的价格
整个算法代码:
#include<iostream>
using namespace std;
int n, m, d;
int c[30][30];
int w[30][30];
int array[30];
int results[30];
int cw = 0;
int cp = 0;
int bestw = 99999;
void backtrack(int t){
if (t > n) {
if (cw < bestw) {
bestw = cw;
for(int i = 1; i <= n; i++)
results[i] = array[i];
}
}
else{
for (int i = 1; i <= m; i++){
array[t] = i;
cp += c[t][i];
cw += w[t][i];
if (cp <= d && cw <= bestw){
backtrack(t + 1);
}
cp -= c[t][i];
cw -= w[t][i];
array[t] = 0;
}
}
}
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];
cp = 0;
cw = 0;
backtrack(1);
cout << bestw << endl;
for (int i = 1; i <= n; i++)
cout << results[i] << " ";
return 0;
}
2. 你对回溯算法的理解
回溯法一般是在集合中递归搜索,集合的大小构成了树的宽度,递归的深度构成的树的深度。应用回溯算法的三个步骤:1.首先得构造解空间树:子集树和排列树;2.以深度优先的方式搜索解空间:递归或迭代;3.设计剪枝函数避免无效搜索:使用约束函数,剪去不满足约束条件的路径或使用限界函数,剪去不能得到最优解的路径。
通用模板:
//针对N叉树的递归回溯方法
void backtrack (int t)
{
if (t > n) output(x); //叶子节点,输出结果,x是可行解
else
for i = 1 to k//当前节点的所有子节点
{
x[t] = value(i); //每个子节点的值赋值给x
//满足约束条件和限界条件
if (constraint(t)&& bound(t))
backtrack(t+1); //递归下一层
}
}