我是靠谱客的博主 悲凉溪流,最近开发中收集的这篇文章主要介绍算法设计与分析第五章作业1. 请用回溯法的方法分析“最小重量机器设计问题”2. 你对回溯算法的理解,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

目录

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

 最小重量机器设计问题描述

问题描述:

输入格式:

输出格式:

输入样例:

输出样例:

回溯法的基本步骤:

常用剪枝函数:

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

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

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

1.4 代码

2. 你对回溯算法的理解


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

 最小重量机器设计问题描述

问题描述:

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

输入格式:

第一行有3 个正整数n ,m和d, 0<n<30, 0<m<30, 接下来的2n 行,每行m个数。前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 

回溯法的基本步骤:

        (1)针对所给问题,定义问题的解空间;

        (2)确定易于搜索的解空间结构;

        (3)以深度优先方式搜索解空间,并在搜索过程中用剪枝函数避免无效搜索

常用剪枝函数:

        用约束函数在扩展结点处剪去不满足约束的子树;

        用限界函数剪去得不到最优解的子树。

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

        理解问题:一共购置n个部件,每个部件可以从m个供应商手中获得,故每个部件有m中选择。

所有可能结果:

{1, 1, ……,1}、{2, 1, ……,1}、{3, 1, ……, 1}

  ……

{m,m,……,m}  

每个大括号里一共n个数字,对应n个部件,取值从1到m对应m个供应商,每个部件都分别有m种可能的选择,一共有m^n种可能的结果。

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

        不剪枝看,这棵解空间树是一棵m叉树,一共n层,第几层结点的状态值就对应第几个部件的选择,是哪个供应商;添加剪枝函数,使得该树被剪枝,删去不满足价格小于d以及得不到最优解的可能,最终使得整体在满足价格不超过d的条件下购置n个商品的最小重量。

剪枝函数:

        约束函数contains():满足当前已购置商品的价格不超过d

        限界函数bound():判断当前已购置商品的重量不会超过已获得的最优解(价格不超过d条件下的最小重量),如果超过了,则不用再往下遍历该结点了,肯定得不到最优解,回溯看上一步选择其他值是否可能得到最优解。

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

        假设该结点是第i层的结点,同时该结点的值为j,表示状态为第i个部件选择在第j个供应商处购置。

1.4 代码

#include <iostream>
using namespace std;
int n; // n个部件
int m; // m个供应商
int w[30][30];
// w[i][j]:从供应商j处购得部件i的重量
int c[30][30];
// c[i][j]:从供应商j处购得部件i的价格
// 1 <= i <= n ; 1 <= j <= m
int x[30], bestx[30];
// 1到n个部件分别选择的供应商
int leastw = 0x3f3f3f3f;
// 预算d条件下购置n个部件的最小重量
int cw;
// 当前重量
int cost;
// 当前价格
int d;
// 总价格不超过d
bool contains(int t) { // 限界
return (cost + c[t][x[t]] <= d);
}
bool bound(int t) {
return (cw + w[t][x[t]] < leastw);
}
void backtrack(int t) { // 依次判断1到n个部件
if(t > n) {
if(cw < leastw) {
leastw = cw;
for(int i = 1; i <= n; i++)
bestx[i] = x[i];
}
return;
}
for(int i = 1; i <= m; i++) { // 依次观察m个供应商
x[t] = i;
if(contains(t) && bound(t)) {// 剪枝:价格小于d条件下,重量尽可能小
cost += c[t][x[t]];
cw += w[t][x[t]];
backtrack(t+1);
cost -= c[t][x[t]];
cw -= w[t][x[t]];
}
}
}
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 << leastw << endl;
for(int i = 1; i <= n; i++) {
cout << bestx[i] << " ";
}
}

2. 你对回溯算法的理解

        目前我所学过的解空间树分为子集树、排列树和n叉树(最小重量机器设计问题),思想都大致相同,像是“试错”,把每种可能的结果走一遍,不行(用剪枝函数)或到叶子结点就回溯,继续看另一种结果是否可以获得想要的结果。

        我目前写代码的步骤,首先是把所有可能的结果都想到,构建解空间;之后是将所有可能的结果在一棵解空间树上体现出来;最后是用深度搜索的方法遍历解空间树,同时根据需要采用剪枝函数,删去不可行结果和减少遍历时间,当遍历完,答案也就出来了。

       

最后

以上就是悲凉溪流为你收集整理的算法设计与分析第五章作业1. 请用回溯法的方法分析“最小重量机器设计问题”2. 你对回溯算法的理解的全部内容,希望文章能够帮你解决算法设计与分析第五章作业1. 请用回溯法的方法分析“最小重量机器设计问题”2. 你对回溯算法的理解所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(37)

评论列表共有 0 条评论

立即
投稿
返回
顶部