背包问题是一个组合优化的问题,描述如下:给一个固定大小,能够携重W的背包以及一组有价值重量的物品,找出一个最佳的方案,使得装入包中的物品重量不超过W且总价值最大。
1、问题分析
数据:物品个数n=5,物品重量weights=[2,2,6,5,4],物品价值values=[6,3,5,4,6],背包总容量W=10。
我们设置一个矩阵f来记录结果:f(i.j)可表示可选的物品为{i.....n},背包容量为j(0 我们先看第一行,物品0的重量为2,价值为6,当容量为0时,什么也放不下,因此第一个格子只能填0,程序表示f(0,0)=0;当j=1时,依然放不下物品0,所以依旧为0,即f(0,1)=0;当j=2时,能放下物品0,则表示为f(0,2)=6,当j=3时,依旧能放下,则表示为f(0,3)=6,依次内推可得第一行的结果: 根据第一行,可以得到以下方程: 2 0 0 6 6 6 6 6 6 6 6 6 0 0 6 6 9 9 9 9 9 9 9 0 0 6 6 9 9 9 9 11 11 14 0 0 6 6 9 9 9 10 11 13 14 0 0 6 6 9 9 12 12 15 15 15 再看第二行,当j=0时,依旧什么都放不下,第一个格子填0,当j=1时,依旧如此,当j=2时,可以选择放不放如物品1: 如果不放入物品1,则背包中有物品0,最大价值为6,即f(0,j) 如果放入物品1,要算出背包放入1后还有多少的容量,然后再根据容量查出他的价值,再加上物品1的价值,即表示为 f(0,j-w(1))+v(1),放与不放要通过比较来决定: 显然此处填6,当j=3时,情况相同,当j=4时,能同时放下,f(1,4)=9,当j>4时,背包只能放入物品0和1,所以最大价值为9; 再看第三行,当j=0、1,什么都放不下,当j=2时,虽然放不下物品2,但是表中可看出,背包的最大容量为6,当j=8时,背包可以放物品0、1,也可以物品0、2,和1、2,物品0、1的价值,可以看到为9,最优值为0/2,总价值为11,当j=10时,三个物品能装下,总价值为14; 整理方程可得到第1行和第2行的使用方程: 根据方程,计算各列得出结果,根还有0-1背包问题的最优方案,得到方程式: 代码如下:
重量
价值
物品id
0
1
2
3
4
5
6
7
8
9
10
6
0
2
3
1
6
5
2
5
4
3
4
6
4
function knapsack(weights, values, w){
var n = weights.length -1;//获取物品个数
var f=[[]];//定义f的矩阵
for(var j=0;j<=w;j++){
if(j