背包问题的实现
* 1.全组合解法(对数器)
* 2.暴力递归解法
* 3.动态规划解法
* 4.动态规划(省空间)解法

对数器的思路是:求解n个物品的全组合中不超过背包容量的组合对应的最大价值(时间复杂度极高:      )

package com.logbug.algorithm.knapsack;import lombok.Data;import java.util.Arrays;
import java.util.Objects;
import java.util.stream.Collectors;/*** 背包问题的实现* 1.全组合解法(对数器)* 2.暴力递归解法* 3.动态规划解法* 4.动态规划(省空间)解法** @author : lin.chen1* @version : 1.0.0.0*/
@Data
public class KnapsackRecursion {/*** 背包容量*/int c;/*** 重量数组*/int[] w;/*** 价值数组*/int[] v;public static void main(String[] args) {debug();test();}static void debug() {// 固定参数用于调试int[] w = new int[]{1, 3, 5, 7};int[] v = new int[]{2, 5, 9, 15};int c = 14;commonTest(w, v, c);}static void test() {int testTimes = 1000 * 1000;int num = 10;int wv = 100;for (int i = 0; i < testTimes; i++) {int[] w = new int[num];int[] v = new int[num];// 保证非0int c = (int) (Math.random() * wv) + 1;for (int j = 0; j < num; j++) {w[j] = (int) (Math.random() * wv + 1);v[j] = (int) (Math.random() * wv + 1);}commonTest(w, v, c);}System.out.println("success");}static void commonTest(int[] w, int[] v, int c) {System.out.println("w = " + Arrays.stream(w).boxed().map(Objects::toString).collect(Collectors.joining(",")));System.out.println("v = " + Arrays.stream(v).boxed().map(Objects::toString).collect(Collectors.joining(",")));System.out.println("c = " + c);KnapsackRecursion knapsackRecursion = new KnapsackRecursion();knapsackRecursion.setW(w);knapsackRecursion.setV(v);knapsackRecursion.setC(c);// 对数器解法int result1 = knapsackRecursion.simple();// 暴力递归解法int result2 = knapsackRecursion.forceRecursion(w.length, c);// 动态规划解法int result3 = knapsackRecursion.dynamicPrograming();// 动态规划省空间解法int result4 = knapsackRecursion.dynamicProgramingPro();System.out.println("result1 = " + result1);System.out.println("result2 = " + result2);System.out.println("result3 = " + result3);System.out.println("result4 = " + result4);if (result1 != result2 || result1 != result3 || result1 != result4) {System.err.println("fail");System.exit(0);} else {System.out.println("=====================");}}/*** 对数器*/int simple() {int max = 0;// n 个物品的全组合for (int num = 1; num < 1 << w.length; num++) {// 选中物品的总重量int allW = 0;// 选中物品的总价值int allV = 0;// 第num中情况的背包价值;for (int i = 0; i < w.length; i++) {if ((1 << i & num) != 0) {allV += v[i];allW += w[i];}}// 未超出背包容量的组合选的总重量与当前最大值比较if (allW <= c) {max = Math.max(max, allV);}}return max;}/*** 暴力递归版本* 返回扫过第n个元素后背包的最大价值。<br>* 第n个元素的结果依赖第n-1个元素的结果,从n开始递归** @param n     元素位置* @param wight 来到第n个元素时背包的剩余容量* @return 对当前元素决策后的最大价值*/int forceRecursion(int n, int wight) {if (n <= 0) {// 递归终止条件return 0;} else if (w[n - 1] > wight) {// 当前物品重量超出背包剩余容量,返回不放该物品的最大价值return forceRecursion(n - 1, wight);} else {// 返回放和不放当前物品所能达到的最大价值的较大值return Math.max(forceRecursion(n - 1, wight), v[n - 1] + forceRecursion(n - 1, wight - w[n - 1]));}}/*** 动态规划版本* 动态规划表示例:* w   v   0   1   2   3   4   5   6   7   8   9   10  11  12  13  14  15  16* 1   2   0   2   2   2   2   2   2   2   2   2   2   2   2   2   2   2   2* 3   5   0   2   2   5   7   7   7   7   7   7   7   7   7   7   7   7   7* 5   9   0   2   2   5   7   9   11  11  14  16  16  16  16  16  16  16  16* 7   15  0   2   2   5   7   9   11  15  17  17  20  22  24  26  26  29  31*/int dynamicPrograming() {int n = w.length;int[][] dp = new int[n][c + 1];// 初始化第一列,即剩余容量为零,价值为0for (int i = 0; i < n; i++) {dp[i][0] = 0;}// 初始化动态规划表的第一行for (int i = 1; i <= c; i++) {if (w[0] > i) {dp[0][i] = 0;} else {dp[0][i] = v[0];}}for (int i = 1; i < n; i++) {for (int j = 1; j <= c; j++) {if (w[i] > j) {dp[i][j] = dp[i - 1][j];} else {dp[i][j] = Math.max(dp[i - 1][j], dp[i - 1][j - w[i]] + v[i]);}}}return dp[n - 1][c];}/*** 动态规划省空间版本* 求解动态规划表第i行时,只依赖第i-1行的记录,所以可以压缩动态规划表为1行。* 求解单行时,从后往前填充*/int dynamicProgramingPro() {int n = w.length;int[] dp = new int[c + 1];dp[0] = 0;// 初始化for (int i = 1; i <= c; i++) {int value = 0;if (i >= w[0]) {value = v[0];}dp[i] = value;}for (int i = 1; i < n; i++) {for (int j = c; j > 0; j--) {if (j >= w[i]) {dp[j] = Math.max(dp[j], v[i] + dp[j - w[i]]);}}}return dp[c];}
}

背包问题算法实现(全组合、暴力递归、动态规划及空间压缩、对数器)相关推荐

  1. 算法补天系列之——暴力递归

    首先补充一下之前的迪杰斯特拉算法,也可以用堆的形式来实现,不过这个是肯定不能用系统提供的堆来实现的,因为这里有一个新发现的更小的路径,要修改堆的数据. 所以自己写堆的本领是必须要的,堆的底层结构是一个 ...

  2. 算法入门篇九 暴力递归

    牛客网 左程云老师的算法入门课 暴力递归 原则  汉诺塔问题 问题 打印n层汉诺塔从左边移动到最右边的过程 思想 一共六个过程,左到右.左到中,中到左,中到右,右到左,右到中,互相嵌套使用 左到右 将 ...

  3. 算法设计与分析 暴力递归

    暴力递归 概述 题目一:汉诺塔问题 题目二:字符串的全部子序列问题 题目三:字符串的全排列问题(分支限界) 题目四:拿纸牌比最大问题 题目五:递归逆序栈 题目六:数字与字符串的转化问题 题目七:重量和 ...

  4. 常见数据结构与算法:拆分数字(暴力递归,动态规划)

    public class SplitNumber {public static void main(String[] args) {int pre = 1;int rest = 27;System.o ...

  5. 字符串所有排列组合暴力递归

    给你一个字符串"acb",可以打印出六种排列组合,这里又是一种index推动的递归,但是这里有一些小trick,就是从第一个开始,在后面的字符串的每一个字符进行交换,这样就可以省很 ...

  6. 【LeetCode】LeetCode之打家劫舍Ⅱ——暴力递归+动态规划解决循环问题+DP空间优化

    这道题和第 198 题相似,建议读者首先阅读「198. 打家劫舍」

  7. 带你击杀动态规划梦魇-从暴力递归到动态规划

    本文章欢迎转载,但是转载请标明出处,程序锋子https://blog.csdn.net/l13591302862/article/details/111410091 想要分享下自己之前学习动态规划的过 ...

  8. 数据结构与算法之暴力递归改动态规划

    数据结构与算法之暴力递归改动态规划 目录 二维数组最小路径和 暴力递归改动态规划解析 任意选择数组arr中的数字,看能不能累加得到aim 1. 二维数组最小路径和 (一) 题目描述 (二) 思路 递归 ...

  9. 数据结构和算法之暴力递归到动态规划01-绝顶聪明纸牌问题

    从一开始的暴力递归到傻瓜式的缓存动态规划到最终的动态规划 package day_16;/*** 给定一个整型数组arr,代表数值不同的纸牌排成一条线* 玩家A和玩家B依次拿走每张纸牌* 规定玩家A先 ...

最新文章

  1. 使用 Vue 2.0 实现服务端渲染的 HackerNews
  2. 用Spark和DBSCAN对地理定位数据进行聚类
  3. ubuntu 下载mysql8_mysql8.0 ubuntu 安装
  4. VxWorks/tornado环境搭建(Win 7 64位 corei5下试验成功)
  5. Linux命令之 mkfs -- 在特定的分区创建 Linux 文件系统
  6. concat合并的数组会有顺序么_超全的JS常用数组方法整理
  7. 解析软件系统稳定性的三大秘密
  8. 成都高新税务推出智能电话语音咨询服务 24小时在线答复
  9. PHP GUID和UUID生成类
  10. 人工智能(腾讯AI)-身份证识别技术使用接口说明
  11. unity学习2——基于物理模拟的太阳系模型
  12. 绕过360实现lsass转储
  13. python mqtt publish_mqtt异步publish方法
  14. 长期置顶:作为一个技术人,你为什么有时间写博客?准备应对未来的中年危机
  15. Kettle教程(三):Excel转换文本
  16. OpenSSL SSL_read: Connection was aborted, errno 10053的问题
  17. 如何将CSDN文章内容转成PDF
  18. 腾讯员工平均月薪高达8.5万元,过来人教你普通人如何进大厂
  19. 【python+ROS+路径规划】一、前置准备
  20. STM32 FLASH 简单读写操作【有代码】

热门文章

  1. 华为OD机试用JS实现 -【停车找车位】(2023-Q2 押题)
  2. 江苏省计算机学业水平测试模拟软件,基于江苏省普通高中物理学业水平测试的学生在线自主模拟测试系统研发...
  3. Go语言Github包依赖环境的安装
  4. strcmp和strncmp
  5. python:return之后的语句还会执行吗
  6. Python--简单的深度学习CNN睁闭眼分类
  7. win10msmpeng占内存_彻底解决win10 占用内存高的办法
  8. 三亚RHCE学习之路
  9. 关于组合数(二项系数)的一个递推公式
  10. 【web前端开发】后台PHP