算法第五章上机作业

算法第五章作业

问题描述:

设某一机器由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

参考代码:

#include <bits/stdc++.h>

using namespace std;

int m,n,d;

int c[100][100];

int w[100][100];

int count1=0;//价格

int weight=0;//重量

int minn =1000000;

int x[100];

int minx[100];

 

void backtrack(int t){

if(t>n){

if(weight < minn && count1 <= d) {

minn = weight;

for(int i = 1;i <= n;i++){

minx[i] = x[i];

}

}

        return;

}

else{

for(int i = 1;i <= m;i++){

if(c[t][i]+count1 <=d&&weight+ w[t][i] < minn){

x[t] = i;//i是供应商标记

count1 += c[t][i];

weight += w[t][i];

    backtrack(t+1);

    count1 -= c[t][i];

weight -= w[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<<minn<<endl;

for(int i = 1;i <= n;i++){

cout<<minx[i]<<" ";

}

return 0;

}

1.1 说明“最小重量机器设计问题"的解空间

解空间即进行穷举的搜索空间,包含所有的可能解,这里以样例为例写出解空间:

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 说明 “最小重量机器设计问题"的解空间树

   

 

 

1.3 在遍历解空间树的过程中,每个结点的状态值是什么

每个结点的状态值包括:该结点的重量weight、该结点的价格count

    

2. 你对回溯算法的理解

回溯算法解决问题的例子:n皇后问题,0-1背包问题,货郎问题。

 

这些问题的共同点是它们的解或者解集都是向量或者向量集,它们的搜索空间:树。可能是n叉树、子集树、排列树等。树的节点对应于部分向量,可行解在叶节点。 搜索方法有:DFSBFS,或者二者结合。

 

回溯算法适用于求解搜索问题和优化问题,它采用DFS/BFS隐含的遍历搜索树。

 

回溯算法的使用条件:多米诺性质,即:X1...Xn+1成立→X1...Xn成立,逆否命题也成立。

 

posted @ 2021-12-14 09:39  CarinaLing  阅读(72)  评论(0编辑  收藏  举报