Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 多功能背包_Java_Algorithm_Dynamic Programming_Knapsack Problem - Fatal编程技术网

Java 多功能背包

Java 多功能背包,java,algorithm,dynamic-programming,knapsack-problem,Java,Algorithm,Dynamic Programming,Knapsack Problem,给定问题: n个项目,每个项目都有一个值val、一个重量w、一个体积vol。基本上与背包0/1问题相同,但任务是找到背包中的最大值V,但重量不能超过W_max,体积至少需要Vol_min 值、重量和体积以三个数组表示: val[n+1], w[n+1], vol[n+1] The i-th item has value val[i], weight w[i] and volume vol[i] 我知道如何解决只有一个极限的正常0/1背包问题,但我不知道如何解决这个问题。我曾考虑使用3D DP表

给定问题:

n个项目,每个项目都有一个
值val
、一个
重量w
、一个
体积vol
。基本上与背包0/1问题相同,但任务是找到背包中的最大值V,但重量不能超过W_max,体积至少需要Vol_min

值、重量和体积以三个数组表示:

val[n+1], w[n+1], vol[n+1]
The i-th item has value val[i], weight w[i] and volume vol[i]
我知道如何解决只有一个极限的正常0/1背包问题,但我不知道如何解决这个问题。我曾考虑使用3D DP表,但表中的条目是如何定义的

以下是我迄今为止所尝试的:

static int knapsack(int[] vol, int[] w, int[] val, int n, int Vol_min, int W_max) {

    int[][][] DP = new int[n+1][W_max][Vol_min];

    for(int i = 1; i < n+1; i++) {
        for(int j = 0; j < W_max; j++) {
            for(int k = 0; k < Vol_min; k++) {

                if(w[i] > W_max) {
                    DP[i][j][k] = DP[i-1][j][k];
                } else {

                    if(j - w[i] >= 0 && k + vol[i] <= n) {
                        DP[i][j][k] = Math.max(DP[i-1][j][k], DP[i-1][j - w[i]][k + vol[i]] + val[i]);
                    } else {
                        DP[i][j][k] = DP[i-1][j][k];
                    }

                }
            }
        }
    }

    return DP[n][n][n]; 
}

因此,使用递归DP,我对1/0背包提出了一个非常标准的解决方案,只做了一点修改

    public static int[][] dp;// Item number, Weight, Volume
    public static int[] vol, w, val;
    public static int Vol_min, W_max, n;

    static int knapsack(int item, int weight, int volume) {
        // See if we have calculated this item before
        if (dp[item][weight] == -1) {
            // Set initial value to -2 (invalid result)
            int max = -2;
            // Iterate though all items past current item
            for (int i = item; i < n; i++) {
                // Make sure we don't go over max weight
                if (weight + w[i] <= W_max) {
                    // Get the result of taking ith item
                    int res = knapsack(i + 1, weight + w[i], volume + vol[i]);
                    // Make sure result is valid (Total volume is greater than
                    // Vol_min)
                    if (res != -2) {
                        // If the result is valid take the max
                        max = Math.max(res + val[i], max);
                    }
                }
            }

            if (max == -2 && volume >= Vol_min)// No other items taken and over
                                                // Vol_min
                dp[item][weight] = 0;
            else // Eveything else
                dp[item][weight] = max;
        }
        // Return the value
        return dp[item][weight];
    }

    public static void main(String[] args) {
        n = 6;
        Vol_min = 10;
        W_max = 12;
        vol = new int[] { 1, 3, 7, 5, 1, 3 };
        w = new int[] { 4, 5, 10, 2, 1, 4 };
        val = new int[] { 10, 8, 5, 3, 1, 2 };
        dp = new int[n + 1][W_max + 1];
        for (int i = 0; i <= n; i++) {
            for (int j = 0; j <= W_max; j++) {
                dp[i][j] = -1;
            }
        }
        System.out.println(knapsack(0, 0, 0));

    }
publicstaticint[]dp;//项目编号、重量、体积
公共静态int[]卷,w,val;
公共静态整数最小值,最大值,n;
静态整数背包(整数项、整数重量、整数体积){
//看看我们以前是否计算过这个项目
如果(dp[项目][重量]=-1){
//将初始值设置为-2(结果无效)
int max=-2;
//迭代当前项之前的所有项
对于(int i=项;i对于(int i=0;i
dp[i][j][k]=max(dp[i-1][j][k],dp[i-1][j-w[i]][k-vol[i]]+val[i])
-???@ShihabShahriar我认为如果最大卷是一个上限,那么这将是一个解决方案,但这里的卷是最小的,即下限。你应该能够让第三维表示给定卷的最大值,而不是现在所有卷的最大值。这是一个竞争问题吗分享到问题的链接?我很确定这是可以做到的,但是如果有一个地方可以让我得到判断结果,我可以更具体一点。@kevmo314我添加了一个简单的例子,不幸的是,我不能给你到判断的链接,因为它对某些用户是有限的…@G.m你考虑过使用递归DP吗?
    public static int[][] dp;// Item number, Weight, Volume
    public static int[] vol, w, val;
    public static int Vol_min, W_max, n;

    static int knapsack(int item, int weight, int volume) {
        // See if we have calculated this item before
        if (dp[item][weight] == -1) {
            // Set initial value to -2 (invalid result)
            int max = -2;
            // Iterate though all items past current item
            for (int i = item; i < n; i++) {
                // Make sure we don't go over max weight
                if (weight + w[i] <= W_max) {
                    // Get the result of taking ith item
                    int res = knapsack(i + 1, weight + w[i], volume + vol[i]);
                    // Make sure result is valid (Total volume is greater than
                    // Vol_min)
                    if (res != -2) {
                        // If the result is valid take the max
                        max = Math.max(res + val[i], max);
                    }
                }
            }

            if (max == -2 && volume >= Vol_min)// No other items taken and over
                                                // Vol_min
                dp[item][weight] = 0;
            else // Eveything else
                dp[item][weight] = max;
        }
        // Return the value
        return dp[item][weight];
    }

    public static void main(String[] args) {
        n = 6;
        Vol_min = 10;
        W_max = 12;
        vol = new int[] { 1, 3, 7, 5, 1, 3 };
        w = new int[] { 4, 5, 10, 2, 1, 4 };
        val = new int[] { 10, 8, 5, 3, 1, 2 };
        dp = new int[n + 1][W_max + 1];
        for (int i = 0; i <= n; i++) {
            for (int j = 0; j <= W_max; j++) {
                dp[i][j] = -1;
            }
        }
        System.out.println(knapsack(0, 0, 0));

    }