R中具有递归函数的KnapSack动态规划

Posted

技术标签:

【中文标题】R中具有递归函数的KnapSack动态规划【英文标题】:KnapSack dynamic programming in R with recursive function 【发布时间】:2016-10-24 15:49:37 【问题描述】:

我在 R 中创建了这个简单的代码来解决带有递归函数的背包程序

n <- c(0,1,2,3,4)
v <- c(10,40,30,50)
w <- c(5,4,6,3)
k <- 10


myfunction  <- function(n,k)
  if (n==0 | k==0)
  output <- 0
   else if (w[i] > k) 
        output <- myfunction[i-1,w]
   else 
        output <- max(v[i]+ myfunction(i-1, k-w[i]),myfunction(i-1,k))
      
return(myfunction)

但是,我没有得到一个值作为输出,而是整个函数。例如,如果我输入: 我的函数(4,10)

我没有得到 90 的值,但整个函数都输入了。

这些是值

【问题讨论】:

您应该使用return(output) 而不是return(myfunction)。此外,您在函数中使用了i,但未定义,因此必须更正该函数。 【参考方案1】:

除了@etienne 指出的错误之外,还有几个错误。这是一个带注释的调试会话。首先我们修复返回的对象:

> myfunction  <- function(n,k)
+   if (n==0 | k==0)
+   output <- 0
+    else if (w[i] > k) 
+         output <- myfunction[i-1,w]
+    else 
+         output <- max(v[i]+ myfunction(i-1, k-w[i]),myfunction(i-1,k))
+       
+ return(output)
+ 
> myfunction(4,10)
Error in if (w[i] > k)  : argument is of length zero

显然 w 和 k 的长度都不为零,这表明它必须是 i。 (正如 etienne 也指出的那样)。查看您的代码,您似乎实际上希望 i 成为在满足终止条件之前减少的索引。因此,在出现的少数情况下将n 替换为i

> myfunction  <- function(i,k)
+   if (i==0 | k==0)
+   output <- 0
+    else if (w[i] > k) 
+         output <- myfunction[i-1,w]
+    else 
+         output <- max(v[i]+ myfunction(i-1, k-w[i]),myfunction(i-1,k))
+       
+ return(output)
+ 
> myfunction(4,10)
Error in myfunction[i - 1, w] : 
  object of type 'closure' is not subsettable

所以你也犯了一个错误,在需要括号的地方使用方括号(在世界的非美国部分也称为括号):

> myfunction  <- function(i,k)
+   if (i==0 | k==0)
+   output <- 0
+    else if (w[i] > k) 
+         output <- myfunction(i-1,w)
+    else 
+         output <- max(v[i]+ myfunction(i-1, k-w[i]),myfunction(i-1,k))
+       
+ return(output)
+ 
> myfunction(4,10)
[1] 90

成功,嗯,差不多。大多数警告是因为您在其中一个条件句中使用了| 而不是||

Warning messages:
1: In if (i == 0 | k == 0)  :
  the condition has length > 1 and only the first element will be used
2: In if (w[i] > k)  :
  the condition has length > 1 and only the first element will be used
3: In if (i == 0 | k == 0)  :
  the condition has length > 1 and only the first element will be used
4: In if (i == 0 | k == 0)  :
  the condition has length > 1 and only the first element will be used
5: In if (i == 0 | k == 0)  :
  the condition has length > 1 and only the first element will be used
6: In if (i == 0 | k == 0)  :
  the condition has length > 1 and only the first element will be used

所以用逻辑 || 替换该实例。要处理似乎没有破坏您的逻辑的其他警告,请意识到w[i]i == 0 时长度为0,因此在条件中添加一个逻辑子句,首先测试这种可能性并使用正确的“双-AND-签名”(&amp;&amp;):

myfunction  <- function(i,k)
  if (i==0 || k==0)
  output <- 0
   else if (length( w[i]) && w[i] > k) 
        output <- myfunction(i-1,w)
   else 
        output <- max(v[i]+ myfunction(i-1, k-w[i]), myfunction(i-1,k))
      
return(output)

现在你得到:

> myfunction(4,10)
[1] 90

【讨论】:

以上是关于R中具有递归函数的KnapSack动态规划的主要内容,如果未能解决你的问题,请参考以下文章

动态规划-背包问题 Knapsack

动态规划:0/1 背包 - 将组合检索为数组

递归与动态规划

左程云-递归和动态规划

动态规划(DP)

关于递归和动态规划的简单理解