knapsack() 向量长度问题

Posted

技术标签:

【中文标题】knapsack() 向量长度问题【英文标题】:knapsack() vector length issues 【发布时间】:2016-01-24 19:47:04 【问题描述】:

当我跑步时

weights <- 1:50
profits <- 1:50
library(adagio)
knapsack(w = weights, p = profits, cap = 30)

我得到了错误

Error in F[, k] <- G : 
  number of items to replace is not a multiple of replacement length
In addition: Warning message:
In pmax(G, H) : an argument will be fractionally recycled

但是当我运行较小尺寸的向量时,比如

weights <- 1:20
profits <- 1:20
knapsack(w = weights, p = profits, cap = 30)

它运行良好。 knapsack() 是否只是减慢(并阻止运行)更大的集合?我希望最终使用数千个长度。

【问题讨论】:

cap = 30 和它有关系吗?当我将cap=30 更改为cap=60 时,错误消失了。但是,这并不意味着这是正确的解决方案。 奇怪,10,20,40 有相同的结果。 cap = 50, 60, 70 给出结果。 但这并不能解决问题,我不清楚为什么会发生这种情况,以及是否可以避免 【参考方案1】:

这是传递重量超过总容量的元素的问题。看问题,我们看knapsack函数的前几行:

function (w, p, cap) 

    n <- length(w)
    x <- logical(n)
    F <- matrix(0, nrow = cap + 1, ncol = n)
    G <- matrix(0, nrow = cap + 1, ncol = 1)
    for (k in 1:n) 
        F[, k] <- G
        H <- c(numeric(w[k]), G[1:(cap + 1 - w[k]), 1] + p[k])
        G <- pmax(G, H)
    

当迭代地一次填充F 矩阵一列时,算法使用以下命令创建一个向量H(然后立即计算pmax(G, H)):

H <- c(numeric(w[k]), G[1:(cap + 1 - w[k]), 1] + p[k])

numeric(w[k]) 的长度为w[k],当w[k] &lt;= cap 时,G[1:(cap + 1 - w[k]), 1] + p[k] 的长度为cap + 1 - w[k],这意味着整个向量H 的长度为cap+1,与G 的大小匹配。另一方面,当w[k] == cap + 1 时,我们将得到一个大小为cap+2H 向量,它与G 的大小不匹配,给我们带来麻烦,而使用w[k] &gt; cap + 1,我们将得到一个混合正负索引的错误。

回到您的示例函数调用,您的权重最多为 50,但容量仅为 30,会产生错误:

weights <- 1:50
profits <- 1:50
knapsack(w = weights, p = profits, cap = 30)
# Error in F[, k] <- G : 
#   number of items to replace is not a multiple of replacement length
# In addition: Warning message:
# In pmax(G, H) : an argument will be fractionally recycled

但是,当您限制重量不超过容量的元素时,您不会出错:

knapsack(w = weights[weights <= 30], p = profits[weights <= 30], cap = 30)
# $capacity
# [1] 30
# 
# $profit
# [1] 30
# 
# $indices
# [1] 1 2 3 4 5 7 8

如果knapsack 函数优雅地删除任何重量超过容量的对象(因为在可行的解决方案中永远无法使用此类元素)并为您发布的代码提供解决方案,那将是最理想的,但作为一种解决方法,您可以简单地将它们从knapsack 函数的输入中删除。

【讨论】:

【参考方案2】:

我收到了同样的错误(这就是我得到这篇 SO 帖子的方式..)我认为 adagio knapsack 函数不喜欢作为小数值的利润或权重。我使用 rnorm() 来生成利润和权重,将它们的结果与我个人编写的另一个背包函数进行比较。即使容量比所有重量总和大几倍,我也遇到了“回收”错误。但是,当我在将 rnorm() 向量作为参数传递给背包之前对其进行四舍五入时,没有问题。

【讨论】:

以上是关于knapsack() 向量长度问题的主要内容,如果未能解决你的问题,请参考以下文章

knapsack

如何在 KnapSack 问题中显示所有包含的数字?

修改了 KnapSack 运行时错误

knapSack 背包问题

knapSack 背包问题

knapSack 背包问题