1、问题描述:
一个旅行者有一个最多能装m公斤的背包,现在有n中物品,每件的重量分别是W1、W2、……、Wn,每件物品的价值分别为C1、C2、……、Cn, 需要将物品放入背包中,要怎么样放才能保证背包中物品的总价值最大?
2、动态规划算法的概述
1)动态规划(Dynamic Programming)算法的核心思想是:将大问题划分为小问题进行解决,从而一步步获取最优解的处理算法
2)动态规划算法与分治算法类似,其基本思想也是将待求解问题分解成若干个子问题,先求解子问题,然后从这些子问题的解得到原问题的解。
3)与分治法不同的是,适合于用动态规划求解的问题,经分解得到子问题往往不是互相独立的。 ( 即下一个子阶段的求解是建立在上一个子阶段的解的基础上,进行进一步的求解 )
4)动态规划可以通过填表的方式来逐步推进,得到最优解
3、解题思路
利用动态规划来解决,每次遍历到的第i个物品,根据 w[i]和v[i]来确定是否需要将该物品放入背包中。
对于给定的n个物品,
v[i]:第i个物品的价值
w[i]:第i个物品的重量
c:为背包的容量
v[i][j]表示在前i个物品中能够装入容量为j的背包中的最大价值。
1)v[i][0]=v[0][j]=0,表示第一行和第一列是0。
2)当w[i]>j时:v[i][j]=v[i-1][j] ,当准备加入新增的物品的容量大于当前背包的容量时,就直接使用上一个单元格的装入
3)当j>=w[i]时:v[i][j]=max{v[i-1][j] ,v[i]+v[i-1][j-w[i]]},当准备加入的新增的物品的容量小于等于当前背包的容量。
其中:
v[i-1][j]:就是上一个单元格的装入的最大值
v[i]:表示当前物品的价值
v[i-1][j-w[i]]:装入i-1物品,到剩余空间j-w[i]的最大值
4、完整代码及运行结果文章来源:https://www.toymoban.com/news/detail-406851.html
package com.example.demo;
public class DynamicProgramming {
public static void main(String[] args) {
//物品的重量
int[] c = {7, 2, 6, 3, 5};
//物品的价值
int[] w = {21, 18, 9, 15, 6};
//物品的个数
int n = w.length;
//背包的容量
int v = 14;
knapsackDP(c, w, n, v);
}
/**
*利用动态规划来解决:
* 每次遍历到的第i个物品,根据 w[i]和v[i]来确定是否需要将该物品放入背包中。
* 对于给定的n个物品,
* v[i]:第i个物品的价值
* w[j]:第i个物品的重量
* c:为背包的容量
* v[i][j]表示在前i个物品中能够装入容量为j的背包中的最大价值。
*
* @param w 物品的重量
* @param val 物品的价值
* @param n 物品的个数
* @param m 背包的容量
* @return
*/
public static int knapsackDP(int[] w, int[] val, int n, int m) {
//v[i][j] 表示在前i个物品中能够装入容量为j的背包中的最大价值
int[][] v = new int[n + 1][m + 1];
//记录放入物品的情况
int[][] records = new int[n + 1][m + 1];
//初始化第一行和第一列为0
for (int i = 0; i < v.length; i++) {
v[i][0] = 0;
}
for (int i = 0; i < v[0].length; i++) {
v[0][i] = 0;
}
for (int i = 1; i < v.length; i++) {
for (int j = 1; j < v[0].length; j++) {
//当w[i]>j时,数组下标从1开始,所以-1
if (w[i - 1] > j) {
v[i][j] = v[i - 1][j];
} else {//当j>=w[i]时,数组下标从1开始,所以-1
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]];
//记录
records[i][j] = 1;
} else {
v[i][j] = v[i - 1][j];
}
}
}
}
//
for (int i = 0; i < v.length; i++) {
for (int j = 0; j < v[i].length; j++) {
System.out.print(v[i][j] + " ");
}
System.out.println();
}
System.out.println("============================");
//行的最大下标
int i = records.length - 1;
//列的最大下标
int j = records[0].length - 1;
while (i > 0 && j > 0) { //从records的最后开始找
if (records[i][j] == 1) {
System.out.printf("第%d个物品放入到背包\n", i);
j -= w[i - 1]; //w[i-1]
}
i--;
}
return 0;
}
}
程序运行结果:文章来源地址https://www.toymoban.com/news/detail-406851.html
到了这里,关于【Java实现】动态规划算法解决01背包问题的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!