算法第五章作业

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 

2.代码

#include <bits/stdc++.h>
using namespace std;
int n,m,d;
int w[40][40];//从供应商j 处购得的部件i的重量
int c[40][40];//cij是相应的价格
int x[40],X[40];//
int minw=100000;
int weight;
int dsum=0;//总价格

void backtrack(int t){
    if(t>n){//到达叶子节点
        if(weight<minw){//更新最优值
            minw=weight;
            for(int i=1;i<=n;i++){
                X[i]=x[i];//同时记录选择的厂商
            }
        }            
        return;
    }
    else{
            for(int i=1;i<=m;i++){
                if(dsum+c[t][i]<=d&&weight+w[t][i]<minw){//之前已选的总价格加上接下来要选的机器价格,之前已选的机器总重量加上接下来要选的机器重量,同时满足条件
                    x[t]=i;//此处t表示行,每一行用来表示第1~n个部件;i表示列,表示第t个部件选择的是第i个厂家
weight
+=w[t][i]; dsum+=c[t][i]; backtrack(t+1); weight-=w[t][i]; dsum-=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<<X[i]<<" "; } }

3.解空间

123分别对应ABC三个厂家

(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)

4.解空间树

 

 

5.每个节点的状态值

每个节点的状态值有weight表示已选部件总重量(该重量有包含当前节点部件的重量)和dsum表示已选部件总价格(也包含当前节点部件的价格)

6.对回溯法的理解

回溯法的基本思想是构建问题的解空间树,在其解空间树中,从根节点出发,进行深度优先搜索。在搜索过程中,对解空间树的每个结点进行判断,判断该结点是否包含问题的解,若肯定不包含,则跳过对以该结点为根的子树的搜索,逐层向其祖先结点回溯。否则,则进入该子树,继续按深度优先策略搜索。

在使用回溯法时,要注意用剪枝函数和限界函数避免不必要的尝试,从而提高算法的效率

 

posted @ 2021-12-14 23:31  白蔡  阅读(30)  评论(0编辑  收藏  举报