0-1背包问题(Java实现)

0-1背包问题
给定 n 种物品和一背包。物品 i 的重量是 wi,其价值为 vi,背包的容量为 C。问应 如何选择装入背包的物品,使得在总重量不超过背包的容量 C 的前提下装入背包中物品 的总价值最大;

public class Backpack {
    public int[] v;//价值数组
    public int[] w;//重量数组
    public int c;//背包容量
    public int[][] m;//m(i,j)是背包容量为j,可选物品为,i,i+1,i+2,i+3,...,n 时0-1背包问题的最优值
    public int[] x;//保存第i个物品是否放入背包,1:放入;0:未放入
    public Backpack(int[] vv,int[] ww,int cc){
        this.v=vv;
        this.w=ww;
        this.c=cc;
        this.x=new int[vv.length];
        int max = maxM(w, c);//获取j的最大值,从而通过new关键字创建m数组,在内存中维数组分配相应的存储空间
        m = new int[v.length][max + 1];
    }
    /**
     * 获取重量和背包容量的最大值,从而为m创建相应的存储空间
     * @param w
     * @param c
     * @return
     */
    public int maxM(int[] w,int c){
        int max = c;
        for(int i = 1; i < w.length; i++){
            if(w[i] > c)
                max = w[i];
        }
        return max;
    }
    public void knapsack(int[] v,int[] w,int c,int[][] m){
        int n = v.length - 1;
        int jMax = Math.min(w[n] - 1, c);
        for(int j = 0; j <= jMax;j++)
            m[n][j] = 0;
        for(int j = w[n]; j <= c;j++)
            m[n][j] = v[n];
        for(int i=n-1;i>1;i--){
            jMax = Math.min(w[i]-1,c);
            for(int j = 0; j <= jMax; j++)
                m[i][j] = m[i + 1][j];
            for(int j = w[i]; j <= c; j++)
                m[i][j] = Math.max(m[i + 1][j], m[i + 1][j - w[i]] + v[i]);
        }
        //m[1][c] = m[2][c];
        if(c >= w[1])//对于i=1时的两种情况
            m[1][c] = Math.max(m[2][c], m[2][c - w[1]] + v[1]);
        else
            m[1][c] = m[2][c];

    }
    public void traceback(int[][] m, int[] w, int c, int[] x){
        int n = w.length - 1;
        for(int i = 1; i < n; i++){
            if(m[i][c] == m[i+1][c])//第i个包未放入
                x[i] = 0;
            else{
                x[i] = 1;
                c -= w[i];//c是全局变量
            }
        }
        x[n] = (m[n][c]>0)?1:0;
    }
    public static void main(String[] args) {
        int v[] = {0,2,1,4,3};
        int w[] = {0,1,4,2,3};
        int c = 8;
        Backpack pa = new Backpack(v, w, c);
        pa.knapsack(pa.v, pa.w, pa.c, pa.m);
        System.out.println("装入背包中物品总价值最大为:");
        System.out.println(pa.m[1][c]);
        pa.traceback(pa.m, pa.w, pa.c, pa.x);
        System.out.println("装入的物品的序号为:");
        for(int i = 0; i <= v.length - 1; i++){
            if(pa.x[i]==1)
                System.out.print(i + " ");
        }
    }
}
全部评论

相关推荐

05-22 09:23
门头沟学院 Java
点赞 评论 收藏
分享
06-02 15:17
门头沟学院 Java
心爱的idea:怎么会呢 应该是打招呼有问题 问就说实习6个月全国可飞随时到岗
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务