揹包問題之輸出最優方案

一般而言,揹包問題要求一個最優解,若要求輸出這個最優值的方案,可參照一般動態規劃問題輸出方案的方法:記錄下每個狀態的最優值是由狀態轉移方程的哪一項推出來的,也就是說,記錄下它是由哪一項決策推出來的,便可以根據這個決策找到上一個狀態,從上一個狀態接着往前推即可,這裏以0-1揹包爲例子,給定輸入如下:

c = [2,3,4,5,6,7,8];
v = [3,4,5,6,7,8,9];
V = 23;

求解最優值的狀態轉移方程爲 dp[i][j]=max{dp[i1][j],dp[i1][jc[i]]+v[i]}dp[i][j]=max\{dp[i-1][j],dp[i-1][j-c[i]]+v[i]\}。再用一個數組 g[i][j]g[i][j],設 g[i][j]=0g[i][j]=0 表示推出 dp[i][j]dp[i][j] 的值時是採用了方程的前一項,g[i][j]=1g[i][j]=1 表示採用了方程的後一項。

    public int knapsackProblem(int[] c, int[] v, int cap) {
        int[][] dp = new int[c.length + 1][cap + 1], g = new int[c.length + 1][cap + 1];
        List<Integer> list = new LinkedList<>();
        for (int i = 1; i <= c.length; i++) {
            for (int j = cap; j > 0; j--) {
                if (c[i - 1] <= j) {
                    if (dp[i - 1][j] >= dp[i - 1][j - c[i - 1]] + v[i - 1]) {
                        dp[i][j] = dp[i - 1][j];
                        g[i][j] = 0;
                    } else {
                        dp[i][j] = dp[i - 1][j - c[i - 1]] + v[i - 1];
                        g[i][j] = 1;
                    }
                } else {
                    dp[i][j] = dp[i - 1][j];
                }
            }
        }
        int i = c.length, V = cap;
        while (i > 0) {
            if (g[i][V] == 0) {
                i--;
            } else {
                list.add(i - 1);
                V -= c[i-- - 1];
            }
        }
        Collections.reverse(list);
        System.out.println("已選擇物品下標: " + list);
        return dp[c.length][cap];
    }

上一篇:揹包問題之分組揹包問題
下一篇:揹包問題之最優方案總數

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章