算法第五章作业

算法第五章作业

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);  //递归下一层  
        }  
}  
posted @ 2021-12-13 21:29  星辰若凡  阅读(53)  评论(0编辑  收藏  举报