我的 Knapsack 递归解决方案可以改进吗?
Can my recursive solution for Knapsack be improved?
我正在尝试做背包问题,这是我想出的递归解决方案。这可以做得更好吗?我想我需要通过检查我之前是否达到过这种状态来添加记忆。我需要为 state[c_w][i]
添加状态,我说得对吗?
我故意没有使用动态规划,因为我知道它的递归关系,而是想正确地递归。
#include <stdio.h>
int memoize[1000][1000];
int max(int a, int b)
{
return a>b?a:b;
}
/* c_w-current weight of the container */
int max_profit_func(int *val, int *wt, int W, int c_w, int i, int size)
{
int max_profit = 0;
int j;
/* if the current item is beyond the range then we have 0 profit*/
if (i >= size)
return 0;
if (memoize[c_w][i] != -1)
return memoize[c_w][i];
/* get the profit with this index and if the profit is more than previous
* than store it */
for(j=i;j<size;j++) {
int profit = 0;
if (c_w+wt[j] <= W)
profit = val[j] + max_profit_func(val, wt, W, c_w+wt[j], j+1, size);
max_profit = max(max_profit, profit);
}
memoize[c_w][i] = max_profit;
return max_profit;
}
int main(void) {
int val[] = {3, 7, 2, 9};
int wt[] = {2, 3, 4, 5};
int W = 5;
memset(memoize, -1, sizeof(int)*1000*1000);
printf("%d\n", max_profit_func(val, wt, W, 0, 0, sizeof(wt)/sizeof(wt[0])));
return 0;
}
你是对的。当您的函数正在解决问题时,它会一次又一次地重新计算相同的事情。
您需要沿着二维数组拖动,这将跟踪您已经解决了哪些对 (c_w, i) 以及结果是什么。这叫记忆(不是记忆):http://en.wikipedia.org/wiki/Memoization
我正在尝试做背包问题,这是我想出的递归解决方案。这可以做得更好吗?我想我需要通过检查我之前是否达到过这种状态来添加记忆。我需要为 state[c_w][i]
添加状态,我说得对吗?
我故意没有使用动态规划,因为我知道它的递归关系,而是想正确地递归。
#include <stdio.h>
int memoize[1000][1000];
int max(int a, int b)
{
return a>b?a:b;
}
/* c_w-current weight of the container */
int max_profit_func(int *val, int *wt, int W, int c_w, int i, int size)
{
int max_profit = 0;
int j;
/* if the current item is beyond the range then we have 0 profit*/
if (i >= size)
return 0;
if (memoize[c_w][i] != -1)
return memoize[c_w][i];
/* get the profit with this index and if the profit is more than previous
* than store it */
for(j=i;j<size;j++) {
int profit = 0;
if (c_w+wt[j] <= W)
profit = val[j] + max_profit_func(val, wt, W, c_w+wt[j], j+1, size);
max_profit = max(max_profit, profit);
}
memoize[c_w][i] = max_profit;
return max_profit;
}
int main(void) {
int val[] = {3, 7, 2, 9};
int wt[] = {2, 3, 4, 5};
int W = 5;
memset(memoize, -1, sizeof(int)*1000*1000);
printf("%d\n", max_profit_func(val, wt, W, 0, 0, sizeof(wt)/sizeof(wt[0])));
return 0;
}
你是对的。当您的函数正在解决问题时,它会一次又一次地重新计算相同的事情。
您需要沿着二维数组拖动,这将跟踪您已经解决了哪些对 (c_w, i) 以及结果是什么。这叫记忆(不是记忆):http://en.wikipedia.org/wiki/Memoization