背包1/0实施需要解释

时间:2014-02-13 06:45:05

标签: c algorithm knapsack-problem

我正在尝试理解这种Knapsack 1/0 Problem的动态编程方法,但我没有得到算法。

请有人帮我解释这个具体的实施,从Rosetta Code转到我身上?

使用一些注释更新代码会有很大帮助!

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>

typedef struct {
        const char * name;
        int weight, value;
} item_t;

item_t item[] = {
        {"map",                     9,       150},
        {"compass",                 13,      35},
        {"water",                   153,     200},
        {"sandwich",                50,      160},
        {"glucose",                 15,      60},
        {"tin",                     68,      45},
        {"banana",                  27,      60},
        {"apple",                   39,      40},
        {"cheese",                  23,      30},
        {"beer",                    52,      10},
        {"suntancream",             11,      70},
        {"camera",                  32,      30},
        {"T-shirt",                 24,      15},
        {"trousers",                48,      10},
        {"umbrella",                73,      40},
        {"waterproof trousers",     42,      70},
        {"waterproof overclothes",  43,      75},
        {"note-case",               22,      80},
        {"sunglasses",              7,       20},
        {"towel",                   18,      12},
        {"socks",                   4,       50},
        {"book",                    30,      10}
};

#define n_items (sizeof(item)/sizeof(item_t))

typedef struct {
        uint32_t bits; /* 32 bits, can solve up to 32 items */
        int value;
} solution;


void optimal(int weight, int idx, solution *s)
{
        solution v1, v2;
        if (idx < 0) {
                s->bits = s->value = 0;
                return;
        }

        if (weight < item[idx].weight) {
                optimal(weight, idx - 1, s);
                return;
         }

        optimal(weight, idx - 1, &v1);
        optimal(weight - item[idx].weight, idx - 1, &v2);

        v2.value += item[idx].value;
        v2.bits |= (1 << idx);

        *s = (v1.value >= v2.value) ? v1 : v2;
}

int main(void)
{
        int i = 0, w = 0;
        solution s = {0, 0};
        optimal(400, n_items - 1, &s);

        for (i = 0; i < n_items; i++) {
                if (s.bits & (1 << i)) {
                        printf("%s\n", item[i].name);
                        w += item[i].weight;
                }
        }
        printf("Total value: %d; weight: %d\n", s.value, w);
        return 0;
}

提前多多感谢, skylla

1 个答案:

答案 0 :(得分:3)

  

我不明白为什么使用解决方案v1和v2,它们用于什么

它们分别对应于不包括或包括索引&#34; idx&#34;的项目。在解决方案中。

  

最佳()开头的2个if条件意味着......

if (idx < 0)意味着没有更多的项目需要考虑,它是递归的结束

if (weight < item[idx].weight)检查是否可以包含项idx。如果自身重量大于极限重量,则不可能包括在内。

另外,请注意,这不是动态编程,而是一个简单的递归算法,可生成所有可能的元素子集(此处和那里修剪的递归树)。