【问题标题】:function for solving 0/1 knapsack problem using Brute-force recursive solution [closed]使用蛮力递归解决方案解决 0/1 背包问题的函数 [关闭]
【发布时间】:2022-01-09 03:28:12
【问题描述】:

我正在尝试使用蛮力递归解决方案解决 0/1 背包问题的代码,但是当我将问题的大小(利润和权重数组)设为 100 时,它会一直运行而没有任何输出。如果有的话能告诉我为什么吗?以及如何解决。

如果有人能告诉我什么时候可以找到可信的伪代码和 0/1 背包问题的代码。

#include <iostream>
#include <ctime>
#include <cmath>

using namespace std;
//Return the maximum value that can be put in a knapsack of capacity W
int knapsackRecursive(int profits[], int profitsLength, int weights[], int capacity, int currentIndex) {
    // Base Case 
    if (capacity <= 0 || currentIndex >= profitsLength || currentIndex < 0)
        return 0;

    //If weight of the nth item is more than knapsack capacity W, then 
    // this item cannot be included in the optimal solgurion
    int profit1 = 0;
    if (weights[currentIndex] <= capacity)
        profit1 = profits[currentIndex] + knapsackRecursive(profits, profitsLength, weights, capacity - weights[currentIndex], currentIndex + 1);

    int profit2 = knapsackRecursive(profits, profitsLength, weights, capacity, currentIndex + 1);

    //Return the maximum of two cases:
    //(1) nth item included
    //(2) not included

    return max(profit1, profit2);
}

int knapSack(int profits[], int profitsLength, int weights[], int capacity) {
    return knapsackRecursive(profits, profitsLength, weights, capacity, 0);

}


int main() {
    int profits[100];
    int weights[100];
    int capacity = 300;
    srand(time(0));


    clock_t startTime;
    clock_t endTime;
    clock_t timeTaken = 0;

    for (int i = 0; i < 20; i++) {      //repeat the knapSack 20 times

        for (int j = 0; j < 100; j++) {
            profits[j] = 1 + (rand() % 100);
            weights[j] = 1 + (rand() % 100);
        }
        startTime = clock();
        knapSack(profits, 100, weights, capacity);
        endTime = clock();
        timeTaken = timeTaken + (endTime - startTime);      //compute the total cpu time 
    }

    cout << "The avearage of the time taken is" << ((float)timeTaken / CLOCKS_PER_SEC) / 20 << " seconds";



    return 0;
}

【问题讨论】:

标签: c++ recursion knapsack-problem brute-force


【解决方案1】:

将大小设置为 100 只会使时间过长。指数运行时间可不是开玩笑的。

我不知道你的代码是否正确,但只要看看它,我就可以看到唯一改变的递归调用参数是 capacitycurrentIndex 所以很容易在你的代码中应用 memoization代码,这将是一个巨大的加速。基本上,记忆只是意味着通过将之前计算的结果存储在一个表中来重复使用它们,而不是每次都重新计算。

代码如下:

#include <iostream>
#include <cmath>
#include <tuple>
#include <unordered_map>
#include <functional>

using key_t = std::tuple<int, int>;

struct tuple_hash_t  {
    std::size_t operator()(const key_t& k) const {
        return std::hash<int>{}(std::get<0>(k) ^ std::get<1>(k)); // or use boost::hash_combine
    }
};

using memoization_tbl = std::unordered_map<std::tuple<int, int>, int, tuple_hash_t>;

//Return the maximum value that can be put in a knapsack of capacity W
int knapsackRecursive(memoization_tbl& tbl, int profits[], int profitsLength, int weights[], int capacity, int currentIndex) {

    // Base Case 
    if (capacity <= 0 || currentIndex >= profitsLength || currentIndex < 0)
        return 0;

    // just return the memoized call if we already have a result...
    auto iter = tbl.find(key_t(capacity, currentIndex));
    if (iter != tbl.end()) {
        return iter->second;
    }

    //If weight of the nth item is more than knapsack capacity W, then 
    // this item cannot be included in the optimal solgurion
    int profit1 = 0;
    if (weights[currentIndex] <= capacity)
        profit1 = profits[currentIndex] + knapsackRecursive(tbl, profits, profitsLength, weights, capacity - weights[currentIndex], currentIndex + 1);

    int profit2 = knapsackRecursive(tbl, profits, profitsLength, weights, capacity, currentIndex + 1);

    //Return the maximum of two cases:
    //(1) nth item included
    //(2) not included

    auto result = std::max(profit1, profit2);
    tbl[key_t(capacity, currentIndex)] = result;

    return result;
}

int knapSack(int profits[], int profitsLength, int weights[], int capacity) {
    memoization_tbl tbl;
    return knapsackRecursive(tbl, profits, profitsLength, weights, capacity, 0);
}

int main() {
    int profits[100];
    int weights[100];
    int capacity = 300;
    srand(time(0));

    for (int j = 0; j < 100; j++) {
        profits[j] = 1 + (rand() % 100);
        weights[j] = 1 + (rand() % 100);
    }

    std::cout << knapSack(profits, 100, weights, capacity) << "\n";

    return 0;
}

【讨论】:

    猜你喜欢
    • 2014-12-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-29
    • 1970-01-01
    相关资源
    最近更新 更多