背包问题和0-1背包问题

来源:互联网 发布:中国p2p网贷数据 编辑:程序博客网 时间:2024/04/27 14:34
package com.Thread.Learn;import java.util.*;/* * author:Tammy Pi * function:用动态规划算法解0/1背包问题 */public class BagProblem {//0/1背包问题的解法//背包能够放入的总容量为weight,物品有n个//物品的价值在数组v中,物品的重量在数组w中//f[i][k]表示放进第i个物品使得容量为k的背包价值最大//所以:f[i][k] = max{f[i-1][k],f[i-1][k-w[i]]+v[i]}public void bag01(int n,int v[],int w[],int weight){int[][] f = new int[n+1][weight+1];for(int i=0;i<=weight;i++){f[0][i] = 0;}for(int i=1;i<=n;i++){for(int j=1;j<=weight;j++){if(j<w[i]){f[i][j] = f[i-1][j];}else{f[i][j] = Math.max(f[i-1][j],f[i-1][j-w[i]]+v[i]);}}}System.out.println(f[n][weight]);}class MyClass{//物品的序号int i;//物品的单价Float myV;public MyClass(int i,float myV){this.i = i;this.myV = myV;}public int getI() {return i;}public void setI(int i) {this.i = i;}public Float getMyV() {return myV;}public void setMyV(Float myV) {this.myV = myV;}}//贪心算法求解背包问题public void bag(int n,float v[],float w[],float c){float[] myV = new float[v.length];List<MyClass> list = new ArrayList<MyClass>();//计算出每个物品的单个价值for(int i=0;i<v.length;i++){myV[i] = v[i]/w[i];list.add(new MyClass(i,myV[i]));}Collections.sort(list,new Comparator<MyClass>(){public int compare(MyClass arg0, MyClass arg1) {return arg0.getMyV().compareTo(arg1.getMyV());}});float myC = c;for(int i=0;i<list.size();i++){MyClass tempClass = list.get(i);float tempWeight = w[tempClass.getI()];if(myC>=tempWeight){System.out.println("物品"+tempClass.getI()+"被放入背包!");myC -= tempWeight;}else{float result = myC/tempWeight;System.out.println("物品"+tempClass.getI()+"的"+result+"被放入背包!");break;}}}public static void main(String[] args){/*int weight = 10;int[] w = {0,5,8,5,10};int[] v = {0,10,16,5,10};int n = 4;BagProblem pro = new BagProblem();pro.bag01(n, v, w, weight);*/float weight = 10;float[] w = {5,8,5,10};float[] v = {10,16,5,10};int n = 4;BagProblem pro = new BagProblem();pro.bag(n, v, w, weight);}}


看到不少人,背包问题和0-1背包问题混着叫,明明写的0-1背包问题的源代码,却给自己取个题目叫做背包问题。

其实,背包问题比0-1背包要简单。背包问题中的物品是可以放进去一部分的,这样我们就可以用贪心算法求解,首先对各个物品求单价,然后按单价的高低依次放入物品,最后一个物品一般是放进去一部分。

而0-1背包问题,则是物品要么放进去要么不放进去。它不满足当前最优解就是全局最优解,不能够用贪心算法求解,那么就只能够用动态规划的办法进行解答。动态规划的思想是:

令f[i][k]为放第i个物品到重量为k的背包的最大价值,它的值应该是:

当weight<w[i]时,f[i][k]=f[i-1][k];

当weight>=w[i]时,f[i][k]=max{f[i-1][k],f[i-1][k-w[i]]+v[i]}