使用动态编程实现0-1背包

时间:2017-10-16 11:49:56

标签: c algorithm segmentation-fault dynamic-programming knapsack-problem

对于给定的weight,value,max_weight和total_items值,它正常工作,但是当我改变权重,值和其他变量时,它会给出分段错误。

我检查过,当我更改变量时,背包函数items->valueitems->weight变为NULL

items->max_weightitems->total_items变为0

我无法弄清楚代码中有什么问题,请提前帮助,谢谢。

代码

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

typedef struct
{
    int total_items, max_weight;
    int *weight, *value;
} Items_knapsack;


void knapsack(Items_knapsack *items, int solution[][items->max_weight + 1]);
int max(int a, int b);

int main (int argc, char *argv[])
{
    int max_weight = 7, total_items = 4;
    int weight[] = {0, 1, 3, 4, 5};
    int value[] = {0, 1, 4, 5, 7};

    Items_knapsack items = {.value = value, .weight = weight, .max_weight = max_weight, .total_items = total_items};
    int solution[total_items + 1][max_weight + 1];

    knapsack(&items, solution);

    for ( int i = 0; i < total_items + 1; i += 1 )
    {
        for ( int j = 0; j < max_weight + 1; j += 1 )
        {
            printf("%d ", solution[i][j]);
        }

        printf("\n");
    }

    return 0;

}

void knapsack(Items_knapsack *items, int solution[][items->max_weight + 1])
{
    int total_items = items->total_items;
    int max_weight = items->max_weight;

    for ( int *i = (int *) solution; i < &solution[total_items + 1][(max_weight + 1)]; i += 1 )
    {
        *i = 0;
    }

    for ( int i = 1; i < total_items + 1; i += 1 )
    {
        for ( int j = 1; j < max_weight + 1; j += 1 )
        {
            int w = *(items->weight + i); //weight of current item
            int v = *(items->value + i); //value of current item

            if ( w > j )
            {
                solution[i][j] = solution[i - 1][j];
            }

            else
            {
                solution[i][j] = max(v + solution[i - 1][j - w], solution[i - 1][j]);
            }
        }
    }
}

int max(int a, int b)
{
    return (a > b) ? a : b;
}

1 个答案:

答案 0 :(得分:0)

Valgrind报道:

==8563== Invalid read of size 4
==8563==    at 0x108977: knapsack (17640299.c:53)
==8563==    by 0x108831: main (17640299.c:23)
==8563==  Address 0x4 is not stack'd, malloc'd or (recently) free'd

这是循环:

    for ( int j = 1; j < max_weight + 1; j += 1 )
    {
        int w = *(items->weight + i); //weight of current item
        int v = *(items->value + i); //value of current item

(我不确定为什么这些内容不会被写成更易读的items->weight[i]items->value[i]

我重新编写了方法,以便更清楚地阅读,并且不再能够触发此失败:

void knapsack(const Items_knapsack *items,
              int solution[items->total_items+1][items->max_weight + 1])
{
    const int total_items = items->total_items;
    const int max_weight = items->max_weight;

    for (int i = 0;  i <= total_items;  ++i)
        for (int j = 0;  j <= max_weight;  ++j)
            solution[i][j] = 0;

    for (int i = 1;  i <= total_items;  ++i) {
        const int w = items->weight[i]; //weight of current item
        const int v = items->value[i]; //value of current item

        for (int j = 1;  j <= max_weight;  ++j) {
            if (w > j) {
                solution[i][j] = solution[i-1][j];
            } else {
                solution[i][j] = max(v + solution[i-1][j-w],
                                     solution[i-1][j]);
            }
        }
    }
}