-2

I want to code the 01 Knapsack problem with c++. Each time I change the value of a constant MAX to a different value, such as 100,90, or 80, the result is different. What's the cause? I'm using Visual Studio 2019.

The input is a text file, for example.

20

40 35 18 4 10 2 70 20 39 37 7 5 10 8 15 21 50 40 10 30

100 50 45 20 10 5 31 10 20 19 4 3 6 8 12 7 10 2 5 5

137

The first row is the number of objects, the second row is the price, the third row is the weight, and the last row is the size of the knapsack.

#include <stdio.h>
#include <time.h>
#define MAX 100
#define CLOCKS_PER_MS CLOCKS_PER_SEC/1000

int X_d[MAX] = { 0 }; //solution vector

int max(int a, int b) {
if (a >= b)
    return a;
else
    return b;
}

void dynamic(int n, int M, int p[], int w[]) {
int result;
int i, y, k;
int P[MAX][MAX] = { 0 };
clock_t start, finish;

start = clock();
for (i = 0; i <= n; i++) {
    for (y = 0; y <= M; y++) {
        if (i == 0 || y == 0)
            P[i][y] = 0;
        else if (w[i - 1] > y)
            P[i][y] = P[i - 1][y];
        else
            P[i][y] = max(P[i - 1][y], p[i - 1] + P[i - 1][y - w[i - 1]]);
    }
}
finish = clock();
result = P[n][M];
y = M;
for (i = n; i > 0 && result > 0; i--) {
    if (result == P[i - 1][y]) {
        continue;
    }
    else {
        X_d[i - 1] = 1;
        result = result - p[i - 1];
        y = y - w[i - 1];
    }
}

printf("\n(1) Dynamic Programming");
printf("\nThe maximum profit is $%d", P[n][M]);
printf("\nThe solution vetor X = ( ");
for (k = 0; k < n; k++)
    printf("%d ", X_d[k]);
printf(")\n");
printf("The execution time is %f milliseconds.\n", (float)(finish - start) / CLOCKS_PER_MS);
}

int main() {
int i, j;
int num, M;
int p[MAX] = { 0 }, w[MAX] = { 0 };
FILE* fp = NULL;


fopen_s(&fp, "p2data6.txt", "r");
fscanf_s(fp, "%d", &num);

for (i = 0; i < num; i++)
    fscanf_s(fp, "%d", &p[i]);

for (i = 0; i < num; i++)
    fscanf_s(fp, "%d", &w[i]);

fscanf_s(fp, "%d", &M);

printf("n = %d\n", num);
printf("pi = ");
for (i = 0; i < num; i++)
    printf("%3d ", p[i]);
printf("\nwi = ");
for (i = 0; i < num; i++)
    printf("%3d ", w[i]);
printf("\npi/wi = ");
for (i = 0; i < num; i++)
    printf("%f ", (double)p[i] / w[i]);
printf("\nM = %d\n", M);

dynamic(num, M, p, w);

return 0;
}
  • 2
    offtopic: dont use macros for constants. Consider what happens if you had a function declared as `void foo(double MAX);` you can avoid this and other problems at (almost) no cost with `const size_t MAX = 100;` – 463035818_is_not_an_ai May 28 '19 at 16:09
  • 1
    In your loop conditions you need `i < n;` and `y < M` as is your program has _undefined behavior_. – πάντα ῥεῖ May 28 '19 at 16:14
  • 2
    If you had used `std::vector` instead of raw arrays, and in addition sized the vector using `m` and `n` as the sizes instead of MAX, Visual Studio would have detected the error. – PaulMcKenzie May 28 '19 at 16:33
  • I changed MAX to 500, and the problem was solved. But I still don't know the cause of the problem. – snowyMountain May 28 '19 at 17:08

1 Answers1

-2

Geeks for Geeks has a very good explanation of this problem here:

To quote the Geeks for Geeks article by Sam007:

A simple solution is to consider all subsets of items and calculate the total weight and value of all subsets. Consider the only subsets whose total weight is smaller than W. From all such subsets, pick the maximum value subset.

1) Optimal Substructure: To consider all subsets of items, there can be two cases for every item: (1) the item is included in the optimal subset, (2) not included in the optimal set. Therefore, the maximum value that can be obtained from n items is max of following two values. 1) Maximum value obtained by n-1 items and W weight (excluding nth item). 2) Value of nth item plus maximum value obtained by n-1 items and W minus weight of the nth item (including nth item).

If weight of nth item is greater than W, then the nth item cannot be included and case 1> is the only possibility.

2) Overlapping Subproblems Following is recursive implementation that simply follows the recursive structure mentioned above.

Dylan Gentile
  • 146
  • 1
  • 5