Реконструкция пути ранца 0-1 (какие предметы взять) - PullRequest
1 голос
/ 08 февраля 2011

Я знаю, как решить проблему ранца 0-1 с помощью подхода динамического программирования, но у меня возникают проблемы с выяснением, какие предметы взять, не ставя под угрозу сложность O (N * C) (N предметов, емкость C).

Есть идеи (я бы предпочел восходящий подход)?

Ответы [ 6 ]

3 голосов
/ 05 января 2015

Вот модификация для восстановления пути в O (n) раз

int knapsack(int weight[], int profit[], int no_of_items, int capacity) {
    for (int var = 0; var <= capacity; ++var) {
        dp[0][var] = 0;
    }
    for (int var = 0; var <= no_of_items; ++var) {
        path[var] = false;
    }
    int using_item_i, without_using_item_i;
    for (int i = 1; i <= no_of_items; ++i) {
        for (int j = 1; j <= capacity; ++j) {
            without_using_item_i = dp[i - 1][j];
            using_item_i = 0;
            if ((weight[i]) <= j) {
                using_item_i = dp[i - 1][j - weight[i]] + profit[i];
            }

            if (using_item_i >= without_using_item_i) {
                taken[i][j] = true;
                dp[i][j] = using_item_i;
            } else {
                taken[i][j] = false;
                dp[i][j] = without_using_item_i;
            }
        }
    }
    //Reconstructing back the path
    int j = capacity;
    for (int i = no_of_items; i >= 0; --i) {
        if (taken[i][j]) {
            path[i] = true;
            cnt++;
        }
        j = j -  weight[i];
    }
    return dp[no_of_items][capacity];
}
3 голосов
/ 08 февраля 2011

Предположим, сейчас вы сохраняете результаты в массиве bool[] a, где a[i] - это истина, когда можно получить сумму i.
Вам понадобится еще один массив int[] b, где b[i] - последний элемент, который вы поместили в рюкзак для получения суммы i.

Итак, где у вас было

a[i] = true;

вам понадобится

a[i] = true;
b[i] = current_item;

Затем поиск предметов, которые можно взять для получения суммы i, - это простой цикл.

PS Для простоты я использую два массива, но, очевидно, массив a можно удалить.

1 голос
/ 03 апреля 2017
public class Knapsackproblem {
    private static int[][] cache;
    public static void main(String[] args) {
        int val[] = new int[]{60, 100, 120};
        int wt[] = new int[]{10, 20, 30};
        int  W = 50;
        int n = val.length;
        System.out.println(knapSack(W, wt, val, n));
        printValues(wt,val);
    }

    /**
     * This method will find the result with
     * more value with weight less than or equal
     * to given weight
     * @param w given weight
     * @param wt arrays of weights
     * @param val array of values
     * @param n length of the array
     * @return max value we can obtain
     */
    private static int knapSack(int w, int[] wt, int[] val, int n) {
    cache = new int[n+1][w+1];
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= w; j++) {
                if(j < wt[i-1]){
                    cache[i][j] = cache[i-1][j];
                }else {
                    cache[i][j] = Math.max(cache[i-1][j],(cache[i-1][j-wt[i-1]])+val[i-1]);
                }
            }
        }
        for (int[] aCache : cache) {
            System.out.println(Arrays.toString(aCache));
        }
        return cache[n][w];
    }

    private static void printValues(int[] wt, int[] val) {
        int m = cache.length-1;
        int n = cache[0].length-1;
        util(wt,val,m,n);
    }

    private static void util(int[] wt, int[] val, int m, int n) {
        if(m <=0 || n<=0) return;
        if((cache[m][n] != cache[m-1][n]) && (cache[m][n] != cache[m][n-1])){
            System.out.println(val[m-1]+"-->"+wt[m-1]);
            util(wt, val, m-1, (n - wt[m - 1] + 1));
        }else
        if(cache[m][n] == cache[m-1][n]){
            util(wt,val,m-1,n);
        }
        else if(cache[m][n] == cache[m][n-1])
            util(wt,val,m,n-1);
        else
            util(wt,val,m,(n-val[m-1]+1));
    }
}
1 голос
/ 02 января 2017

Проверьте золь на прикрепленном изображении The below image has the snippet

1 голос
/ 04 января 2015
boolean[] solution = new boolean[nItems];

for (int i = nItems, c = maxCapacity; i > 0 && c > 0; i--) {
    int iThItemAddedValue = value[i - 1][c - weights[i - 1]] + values[i - 1];
    int iThItemInheritedValue = value[i - 1][c];

    if (iThItemAddedValue > iThItemInheritedValue) {
        solution[i - 1] = true;
        c = c - weights[i - 1];
    } else {
        solution[i - 1] = false;
    }
}
0 голосов
/ 02 января 2017

https://www.dropbox.com/s/ish7t5vgy91fovt/Screenshot%202017-01-01%2015.16.31.png?dl=0

Распечатайте tmpList в вызывающей программе, и вы получите ответ

...