【问题标题】:trouble with solving knapsack issue via dynamic programming in C通过 C 中的动态编程解决背包问题的麻烦
【发布时间】:2015-07-20 09:55:24
【问题描述】:

我需要递归、记忆和动态规划来解决背包问题。目前我停留在动态编程方法上。

我根据在互联网上其他地方找到的代码改编了代码。目前输出不正确。

问题涉及利润和质量。每个项目都有关联的利润和质量,有 MAX_N(数量)个可用项目和 MAX_CAPACITY 用于质量。目的是在背包中获得尽可能多的“利润”。

以下是练习提供的示例:

示例:给定一个容量为 5 的背包,物品的质量 [] = {2, 4, 3, 2} 和利润利润[] = {45, 40, 25, 15},最佳组合是项目 0(质量为 2,利润为 45)和项目 2(质量为 3,利润为 25),总利润为 70。没有其他质量 5 或更少的组合具有更大的利润。

完整代码如下:

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

#define MAX_N 10
#define MAX_CAPACITY 165

int m[MAX_N][MAX_CAPACITY];

int max(int x, int y) {
    return x ^ ((x ^ y) & -(x < y));
}

int min(int x, int y) {
    return y ^ ((x ^ y) & -(x < y));
}

int knapsackRecursive(int capacity, int mass[], int profit[], int n) {

    if (n < 0)
        return 0;

    if (mass[n] > capacity)
        return knapsackRecursive(capacity, mass, profit, n-1);

    else
        return max(knapsackRecursive(capacity, mass, profit, n-1), knapsackRecursive(capacity - mass[n], mass, profit, n-1) + profit[n]);

}

int knapsackMemoized(int capacity, int mass[], int profit[], int n) {

}

int knapsackDynamic(int capacity, int mass[], int profit[], int n) {

    int i;
    int j;

    for (i = 0; i <= n; i++) {

        for (j = 0; j <= capacity; j++) {

            if (i == 0 || j == 0)
                m[i][j] = 0;

            else if (mass[i-1] <= j)
                m[i][j] = max(profit[i-1] + m[i-1][j-mass[i-1]], m[i-1][j]);

            else
                m[i][j] = m[i-1][j];
        }
    }

    return m[n][capacity];

}

void test() {

    // test values
    //int M1[MAX_N] = {2, 4, 3, 2};
    //int P1[MAX_N] = {45, 40, 25, 10};

    int M1[MAX_N] = {6, 3, 2, 4};
    int P1[MAX_N] = {50, 60, 40, 20};

    int M2[MAX_N] = {23, 31, 29, 44, 53, 38, 63, 85, 89, 82};
    int P2[MAX_N] = {92, 57, 49, 68, 60, 43, 67, 84, 87, 72};

    // a)
    printf("Recursion: %d\n",knapsackRecursive(MAX_CAPACITY, M1, P1, MAX_N));
    printf("Recursion: %d\n",knapsackRecursive(MAX_CAPACITY, M2, P2, MAX_N));
    printf("\n");

    // b)
    printf("Memoization: %d\n",knapsackMemoized(MAX_CAPACITY, M1, P1, MAX_N));
    printf("Memoization: %d\n",knapsackMemoized(MAX_CAPACITY, M2, P2, MAX_N));
    printf("\n");

    // c)
    printf("Dynamic Programming: %d\n",knapsackDynamic(MAX_CAPACITY, M1, P1, MAX_N));
    printf("Dynamic Programming: %d\n",knapsackDynamic(MAX_CAPACITY, M2, P2, MAX_N));

}

int main() {
    test();
}

这是我目前得到的输出。递归方法应该提供正确的结果,但动态编程目前不输出相同的结果。记忆还没有完成,因此它也不能正确输出。

Recursion: 170
Recursion: 309

Memoization: 2686680
Memoization: 2686600

Dynamic Programming: 0
Dynamic Programming: 270

Process returned 25 (0x19)   execution time : 0.269 s
Press any key to continue.

【问题讨论】:

    标签: c dynamic-programming knapsack-problem


    【解决方案1】:

    事实证明,我用于编写动态编程部分的代码应该与 int m[MAX_N+1][MAX_CAPACITY+1]; 一起使用,而不是 int m[MAX_N][MAX_CAPACITY];

    改变这让我得到了一个工作代码,如果不是我想要的代码。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-10-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-09-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多