dynamic programming
Introduction to Dynamic Programming Algorithms
Best Practices for Dynamic Programming Algorithms - Knapsack Problem
Introduction to Dynamic Programming Algorithms
1) The core idea of the dynamic programming (Dynamic Programming) algorithm is: divide the big problem into small problems to solve, so as to obtain the optimal solution step by step
2) The dynamic programming algorithm is similar to the divide-and-conquer algorithm. Its basic idea is to decompose the problem to be solved into several sub-problems, first solve the sub-problems, and then obtain the solution of the original problem from the solutions of these sub-problems.
3) Different from the divide and conquer method, it is suitable for problems solved by dynamic programming, and the sub-problems obtained through decomposition are often not independent of each other. (That is, the solution of the next sub-stage is based on the solution of the previous sub-stage for further solution)
4) Dynamic programming can be gradually advanced by filling in the form to get the optimal solution.
Best Practices for Dynamic Programming Algorithms - Knapsack Problem
The knapsack problem mainly refers to a number of knapsacks with a given capacity, items with a certain value and weight, how to choose items to put into the knapsack to maximize the value of the items. Among them, it is divided into 01 backpack (01 backpack: only one item is available for each item) and complete backpack (complete backpack refers to: each item has unlimited items available)
Case of knapsack problem: There is a knapsack with a capacity of 4 pounds and the following items:
1) The goal required to be achieved is that the total value of the loaded backpack is the largest, and the weight does not exceed 4 pounds.
2) The items required to be loaded cannot be repeated.
Idea analysis:
1) The problem here belongs to the 01 backpack, that is, each item can put at most one
2) The main idea of the algorithm is solved by dynamic programming. For the i-th item traversed each time, determine whether the item needs to be put into the backpack according to w[i] and v[i]. That is, for a given n items, let v[i] and w[i] be the value and weight of the i-th item respectively, and then let v[i][j] represent the capacity that can be loaded in the first i items is the maximum value in j's knapsack.
Then we have the following result:
//表示填入表第一行和第一列是0
(1)v[i][0]=v[0][j]=0;
//当准备加入新增的商品的容量大于当前背包的容量时,就直接使用上一个单元格的装入策略
(2)当w[i]>j时: v[i][j]=v[i-1][j]
//当准备加入的新增的商品的容量小于等于当前背包的容量时:取【方案一:上一个单元格的价值】和【方案二:装入当前商品与其他商品的价值的总和】的最大值
(3)当j>=w[j]时: v[i][j]=max{v[i-1][j], v[i]+v[i-1][j-w[i]]
//[i-1][j]:就是上一个单元格的价值
//v[i]:表示当前商品的价值
//v[i-1][j-w[i]]:在剩余j-w[i]空间里,装入【i-1】即【即i前面的某个或某几个】商品以达到价值最大化
//v[i]+v[i-1][j-w[i]]:装入当前商品与其他商品的价值的总和
Graphical analysis:
Java code implementation:
public class KnapsackProblem {//01背包问题
public static void main(String[] args) {
int[] w = {1, 4, 3};//物品的重量
int[] val = {1500, 3000, 2000};//物品的价值
int m = 4;//背包的容量
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) {//因为我们的程序的i是从1开始,所以原来公式里的w[i]-->>w[i-1]
v[i][j] = v[i - 1][j];//v[1][1]从第二行第二个开始
} else {
//因为我们的程序的i是从1开始,因此要调整:
//为了记录商品存放到背包的情况,我们不能直接的使用上面的公式,,需要使用if-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);
j -= w[i - 1];
}
i--;
}
}
}
There will be times when the wind and the waves cleave, hang the clouds and sail straight to the sea!