每次更改常数,结果都是不同的

时间:2019-05-28 16:03:56

标签: c++ dynamic-programming knapsack-problem visual-studio-2019

我想用c ++编写01背包问题。每次我将常数MAX的值更改为不同的值(例如100,90或80)时,结果都是不同的。是什么原因我正在使用Visual Studio 2019。

例如,输入是一个文本文件。

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

第一行是物品的数量,第二行是价格,第三行是重量,最后一行是背包的大小。

#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;
}

1 个答案:

答案 0 :(得分:-2)

Geeks for Geeks对这个问题here有很好的解释:

引用Sam007的Geeks for Geeks文章:

  

一个简单的解决方案是考虑项目的所有子集并计算所有子集的总重量和价值。仅考虑总权重小于W的子集。从所有此类子集中,选择最大值子集。

     

1)最佳子结构:   为了考虑项目的所有子集,每个项目可能有两种情况:(1)项目包括在最优子集中,(2)不包括在最优集合中。   因此,可以从n个项目获得的最大值是以下两个值中的最大值。   1)通过n-1个项和W权重(不包括第n个项)获得的最大值。   2)第n个项目的值加上n-1个项目获得的最大值以及W减去第n个项目(包括第n个项目)的重量。

     

如果第n个项目的权重大于W,则不能包含第n个项目,并且情况1>是唯一的可能性。

     

2)重叠子问题   以下是简单地遵循上述递归结构的递归实现。