как модифицировать Knapsack - найти максимальную взвешенную сумму

Ниже приведен код ранца, использующий динамическое программирование. Исходный код вернет максимальную сумму значений. Однако я хочу настроить его так, чтобы код возвращал максимальную сумму (значение * вес). Ниже показано, что я сделал, но это не работает, некоторые советы приветствуются.

 #include<stdio.h>
int max(int a,int b)
{
        return a>b?a:b;
}
int Knapsack(int items,int weight[],int value[],int maxWeight)
{
        int dp[items+1][maxWeight+1];
        /* dp[i][w] represents maximum value that can be attained if the maximum weight is w and
           items are chosen from 1...i */
        /* dp[0][w] = 0 for all w because we have chosen 0 items */
        int iter,w;
        for(iter=0;iter<=maxWeight;iter++)
        {
                dp[0][iter]=0;
        }
        /* dp[i][0] = 0 for all w because maximum weight we can take is 0 */
        for(iter=0;iter<=items;iter++)
        {
                dp[iter][0]=0;
        }
        for(iter=1;iter<=items;iter++)
        {
                for(w=0;w<=maxWeight;w=w+10)
                {
                        dp[iter][w] = dp[iter-1][w]*weight[iter-1]; /* If I do not take this item */
                        if(w-weight[iter] >=0)
                        {
                                /* suppose if I take this item */
                                dp[iter][w] = max( (dp[iter][w]*weight[iter]) , (dp[iter-1][w-weight[iter]]*weight[iter-1])+(value[iter]*weight[iter]));
                        }
                }

        }
        return dp[items][maxWeight];
}
int main()
{
        int items=12;
        int weight[/*items+1*/13]={60, 20, 20, 20, 10, 20, 10, 10, 10, 20, 20, 10};
        int value[/*items+1*/13]={48, 77, 46, 82, 85, 43, 49, 73, 65, 48, 47, 51};
        int iter;

        int maxWeight=120;
        printf("Max value attained can be %d\n",Knapsack(items,weight,value,maxWeight));
}

Ожидается, что код выдаст результат Максимальное достигнутое значение может быть 7820 (максимальная общая сумма значения * веса, рассчитанная вручную). Однако на выходе получается Максимальное достигнутое значение может быть равно 0. Почему?


person Voyage_Mystere    schedule 25.12.2013    source источник
comment
Вы также должны упомянуть о том, что вы получаете и каков ваш ожидаемый результат.   -  person haccks    schedule 25.12.2013
comment
Спасибо за указание, отредактируйте это прямо сейчас ~   -  person Voyage_Mystere    schedule 25.12.2013


Ответы (1)


Я думаю, что проблему можно решить, просто внеся следующие изменения:

В исходной задаче о рюкзаке замените все values на value*weight и действуйте как обычно, чтобы максимизировать общее значение.

http://en.wikipedia.org/wiki/Knapsack_problem

Это должно прийти к тому же, если вы измените:

dp[iter][w] = dp[iter-1][w]*weight[iter-1]; /* If I do not take this item */
if(w-weight[iter] >=0)
{
  /* suppose if I take this item */
  dp[iter][w] = max( (dp[iter][w]*weight[iter]) , (dp[iter-1][w-weight[iter]]*weight[iter-1])+(value[iter]*weight[iter]));
}

to

dp[iter][w] = dp[iter-1][w]; /* If I do not take this item */
if(w-weight[iter] >=0)
{
  /* suppose if I take this item */
  dp[iter][w] = max( dp[iter][w] , (dp[iter-1][w-weight[iter]]+(value[iter]*weight[iter]));
}
person Abhishek Bansal    schedule 25.12.2013
comment
Это волшебство! Большое спасибо! Теперь я успешно получил выход 7820. Хотя я действительно не понимаю концепцию, стоящую за этим. - person Voyage_Mystere; 25.12.2013
comment
@Voyage_Mystere Чего ты не понимаешь? вместо того, чтобы напрямую максимизировать сумму значений, вы можете сначала изменить свои значения на значение * вес, а затем максимизировать сумму значений. - person Abhishek Bansal; 25.12.2013
comment
Ошибка в вашем коде заключалась в том, что dp[][] уже состоит из суммы значений * веса, поэтому вам не следует снова умножать его на вес. - person Abhishek Bansal; 25.12.2013
comment
Да, теперь я это понимаю, но я все еще не понимаю концепцию рюкзака. Почему мы должны указывать вес[предмет+1] вместо веса[предмет]? (здесь элемент относится к номеру элемента) - person Voyage_Mystere; 25.12.2013
comment
Вы должны попытаться изучить эту ссылку подробно. Он очень хорошо объясняет алгоритм динамического программирования. en.wikipedia.org/wiki/Knapsack_problem - person Abhishek Bansal; 25.12.2013
comment
Хорошо, спасибо за помощь! - person Voyage_Mystere; 25.12.2013