计算机算法分析与设计(22)---回溯法(最小重量机器设计问题)

文章目录


一、问题描述

 设某一机器由 n n n 个部件组成,每种部件都可以从 m m m 个不同的供应商处购得。设 w i j w_{ij} wij 是从供应商 j j j 处购得的部件i的重置, c i j c_{ij} cij 是相应的价格。设计一个算法,给出总价格不超过 d d d 的最小重量机器设计。

数据输入:

第 1 1 1 行有 3 3 3 个正整数 n n n, m m m 和 d d d。接下来的 2 n 2n 2n 行,每行 n n n 个数。前 n n n 行是 c c c,后 n n n 行是 w w w。

数据输出:

输出计算的最小重量及每个部件的供应商。

二、算法思路

 1. 采用回溯法。因为每个商品可以从 m m m 个供货商获得,则问题的解空间树是一棵 m m m 叉树,该树属于子集树而非排列树。

 2. 然后考虑剪枝条件,此问题中的限制条件为价格上限 c c c,最小重量设 b e s t w bestw bestw,则当前价格 c c < c cc<c cc<c 且 当前重量 c w < b e s t w cw< bestw cw<bestw 时,执行树的深度遍历,否则,执行回溯,因此本问题中包含两个剪枝条件。

 3. 最后是更新最优值,以及问题的解,本题中最优解是 b e s t w bestw bestw,解集合是 x i xi xi。递归出口处更新一种最优解,以及对应解集合。

三、代码编写

输入样例:

3 3 4

1 2 3

3 2 1

2 2 2

3 3 4

1 2 3

3 2 1

2 2 2

输出样例:

4

1 3 1

cpp 复制代码
#include<iostream>
using namespace std; 
#define maxn 110
 
int w[maxn][maxn];
int c[maxn][maxn];
int bestx[maxn];
int x[maxn];
int n, m, d;
int cw = 0, cc = 0, bestw = 0x3f3f3f3f;
 
void Backtrack(int t) {
    if (t > n) 
	{
        bestw = cw;
        for (int i = 1; i <= n; i++)
            bestx[i] = x[i];
    }
	else 
	{
        for (int i = 1; i <= m; i++) 
		{
            if (cc + c[t][i] <= d && cw + w[t][i] < bestw) 
			{
                x[t] = i;
                cc += c[t][i];
                cw += w[t][i];
                Backtrack(t + 1);
                cc -= c[t][i];
                cw -= w[t][i];
            }
        }
    }
}
 
int main() {
    cout<<"请依次输入部件数,供应商数,限定价格:" << endl;
    cin>> n >> m >> d;
    
    cout<<"请输入各部件的在不同供应商的重量:" << endl;
    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= m; j++)
            cin>>w[i][j];
            
    cout<<"请输入各部件的在不同供应商的价格:" << endl;
    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= m; j++)
            cin>>c[i][j];
            
    Backtrack(1);
    cout<<"最小重量为:" << bestw << endl;
    cout<<"每个部件的供应商:" << endl;
    for (int i = 1; i <= n; i++)
    {
    	if(i==1) cout<<bestx[i]<<" "; 
        else cout<<bestx[i]<<" ";
	}
        
    return 0;
}
相关推荐
运维大师12 分钟前
【K8S 运维实战】31-Helm包管理
运维·算法·kubernetes
烬羽25 分钟前
一个队列,怎么让滑动窗口从 O(nk) 变 O(n)?单调队列彻底搞懂
javascript·数据结构·算法
XH华33 分钟前
C++语言第四章:模板初阶
数据结构·c++·算法
纳兰青华34 分钟前
拼图大师:从“暴力尝试“到“动态规划“的拆字艺术
java·算法·动态规划
我不是懒洋洋37 分钟前
从零实现一个分布式流处理:Apache Flink的核心设计
c++
2401_8697695942 分钟前
C/C++常识
c++
星马梦缘43 分钟前
算法设计导论 课堂笔记
算法·动态规划·分治·时间复杂度·最优二叉树
j7~2 小时前
【Linux】二十六.线程篇三《Linux多线程编程:线程控制、线程ID以及进程地址空间分布、线程局部存储__thread以及clone系统调用》---详解
linux·运维·服务器·开发语言·c++·多线程编辑·线程的控制
luj_176811 小时前
星火科技助力边远地区防病攻坚
c语言·开发语言·c++·经验分享·算法
zmzb010312 小时前
C++课后习题训练记录Day175
开发语言·c++