算法第五章作业

7-2 最小重量机器设计问题 (25 分)

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 

#include <bits/stdc++.h>
using namespace std;
int n;//部件个数
int m;//供货商个数
int d;//最大价格

int w[100][100];//价格
int c[100][100];//费用

int curc;//当前价格
int curw;//当前重量
int minw=100000;//最小重量
int minx[100];//最优解向量
int x[100];//当前解向量

void BackTrack(int t)
{
    if(t==n)//到达最后一层
    {
        for(int i=1; i<=m; i++)//遍历所有叶子节点
        {
            curw+=w[t][i];
            curc+=c[t][i];
            x[t]=i;
            if(curc<=d&&curw<minw)//若费用不超过最大费用并且重量小于之前的最优解
            {
                //更新最优解
                minw=curw;
                for(int j=1; j<=n; j++)
                    minx[j]=x[j];
            }
            curc-=c[t][i];//返回上一层
            curw-=w[t][i];
            x[t]=0;
        }
    }
    else//未到达最后一层
    {
        for(int i=1; i<=m; i++)//遍历该层节点
        {
            x[t]=i;
            curw+=w[t][i];
            curc+=c[t][i];
            if(curc<d&&curw<minw)//费用小于最小费用重量小于最优解时进入下一层
            {
                BackTrack(t+1);
            }
            curc-=c[t][i];//返回上一层
            curw-=w[t][i];
            x[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];
        }
    }
    BackTrack(1);
    cout<<minw<<endl;
    for(int i=1; i<=n; i++)
    {
        cout<<minx[i]<<" ";
    }
}

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,1,1)表示三个零件均选择第一个供应商。

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

 

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

每个节点的状态是其对应的重量和价值

 

2. 你对回溯算法的理解

原理:

回溯法是一种选优搜索法,按选优条件向前搜索,以达到目标。但当探索到某一步时,发现原先选择并不优或达不到目标,就退回一步重新选择。这种走不通就退回再走的技术为回溯法

应用回溯算法的三个步骤:

1.首先得构造解空间树:子集树和排列树;

2.以深度优先的方式搜索解空间:递归或迭代;

3.设计剪枝函数避免无效搜索:使用约束函数,剪去不满足约束条件的路径或使用限界函数,剪去不能得到最优解的路径。

回溯法解问题的一个显著特征是,解空间树是虚拟的,在任何时候,只需保存从根节点到当前扩展结点的路径。

在回溯问题中,若要求问题的所有解,就要回溯到根。

 

posted @ 2021-12-16 17:14  Dtsuki  阅读(91)  评论(0编辑  收藏  举报