背包()矢量长度问题

时间:2016-01-24 19:47:05

标签: r mathematical-optimization knapsack-problem

当我跑步时

RenderOptions

我收到错误

forfiles -p "t:\jeopardy" -s -m *.* /D -3 /C "cmd /c del @path"

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

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

运行正常。 knapsack()是否会减慢(并阻止运行)更大的集合?我最终希望使用成千上万的长度。

2 个答案:

答案 0 :(得分:2)

这是传递重量超过总容量的元素的问题。要查看问题,让我们看一下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] <= cap时,G[1:(cap + 1 - w[k]), 1] + p[k]的长度为cap + 1 - w[k],意味着整个向量H的长度为cap+1 1}},匹配G的大小。另一方面,当w[k] == cap + 1时,我们最终会得到H大小为cap+2的{​​{1}}向量,该大小与G的大小不匹配并给我们带来麻烦,使用w[k] > 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函数的输入中删除它们。

答案 1 :(得分:1)

我收到了同样的错误(这就是我得到这个帖子的方式..)我认为adagio背包功能并不像利润或权重是小数值。我使用rnorm()来产生利润和权重,将他们的结果与我个人写的另一个背包函数进行比较。即使容量比放在一起的所有重量都大几倍,我也得到了“回收利用”。错误。然而,当我在将它们作为背包传递给背包之前舍入rnorm()向量时,没有问题。