01背包

01背包的 动态规划和 穷举法
首先是动态规划
public static void main(String[] args) {
		List<Product> products = new ArrayList<Product>();
		products.add(new Product(10, 3));
		products.add(new Product(3, 4));
		products.add(new Product(4, 5));
		products.add(new Product(5, 6));
		dynamicPack01(products, 14);
	}

	/**
	 * 状态转移方程 c[i][m] = max{c[i - 1][m], c[i - 1, m-w[i]] + p[i]}
	 * 其中i 是第i个物品,m是重量, w[i] 指 第i个 物品的重量,p[i]指的是第i个物品的价格
	 * w只能是整数,如果是小数 乘以一个10^x, 由于O(maxWeight * products) 
	 * 可以看到动态规划的复杂度是随之重量的提高而提高,小数的话会生成10^x的数量级- -
	 * @param products
	 * @param maxWeight
	 */
	public static void dynamicPack01(List<Product> products, int maxWeight){
		//这里多开辟了一列空间方便计算,在多开辟一行方便计算,来处理第1列物品的最大值
		long time = System.nanoTime();
		int[][] table = new int[products.size() + 1][maxWeight + 1];
		long time3 = System.nanoTime();
		
		for(int m = 1; m < maxWeight + 1; m++){
			for(int i = 0; i < products.size(); i++){
				Product p = products.get(i);
				if(p.weight > m){//说明背包放不下此物品
					table[i + 1][m] = table[i][m];	
				}else{
					int max1 = table[i][m];
					int max2 = table[i][m - p.weight] + p.price;
					table[i + 1][m] = max1 > max2 ? max1 : max2;
				}
			}
		}
		
		long time2 = System.nanoTime() - time;
		long ktable = time3 - time;
		System.out.println("动态规划的耗时为" + time2);
		System.out.println("开辟表耗时为" + ktable);
		System.out.println("动态规划的耗时去表为" + (time2 - ktable));
		
		for(int j = 0; j < table[0].length; j++){
			System.out.print(j  + "\t");
		}
		System.out.println();
		for(int i = 0; i < table.length; i++){
			for(int j = 0; j < table[i].length; j++){
				System.out.print(table[i][j] + "\t");
			}
			System.out.println();
		}
		
	}


其次是穷举法
/**
	 * 穷举法
	 * @param products
	 * @return
	 */
	public static void getPack01Max(List<Product> products, int maxWeight){
		long time = System.nanoTime();
		List<Product> result = null;
		int priceMax = 0;
		
		for(int i = 0; i < products.size(); i++){
			int j = i;
			int tempWeight = 0;
			
			for(; j < products.size(); j++){
				tempWeight = tempWeight + products.get(j).weight;
				if(tempWeight > maxWeight){
					break;
				}
			}
			List<Product> temp = new ArrayList<Product>();
			int tempPrice = 0;
			for(int k = i; k < j; k++){
				tempPrice = tempPrice + products.get(k).price;
				temp.add(products.get(k));
			}
			if(tempPrice > priceMax){
				priceMax = tempPrice;
				result = temp;
			}
		}
		long time2 = System.nanoTime() - time;
		System.out.println("穷举法的耗时为" + time2);
		
		System.out.println("最大价值为 " + priceMax);
		for(Product p : result){
			System.out.println("weight : " + p.weight + "  price :" + p.price);
		}
	}
	


- - 由于动态规划的时间复杂度是O(Products * maxWeight) 而穷举法的时间复杂度是O(Products^2), 而且 动态规划开辟了一个二维数组,样本很少,且maxWeight比较大的时,穷举法的效率高于动态规划- -

你可能感兴趣的:(背包)