算法设计与分析/数据结构与算法实验6:0-1背包问题(回溯法)

简介: 算法设计与分析/数据结构与算法实验6:0-1背包问题(回溯法)

1.实验目的

(1)掌握回溯法的处理思路与算法框架。

(2)掌握应用回溯法解决具体问题的方法。

(3)掌握回溯法的广泛应用。

2.实验内容

(1)问题描述

image.png


要求使用回溯法解决该问题。

(2)输入

image.png


(3)输出

image.png


3.问题实例分析

image.png


因此,先装入第一个物品,此时体积足够装入第二个物品。装完第二个物品后,还能在装第三个物品。以深度优先的顺序,此时访问到的解空间树的结点如图所示:

注意:我自己都觉得图太丑了,大家画图时不要为了方便用wps自带的画图工具画!!!还是visio好!!!

image.png

image.png


从该结点回溯到上一结点,并在访问右子树前分别计算每个结点的当前价值cp与剩余价值r,发现都可以将右子树直接剪枝剪掉。

image.png

image.png

image.png


4.算法描述及说明

正如第3节问题实例分析所述,算法的整体流程如下:

1.输入数据,并对每个物品进行编号。

2.计算每个物品的单位价值,并将物品按单位价值排序。

3.对于第i ii个物品,判断剩余体积是否能够装下该物品。

4.若能装下该物品,则将该物品装入,并构造相应结点。

5.若不能装入该物品,则不将该物品装入,考虑下一物品。

6.在第4步中的物品撤出背包,构造相应结点,并计算剩余物品能产生价值的上界。若上界大于当前最优解,则装入考虑下一物品,否则不考虑。

7.重复3-6的步骤,直到所有物品都被考虑过。

5.算法正确性分析

算法会正确地结束:在遍历完解空间后,找到了使总价值最大的解,算法会停止。

回溯法的正确性分析:开始时,根结点是解空间树唯一的活结点,也是当前的扩展结点。在这个扩展结点处,搜索向深度方向移至一个新节点。这个新结点成为新的扩展结点。如果在当前扩展结点处不能再向纵深方向移动,则当前扩展结点成为死结点。应回溯至最近的活结点处,使得这个活结点成为当前扩展结点。回溯法以系统的方式递归地在解空间树中进行搜索,直到找到所要求的解惑解空间中已无活结点。

因此,利用回溯法会系统地查找背包问题的所有可行解,在剪枝时利用限界函数与剪枝函数剪去了不可行的分支,保留了可行并能产生最大解的分支。

从而,该算法是正确的。

6.算法时间复杂性分析

image.png

7.运行结果展示及其说明

image.png

8.心得体会

9.程序源代码

#include<iostream>
#include<algorithm>
using namespace std;
double cw;//当前重量
double cp;//当前价值
double bestp;//当前最优价值
int n;//物品数量
double c;//背包容量
const int N = 105;
int x[N];
struct Bag {
  double w, v;
  int id, x;
};
Bag bag[N];
bool cmp(Bag a, Bag b) {
  return (a.v / a.w) > (b.v / b.w);
}
double bound(int i) {
  double cleft = c - cw;
  double bd = cp;
  while (i <= n && bag[i].w <= cleft) {
    cleft -= bag[i].w;
    bd += bag[i].v;
    i++;
  }
  if (i <= n)
    bd += bag[i].v * cleft / bag[i].w;
  return bd;
}
void dfs(int i) {
  if (i > n) {
    bestp = cp;
    for (int i = 1; i <= n; i++) 
        x[bag[i].id] = bag[i].x;
    return;
  }
  if (cw + bag[i].w <= c) {
    cw += bag[i].w;
    cp += bag[i].v;
    bag[i].x = 1;
    dfs(i + 1);
    cw -= bag[i].w;
    cp -= bag[i].v;
    bag[i].x = 0;
  }
  if (bound(i + 1) > bestp)
    dfs(i + 1);
}
int main() {
  cin >> n >> c;
  for (int i = 1; i <= n; i++)
    cin >> bag[i].w;
  for (int i = 1; i <= n; i++)
    cin >> bag[i].v;
  for (int i = 1; i <= n; i++)
    bag[i].id = i;
  sort(bag + 1, bag + 1 + n, cmp);
  dfs(1);
  cout << bestp<<endl;
  for (int i = 1; i <= n; i++)
    cout << x[i] << " ";
  return 0;
}


目录
相关文章
|
18天前
|
JSON 监控 算法
员工上网行为监控:利用Scala编写数据处理和分析算法
企业在数字化时代利用Scala进行员工上网行为监控,以确保合规和网络安全。通过Scala的数据处理和分析能力,读取CSV日志数据转换为DataFrame,分析员工行为,如统计最常访问网站。此外,还展示了将监控数据以JSON格式提交至公司网站的函数,实现实时信息更新与安全防护。
62 5
|
4天前
|
机器学习/深度学习 存储 算法
数据结构与算法 动态规划(启发式搜索、遗传算法、强化学习待完善)
数据结构与算法 动态规划(启发式搜索、遗传算法、强化学习待完善)
11 1
|
6天前
|
机器学习/深度学习 自然语言处理 算法
Python遗传算法GA对长短期记忆LSTM深度学习模型超参数调优分析司机数据|附数据代码
Python遗传算法GA对长短期记忆LSTM深度学习模型超参数调优分析司机数据|附数据代码
|
7天前
|
搜索推荐 C语言
【C语言/数据结构】排序(归并排序|计数排序|排序算法复杂度)
【C语言/数据结构】排序(归并排序|计数排序|排序算法复杂度)
11 0
|
7天前
|
存储 算法
Leetcode 30天高效刷数据结构和算法 Day1 两数之和 —— 无序数组
给定一个无序整数数组和目标值,找出数组中和为目标值的两个数的下标。要求不重复且可按任意顺序返回。示例:输入nums = [2,7,11,15], target = 9,输出[0,1]。暴力解法时间复杂度O(n²),优化解法利用哈希表实现,时间复杂度O(n)。
19 0
|
12天前
|
机器学习/深度学习 算法 数据可视化
Matlab决策树、模糊C-均值聚类算法分析高校教师职称学历评分可视化
Matlab决策树、模糊C-均值聚类算法分析高校教师职称学历评分可视化
|
13天前
|
存储 索引
操作数栈的字节码指令执行分析
操作数栈的字节码指令执行分析
|
13天前
|
存储 算法 Java
22个常用数据结构实现与原理分析
前两天V哥跟一个老学员吃饭,聊起面试大厂的事,说为啥大厂面试第一看基本条件,第二就是考数据结构算法,其他高阶的内容会比较少,最近V哥也在跟大厂对接这一块业务,了解得多一些,这是因为考察基本功能力被放到了重要位置,大厂认为硬性条件,比如学历过关,基本功够扎实,那对于实际工作用的上层技能,内部培养就好,也就是相比你掌握了多少多少牛逼的高阶技术,他们更在乎你的基本功,所以,进大厂,基本功必须要搞稳,否则白扯,今天 V 哥把总结好的22个常用的数据结构实现原理,和示例分析分享给大家,希望对你有帮助,觉得内容有收获,请帮忙转发给更多需求的朋友,共同进步。
|
14天前
|
算法 搜索推荐 数据挖掘
MATLAB模糊C均值聚类FCM改进的推荐系统协同过滤算法分析MovieLens电影数据集
MATLAB模糊C均值聚类FCM改进的推荐系统协同过滤算法分析MovieLens电影数据集
|
14天前
|
算法 数据可视化 数据挖掘
数据分享|R语言改进的K-MEANS(K-均值)聚类算法分析股票盈利能力和可视化
数据分享|R语言改进的K-MEANS(K-均值)聚类算法分析股票盈利能力和可视化