js动态规划---背包问题

		/**
		 * 
		 * @param {Object} capacity 背包容量 5
		 * @param {Object} weights  物品重量 [2,3,4]
		 * @param {Object} values   物品价值  [3,4,5]
		 * 求解该背包最多能装多少价值的物品,(每个物品不能重复,物品必须完整)  
		 */
		
		function knapSack(capacity, weights, values){
			var i,w,a,b,kS = [];  //表示前i件物品恰放入一个容量为w的背包可以获得的最大价值。

			//计算是从0件商品,开始的,所以增加一个商品为0,重量为0的
			weights.unshift(0); 
			values.unshift(0);
			var n = values.length;
			for( i = 0; i < n ; i++ ){ //第几件商品,从一开始
				kS[i] = [];  //初始化一个二维数组
				for(w = 0; w <= capacity; w++){ //容量,忽略为0的容量
					if( i == 0 || w == 0){
						kS[i][w] = 0;
					}else if(weights[i] <= w){   //第i件商品的重量,如果小于当前的容量
						a = values[i] + kS[i-1][w-weights[i]];     //如果加入第i件商品,则为第i件商品的价值+ 前(i-1)件商品,容量为剩余重量价值
						b = kS[i-1][w];                            //如果不加入第i件商品,则为前(i-1)件商品,容量为w的价值
						kS[i][w] = (a > b) ? a:b;				//比较两种情况的最优值 	
					}else{
						kS[i][w] = kS[i - 1][w] || 0 ;				//当第i件商品容量大于当前容量时,只能选 前(i-1)件商品
					}
				}
			}
			console.log(kS)
			findValues(n, capacity, kS, weights, values);
			return kS[n-1][capacity];
		}
		
		//打印路径
		function findValues(n, capacity, kS, weights, values) {
			var i = n-1, k = capacity;
			console.log('解决方案包含以下物品: ');
			while (i > 0 && k > 0) {
				if (kS[i][k] !== kS[i-1][k]) {  //如果不相等,说明加入了i物品
					console.log('物品' + i + ',重量: ' + weights[i] + ',价值: ' + values[i]);
					k = k - weights[i];  //剩余重量
				} 
				i--;  //继续遍历所有物品,找到有哪些物品加入了
			}
		}
		
		//1、当容量为商品为0或者容量为0时,可以携带的价值都为0
		//2、前1件商品分别计算,容量为0-capacity的最大价值
		//3、前2件商品分别计算,容量为0-capacity的最大价值
		//4、..3..
		
		
		//每种物品仅有一件,可以选择放或不放
		//即f[i][w]表示前i件物品恰放入一个容量为w的背包可以获得的最大价值。
		//则其状态转移方程便是:f[i][w]=max{f[i-1][w],f[i-1][w-weights[i]]+values[i]} (这是最根本的算法)
		
		var values = [3, 4, 5],
		weights = [2, 3, 4],
		capacity = 5;
		
		console.log(knapSack(capacity, weights, values)); //输出 7
		
		//其实背包问题有好多版本:
		/*
		 * 01背包(ZeroOnePack): 有N件物品和一个容量为V的背包。每种物品均只有一件,第i件物品的费用是c[i],价值是w[i]。求解将哪些物品装入背包可使价值总和最大。
		完全背包(CompletePack): 有N种物品和一个容量为V的背包,每种物品都有无限件可用。第i种物品的费用是c[i],价值是w[i]。求解将哪些物品装入背包可使这些物品的费用总和不超过背包容量,且价值总和最大。
		多重背包(MultiplePack): 有N种物品和一个容量为V的背包。第i种物品最多有n[i]件可用,每件费用是c[i],价值是w[i]。求解将哪些物品装入背包可使这些物品的费用总和不超过背包容量,且价值总和最大。
		 * */
	

  

猜你喜欢

转载自www.cnblogs.com/muamaker/p/9298129.html