1背包问题

1.1基于动态规划的01背包问题算法实现

问题描述:

动态规划算法实现(Java):

import java.util.Scanner;public class Packageof01 {public static void main(String[] args) {Scanner sc = new Scanner(System.in);//m为背包总容量,n为物品数量。int m = sc.nextInt();int n = sc.nextInt();/*carry数组:动态规划得到的最优方案weight数组:各个物品的重量value数组:每个物品的价值result:背包能装下的最大价值*/int[][] carry = new int[n+1][m+1];int[] weight = new int[n+1];int[] value = new int[n+1];//输入每个物品的重量、价值。for (int i = 1; i <= n; i++) {weight[i] = sc.nextInt();value[i] = sc.nextInt();}//按物品重量与背包容量升序,按照当前容量能装下当前物品的最大价值,// 更新carry数组(物品重量与背包容量向下兼容)。for (int i = 1; i <= n; i++) {for (int j = 1; j <= m; j++) {if (weight[i] > j)carry[i][j] = carry[i - 1][j];else {carry[i][j] = Math.max(carry[i - 1][j], value[i] + carry[i - 1][j - weight[i]]);}}}//输出最优解/*10 42 13 34 57 9*/for(int i=0; i<=n;i++){for(int j=0; j<=m;j++){System.out.print(carry[i][j]+" ");}System.out.println();}System.out.println("在背包容量为"+m+"的情况下,"+"所能装下物品的最大价值为:"+carry[n][m]);}
}

代码运行结果:

0 0 0 0 0 0 0 0 0 0 0
0 0 1 1 1 1 1 1 1 1 1
0 0 1 3 3 4 4 4 4 4 4
0 0 1 3 5 5 6 8 8 9 9
0 0 1 3 5 5 6 9 9 10 12
在背包容量为10的情况下,所能装下物品的最大价值为:12

时间复杂度:O(n^2)

1.2 基于贪心算法实现的部分背包问题

问题描述:对于每一个物品,可以选择放入物品全部或者物品的一部分,这种情况下选择物品的价值/物品的重量作为权重,按照权重将物品降序排序,首先放入权重最大的物品,直到不能完全放入一个物品,此时放入该物品的一部分。

贪心算法代码实现(Java):

import java.util.Scanner;public class Package0fpart {
//创建物品类,包括物品重量、价值、是否全部放入背包、物品的权重(p=value/weight)public static class goods {int weight;int value;float n;float p;}public static void Greedy(goods[] a, int n, int v) {for (int i = 0; i < n; i++) {if (v > a[i].weight) { //当物品能放入背包时,将物品全部放入背包a[i].n = 1;v -= a[i].weight;} else if (v > 0) {//当物品无法全部放入背包时,放入一部分物品a[i].n = (float) v / a[i].weight;v = 0;}}}//插入排序算法实现物品排序public static void sort(goods[] arr) {if (arr.length >= 2) {for (int i = 1; i < arr.length; i++) {//挖出一个要用来插入的值,同时位置上留下一个可以存新的值的坑goods x = arr[i];int j = i - 1;//在前面有一个或连续多个值比x大的时候,一”直循环往前面找,将x插入到这串值前面while (j >= 0 && arr[j].p < x.p) {//当arr[j]比x小的时候,将j向后移一位,正好填到坑中arr[j + 1] = arr[i];j--;//将x插入到最前面arr[i + 1] = x;}}}}public static void main(String[] args) {Scanner sc = new Scanner(System.in);System.out.println("请输入物品数量及背包容量:");int n = sc.nextInt();int v = sc.nextInt();goods[] a = new goods[n]; //创建goods类数组并实例化for (int i = 0; i < n; i++)a[i] = new goods();for (int i = 0; i < n; i++) {System.out.println("请输入第" + (i + 1) + "个物品的重量及价值: ");a[i].weight = sc.nextInt();a[i].value = sc.nextInt();a[i].p = (float) a[i].value / a[i].weight;}sort(a);Greedy(a, n, v);int sumOfvalue = 0;int sumOfweight = 0;for (int i = 0; i < n; i++) {if (a[i].n == 0.0)break;sumOfweight += (a[i].weight * a[i].n);sumOfvalue += (a[i].value * a[i].n);System.out.println("装入背包的第" + (i + 1) + "个物品为: ");System.out.println("重量: " + a[i].weight + "价值:" + a[i].value + "完整 / 部分:" + a[i].n);System.out.println("背包装入的总价值: " + sumOfvalue);System.out.println("背包装入的总重量:" + sumOfweight);}}
}

程序运行结果:

请输入物品数量及背包容量:
3
50
请输入第1个物品的重量及价值:
10
60
请输入第2个物品的重量及价值:
20
100
请输入第3个物品的重量及价值:
30
120
装入背包的第1个物品为:
重量: 10 价值:60 完整 / 部分:1.0
背包装入的总价值: 60
背包装入的总重量:10
装入背包的第2个物品为:
重量: 20 价值:100 完整 / 部分:1.0
背包装入的总价值: 160
背包装入的总重量:30
装入背包的第3个物品为:
重量: 30 价值:120 完整 / 部分:0.6666667
背包装入的总价值: 240
背包装入的总重量:50进程已结束,退出代码0

时间复杂度:O(n)

1.3 基于动态规划实现的完全背包问题

问题描述:对于每一个物品,其数量是无限的,对于背包容量不同的情况下,对于同一个物品,考虑放入数量为k的不同价值情况(k=0、1、2...n),选择价值最大的放置情况更新最大价值数组,直到所有的物品均被选择过。

动态规划代码实现(Java):

import java.util.Scanner;public class PackageofAll {public static void main(String[] args) {Scanner sc = new Scanner(System.in);int n = sc.nextInt();int m = sc.nextInt();int[][] f = new int[n + 1][m + 1]; // f数组表示物品数量为i、背包容量为j的情况下的最大价值int[] v = new int[n]; // n个物品的体积int[] w = new int[n]; // n个物品的价值int a = 0;while (sc.hasNextLine() && a != n) {v[a] = sc.nextInt();w[a] = sc.nextInt();a++;}for (int i = 1; i <= n; i++) {for (int j = 0; j <= m; j++) {for (int k = 0; k * v[i - 1] <= j; k++) {f[i][j] = f[i - 1][j]; // 当背包放不下当前物品时,f取不放入该物品时的最大价值if (j >= v[i - 1])     // 当背包能放下当前物品时,考虑不放入该物品与放入该物品之间的最大值f[i][j] = Math.max(f[i - 1][j], f[i - 1][j - k * v[i - 1]] + k * w[i - 1]);}}}for (int i = 0; i <= n; i++) {for (int j = 0; j <= m; j++) {System.out.print(f[i][j] + " ");}System.out.println();}System.out.println(f[n][m]); //f数组最后一位为所有情况下的最大价值,因为背包容量越大,背包容纳的价值也越大。}
}

程序运行结果:

3
4
1 15
3 20
4 30
0 0 0 0 0
0 15 30 45 60
0 15 30 45 60
0 15 30 45 60
60进程已结束,退出代码0

时间复杂度:O(n^3)

2 针对背包问题的动态规划算法优化

2.1 针对01背包问题的一维数组优化

问题描述:对于01背包问题,可以考虑将二维结果数组变为一维数组,数组下标表示背包容量,数组数值表示该背包容量下的最大价值,代码改进如下:

import java.util.Scanner;public class Packageof01 {public static void main(String[] args) {Scanner sc = new Scanner(System.in);//m为背包总容量,n为物品数量。int m = sc.nextInt();int n = sc.nextInt();/*carry数组:动态规划得到的最优方案weight数组:各个物品的重量value数组:每个物品的价值result:背包能装下的最大价值*/int[] carry = new int[m + 1];int[] weight = new int[n + 1];int[] value = new int[n + 1];//输入每个物品的重量、价值。for (int i = 1; i <= n; i++) {weight[i] = sc.nextInt();value[i] = sc.nextInt();}//按物品重量与背包容量升序,按照当前容量能装下当前物品的最大价值,// 更新carry数组(物品重量与背包容量向下兼容)。for (int i = 0; i <= n; i++) {for (int j = m; j >= weight[i]; j--) {// 背包容量逆序遍历,防止重复选取物品,j>=物品重量,过滤掉放不下的情况carry[j] = Math.max(carry[j], value[i] + carry[j - weight[i]]);}}for (int j = 0; j <= m; j++) {System.out.print(carry[j] + " ");}System.out.println();System.out.println("在背包容量为" + m + "的情况下," + "所能装下物品的最大价值为:" + carry[m]);}
}

程序运行结果:

10 4
2 1
3 3
4 5
7 9
0 0 1 3 5 5 6 9 9 10 12
在背包容量为10的情况下,所能装下物品的最大价值为:12进程已结束,退出代码0

时间复杂度:O(m*n)

2.2 针对完全背包问题的一维数组优化

与01背包问题类似,可以考虑用一维数组压缩空间,与01背包不同的是,完全背包的背包容量需要顺序遍历,用到当前物品的不同数量已经考虑过的情况。程序实现如下:

import java.util.Scanner;public class PackageofAll {public static void main(String[] args) {Scanner sc = new Scanner(System.in);int n = sc.nextInt();int m = sc.nextInt();int[] f = new int[m + 1]; // f数组表示物品数量为i、背包容量为j的情况下的最大价值int[] v = new int[n]; // n个物品的体积int[] w = new int[n]; // n个物品的价值int a = 0;while (sc.hasNextLine() && a != n) {v[a] = sc.nextInt();w[a] = sc.nextInt();a++;}for (int i = 1; i <= n; i++) {for (int j = v[i-1]; j <= m; j++) {// 背包容量从能放下物品开始遍历,降低时间复杂度f[j] = Math.max(f[j], f[j - v[i - 1]] + w[i - 1]);}}for (int j = 0; j <= m; j++) {System.out.print(f[j] + " ");}System.out.println();System.out.println(f[m]); //f数组最后一位为所有情况下的最大价值,因为背包容量越大,背包容纳的价值也越大。}
}

程序运行结果:

3
4
1 15
3 20
4 30
0 15 30 45 60
60进程已结束,退出代码0

时间复杂度:可以看到,经过一维数组优化的算法,只需两次遍历就能求得最大价值,并且背包容量从能放下物品的容量开始遍历,所以总体时间复杂度为:O(m*n)

算法设计与分析结课论文相关推荐

  1. 算法设计与分析实验课(2)

    第1关:0/1 背包(枚举法) 本关任务: 问题 给定n个重量为{w1,w2,···,wn}.价值为{v1,v2,···,vn}的物品和一个容量为C的背包,0/1背包是一个求解这些物品中的一个最有价值 ...

  2. 计算机算法课程论文设计与实现,算法设计与分析课程论文

    算法设计与分析课程论文 "卓越工程师教育培养计划"(简称卓越计划)旨在培养一批创新能力强.适应经济社会发展需要的高质量工程技术人才.在南通大学计算机科学与技术学院制定的软件工程专业 ...

  3. 天津理工大学研究生学位课《算法设计与分析》期末大作业

    2022- 2023学年度第一学期 研究生学位课< 算法设计与分析 > 期末大作业 2022级电子信息天理研究生 一.简答题 1.若,写出用Θ.Ω和О描述f(n) 的渐进表达.(7分) 答 ...

  4. 算法设计与分析:贪心算法 - 排课问题(DP与贪心的区别与应用)

    文章目录 前言 贪心算法概念 排课问题 问题描述与分析 动态规划求解 简化问题应用贪心算法 总结 本文参考UCAS卜东波老师算法设计与分析课程撰写 前言 前面两大章节的内容分治思想与动态规划暂时告一段 ...

  5. 算法设计与分析(屈婉玲)网络课学习笔记(一)

    2017.10.10 21:47 放一波课程的链接首先:http://www.chinesemooc.org/live/685712    华文慕课 北京大学屈婉玲女神的视频教程,非常推荐  学习算法 ...

  6. 计算机视觉结课论文,计算机视觉与图像识别结课论文

    <计算机视觉与图像识别结课论文>由会员分享,可在线阅读,更多相关<计算机视觉与图像识别结课论文(8页珍藏版)>请在人人文库网上搜索. 1.计算机视觉与图像识别结课论文基于C+的 ...

  7. 计算机图形学结课论文,计算机图形学结课论文精要.doc

    计算机图形学结课论文精要 2017届结课论文 <计算机图形学基础教程> -小球的弹跳运动 学生姓名 学 号 所属学院 专 业 计算机科学与技术 班 级 塔里木大学教务处制 目录 摘 要1 ...

  8. 软件工程结课论文 敏捷开发在软件工程中的应用 大学编程作业(TUST 天津科技大学 2022年)

    软件工程结课论文 敏捷开发在软件工程中的应用 大学编程作业(TUST 天津科技大学 2022 年) 软件工程结课论文 敏捷开发在软件工程中的应用 大学编程作业(TUST 天津科技大学 2022 年) ...

  9. 计算机图形学结课论文,计算机图形学基础教程结课论文

    计算机图形学是研究如何在计算机中生成.显示和处理图形的一门学科.计算机图形学具有较高的实用价值.下面是学习啦小编给大家推荐的计算机图形学基础教程结课论文,希望大家喜欢! 计算机图形学基础教程结课论文篇 ...

最新文章

  1. Java 数据类型转换
  2. tomcat服务器配置及加固
  3. 在 TreeView 控件中显示分层数据
  4. mysql uuid_short 为什么不存在_MySQL内置函数uuid和uuid_short
  5. matlab 多文件编程,是否有可能在MATLAB中为每个文件定义多个函数,并从该文件外部访问它们?...
  6. Dart 10-Day
  7. 【计算机网络】1.1 计算机网络的基本概念
  8. BM3D(Block-Matching and 3D filtering)读后感
  9. vue2实现电商后台管理的思路
  10. Android国家区号 中英文
  11. ikbc poker2
  12. 安全事件应急响应工具箱
  13. 【多元函数微分学】易错点总结
  14. 升压电路的原理-原文地址:http://www.52solution.com/basic/1218
  15. 微软亚洲研究院2017年笔试编程题
  16. java计算机毕业设计乐多多宠物店网站源代码+数据库+系统+lw文档
  17. 研究发现有适用于欧洲GDPR法规的加密货币解决方案
  18. 《HTML5+CSS3网页布局和样式精粹》.(张亚飞).[PDF]ckook
  19. 3小时快速入门html5+css(2022)
  20. 芮瑶学编程05-画七彩虹

热门文章

  1. Win10 VS2015 error LNK1104: 无法打开文件“opencv_world331.lib”
  2. 构建patch补丁并提交git和rpm软件包验证
  3. 电影《看不见的客人》是如何找到真相的?
  4. Python -eventlet
  5. 今日科技联播: 马斯克Twitter一句话,骂掉特斯拉20亿美元市值
  6. 不看不知道。。世界真奇妙!
  7. the content must be served over HTTPS 解决方案
  8. LeetCode 数据库题库解析之 175. 组合两个表
  9. 【Bleak】二、扫描(附近全部设备)
  10. [译] 理解Horizon的连接