我的编程空间,编程开发者的网络收藏夹
学习永远不晚

Java使用动态规划算法思想解决背包问题

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

Java使用动态规划算法思想解决背包问题

动态规划算法

动态规划算法的思想

动态规划算法处理的对象是多阶段复杂决策问题,动态规划算法和分治算法类似,其基本思想也是将待求解问题分解成若干个子问题(阶段),然后分别求解各个子问题(阶段),最后将子问题的解组合起来得到原问题的解,但是与分治算法不同的是,子问题往往不是相互独立的,而是相互联系又相互区别的

动态规划算法问题求解的目标是获取导致问题最优解的最优决策序列(最优策略)。对于一个决策序列,可以用一个数值函数(目标函数)衡量这个决策的优劣。

最优性原理

动态规划算法的最优性原理:一个最优决策序列具有这样的性质,不论初始状态和第一步决策如何,对前面的决策所形成的状态而言,其余的决策必须按照前一次决策所产生的新状态构成一个最优决策序列。

最优性原理体现为问题的最优子结构特性,对于一个问题,如果能从较小规模的子问题的最优解求得较大规模同类子问题的最优解,最终得到给定问题的最优解,也就是问题的最优解中所包含的子问题的最优解,这种性质被称为最优子结构性质。最优子结构特性使得在从较小问题的解构造较大问题的解时,只需考虑子问题的最优解,然后以自底向上的方式递归地从子问题的最优解逐步构造出整个问题的最优解,它保证了原问题的最优解可以通过求解子问题的最优解来获得,最优子结构的特性是动态规划算法求解问题的必要条件。

动态规划算法的三大特点

  • 如果求解的问题满足最优性原理,则说明用动态规划算法有可能解决该问题,在分析问题的最优子结构时,所使用的方法具有普遍性。要注意一个问题可以有多种方式刻画它的最优子结构,有些表示方法的求解速度更快(空间占用少,问题的维度低)。
  • 递归定义最优解决方案。动态规划的每一步决策都依赖于子问题的解,动态规划算法求解最优化问题的步骤为:找出最优解的结构,具体来说就是看这个问题是否满足最优子结构特性;其次递归定义一个最优解的值,即构造原问题和子问题之间的递归方程,原问题的最优解可以通过子问题的最优解获得。
  • 以自底向上的方式计算出最优解的值(最优解的目标函数的值)。对子问题的分解是基于原问题的分解的基础之上进行的,而且这些子问题的分解过程是相互独立的。在对原问题分解的过程中,会出现大量的共享重叠子问题,为了避免对大量重叠子问题的重复计算,一般动态规划算法从自底向上开始计算,对每一个问题只解一次,并且保存求解子问题的最优值,当再需要求解这个子问题的时候,可以用常数时间查看一下结果,而不是再递归的去求解每一个问题的解,因此提高了动态规划算法的效率。

动态规划算法中的0/1背包问题

0/1背包问题的规则是不允许该物品进行拆分,即只有把物品放入和不放入两个基本状态,要使用动态规划算法求解决如何放物品才可以是背包中的物品的总价值达到最高。

示例

有一个载重为10的背包,现有4类物品,每类物品的重量分别为(w0,w1,w2,w3)=(2,3,4,7),它们的价值分别为(p0,p1,p2,p3)=(1,3,5,9)。试问如何装载能够使背包容纳物品的价值最大。

package 算法设计与分析;
 import java.util.Arrays;
 import java.util.Scanner;
 //m表示的是背包的容量,a表示有多少种类的物品,数组w用与存放每类物品的重量,数组val用于存放每类物品的价值
 public class my {
     public static void main(String[] args) {
         Scanner scanner = new Scanner(System.in);
         System.out.print("请输入背包的容量:");
         int m = scanner.nextInt();
         Scanner inScanner = new Scanner(System.in);
         System.out.print("请输入物品的个数:");
         int a = inScanner.nextInt();
         int[] w = new int[a + 1];
         System.out.print("请输入物品的重量:" + " ");
         for (int i = 1; i <= a; i++) {
             w[i] = inScanner.nextInt();
         }
         int[] val = new int[a+ 1];
         System.out.print("请输入物品的价值:" + " ");
         for (int i = 1; i <= a; i++) {
             val[i] = inScanner.nextInt();
         }
         int n = val.length;
         int[][] path = new int[n +1][m+1 ];
         //创建二维数组
         //v[i][j]:表示在前i个物品中能够装入容量为j的背包中的最大价值
         int[][] v = new int[n +1][m + 1];
         //初始化第一行和第一列
         for (int i = 0; i < v.length; i++) {//v.length:获取二维数组的行数
             v[i][0] = 0;//将第一列设置为0
         }
         for (int i = 0; i < v[0].length; i++) {//v[0].length:获取二维数组的列数
             v[0][i] = 0;//将第一行设置为0
         }
         for (int i = 1; i < v.length; i++) {//int i = 1 不处理第一行
             for (int j = 1; j < v[0].length; j++) {//int j = 1 不处理第一列
                 if (w[i - 1] > j) {
                     v[i][j] = v[i - 1][j];
                 } else {
                     if (v[i - 1][j] < (val[i - 1] + v[i - 1][j - w[i - 1]])) {
                         v[i][j] = val[i - 1] + v[i - 1][j - w[i - 1]];
                         //把当前情况记录到path
                         path[i][j] = 1;
                     } else {
                         v[i][j] = v[i - 1][j];
                     }
                 }
             }
         }
         //输出二维数组:
         for (int[] ints : v) {
             System.out.println(Arrays.toString(ints));
         }
         //输出最后我们是放入的那些商品
         int i = path.length - 1;//行的最大下标
         int j = path[0].length - 1;//列的最大下标
         while (i > 0 && j > 0) {//从path的最后开始找
             if (path[i][j] == 1) {
                 System.out.printf("第%d个商品放入背包\n", i-1);
                 j -= w[i - 1];
             }
             i--;
         }
     }
 }

输入一个背包容量为10,里面有4类物品,物品的重量分别为2,3,4,7,物品的价值分别为1,3,5,9

 结果 

动态规划算法的优点

若要解一个给定问题,我们需要解其不同部分(即子问题),再合并子问题的解以得出原问题的解。 通常许多子问题非常相似,为此动态规划法试图仅仅解决每个子问题一次,从而减少计算量: 一旦某个给定子问题的解已经算出,则将其记忆化存储,以便下次需要同一个子问题解之时直接查表。 这种做法在重复子问题的数目关于输入的规模呈指数增长时特别有用。

小结

以上就是针对动态规划算法的详细分析,利用动态规划算法可以避免重复计算多次子问题,提高效率,使计算机的性能更好!

到此这篇关于Java使用动态规划算法思想解决背包问题的文章就介绍到这了,更多相关Java背包问题内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

Java使用动态规划算法思想解决背包问题

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

Python算法题解:动态规划解0-1背包问题

概述背包问题(Knapsack problem)是一种组合优化的NP完全问题。问题可以描述为:给定一组物品,每种物品都有自己的重量和价格,在限定的总重量内,我们如何选择,才能使得物品的总价格最高。问题的名称来源于如何选择最合适的物品放置于给
2023-06-02

C++动态规划中关于背包问题怎么解决

本篇内容主要讲解“C++动态规划中关于背包问题怎么解决”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“C++动态规划中关于背包问题怎么解决”吧!一、分割等和子集-最后一块石头的重量II背包问题,难
2023-07-05

C语言动态规划多种背包问题怎么解决

这篇文章主要介绍了C语言动态规划多种背包问题怎么解决的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇C语言动态规划多种背包问题怎么解决文章都会有所收获,下面我们一起来看看吧。01背包问题C语言数学问题与简单DP0
2023-06-30

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录