算法第五章上机实践报告

1. 请用回溯法的方法分析“最小重量机器设计问题”

n个零件,从第一个开始选1号厂家开始选,判断是否超出价格界限d,不超出这选择,若超出就看下个商家是否满足条件。每次选择一个零件就是在解空间树下了一层,直到到叶节点判断cv(当前选择下的价格),并且如果当前重量小于之前记录的最小质量,则更新最小质量mind的值。然后回溯到选择上一个零件的节点换一个商家。

可以用当前的总重量和价格与之前记录的最小值比较进行剪枝。

#include <iostream>
using namespace std;
int n,m,d;
int x[100];
int bx[100];
int x1[100][100];
int x2[100][100];
int cc=0,cw=0;
int minw=10000;

void backtrack(int t){
    if(t==n){
        for(int i=1;i<=m;i++){
            
            cc+=x1[t][i];
            cw+=x2[t][i];
            x[t]=i;
            if(cc<=d&&cw<minw){
                minw=cw;
                for(int i=1;i<=n;i++)bx[i]=x[i];
            }
            cc-=x1[t][i];
            cw-=x2[t][i];
            x[t]=0;
        }
    }
    else for(int i=1;i<=m;i++){
            x[t]=i; 
            cc+=x1[t][i];
            cw+=x2[t][i];
            if(cc<=d&&cw<minw)backtrack(t+1);
            cc-=x1[t][i];
            cw-=x2[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>>x1[i][j];
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)cin>>x2[i][j];
    backtrack(1);
    cout<<minw<<endl;
    for(int i=1;i<=n;i++) cout<<bx[i]<<" ";
    return 0;
}

 

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

因为第三个零件都是2的价格,所以第一和第二个零件只能为1,才能满足<=4这个条件。

解空间需满足题目条件,及{【1,3,1】,【1,3,2】,【1,3,3】}

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

解空间树就是总价格不超过d的所有解构成的数。深度为n,除了叶节点每个节点都有m个子节点(m个供应商就有m个选择)。节点记录的值为当前选择下的质量和价格。

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

每个节点的状态值就是当前选择下的质量和价格。

2. 你对回溯算法的理解

我觉得回溯法是一种枚举法,它基于深度优先搜索每次选择,然后判断行不行,行就继续,不行就回退上一个重新选择。

虽算法思想较为好理解,但是对于较多数据选择的时候,时间复杂度就会相当的大了。所以进行剪枝是十分必要的操作。

posted @ 2021-12-11 11:07  涂一波  阅读(23)  评论(0编辑  收藏  举报