对于固定数量的容器,这可以表述为整数线性规划问题。如果 g 是 10 个组号的向量,cap 是容量,即 80,则必须至少有 k=ceiling(sum(g) / cap) 容器且不超过 k=length(g) 。因此,我们从最小数量到最大数量的容器依次适应,一旦我们适应就停止。对于问题中显示的数据(见最后的注释),只需要一次迭代。
在lp 问题中,有 k × n 个二进制变量,如果我们将它们排列在 k × n 矩阵中,那么如果第 i 个容器包含元素 j,则第 i,j-th 为 1,否则为 0。
lp 问题有 k+n 个约束。前 k 个约束将每个 k 个容器的总和约束为 cap,其余的 n 约束确保每个元素只能出现在一个容器中。
library(lpSolve)
stopifnot(all(g <= cap))
n <- length(g)
kmin <- ceiling(sum(g) / cap)
for(k in seq(kmin, n)) {
objective.in <- rep(1, k * n)
const.mat <- rbind(diag(k) %x% t(g), t(rep(1, k)) %x% diag(n))
const.dir <- c(rep("<=", k), rep("==", n))
const.rhs <- c(rep(cap, k), rep(1, n))
res <- lp("min", objective.in, const.mat, const.dir, const.rhs, all.bin = TRUE)
if (res$status == 0) break
}
# iterations
k - kmin + 1
## [1] 1
# solution - each col is an element, each row is a container
matrix(res$solution, k, byrow = TRUE)
## [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
## [1,] 1 1 1 1 1 0 0 1 0 0
## [2,] 0 0 0 0 0 1 1 0 0 1
## [3,] 0 0 0 0 0 0 0 0 1 0
注意
使用的输入是这样的:
Lines <- "Group 1: 20
Group 2: 5
Group 3: 15
Group 4: 10
Group 5: 12
Group 6: 26
Group 7: 41
Group 8: 15
Group 9: 69
Group 10: 9"
g <- read.table(text = Lines)$V3
cap <- 80