如何在R中复制Excel求解器

17

我使用Excel Solver解决了一个优化问题,现在想在R中复制它。

我找到了很多包,如optim、ROI等,但是似乎它们都只接受向量作为要优化的对象,并允许变量取任意连续值。而在我的情况下,我有一个需要满足的约束矩阵,我的变量只能取二进制值。

以下是我要解决的问题:

A-D是机器,1-3是任务,第一个矩阵中的数字是使用X机器完成Y任务产生的价值。约束条件是:A-D只能做一个任务(不能分割);每个任务只能由一台机器工作。

以下是我正在使用的代码:

par = rep(c(0,1),6)

mat <- matrix(c(9,10,11,4,5,10,1,3,5,7,5,4), nrow = 3)

fr <- function(x) {  
  y= matrix(x,nrow = 4)
  sum(mat %*% y)
}

a = optim(par, fr)

一些问题:如何将最大值优化,似乎此函数默认优化最小值?如何向其中添加约束条件?如何限制为二元变量?


矩阵是一个形状不规则的向量;调整其形状,您就可以开始编写向量优化代码(假设您了解如何编写向量优化的代码)。 xmat = matrix(1:4,ncol=2); x = c(xmat) - Frank
谢谢Frank!我尝试了一下,它起作用了。但是我有一些后续问题。我确实不知道如何为向量编写优化代码。 - Yoki
2
仅在求和函数后添加一个减号,优化器将最大化此函数。 - forecaster
1个回答

17

您需要构建一个目标函数向量和一个约束矩阵,最后使用R LP求解器之一来解决:

library(lpSolve)
costs <- matrix(c(9, 10, 11, 4, 5, 10, 1, 3, 5, 7, 5, 4), nrow=3)
nr <- nrow(costs)
nc <- ncol(costs)
columns <- t(sapply(1:nc, function(x) rep(c(0, 1, 0), c(nr*(x-1), nr, nr*(nc-x)))))
rows <- t(sapply(1:nr, function(x) rep(rep(c(0, 1, 0), c(x-1, 1, nr-x)), nc)))
mod <- lp("max", as.vector(costs), rbind(columns, rows), "<=", rep(1, nr+nc), binary.vec=rep(TRUE, nr*nc))

现在您可以获取解决方案和目标函数:
mod$objval
# [1] 27
matrix(mod$solution, nrow=nr)
#      [,1] [,2] [,3] [,4]
# [1,]    0    0    0    1
# [2,]    1    0    0    0
# [3,]    0    1    0    0

请注意,像 optim 这样的函数并不适用于此问题,因为它们既不考虑约束矩阵,也不能限制二进制变量值。

你好,能否请您解释一下整个过程是如何工作的?特别是为什么“columns”和“rows”必须重复。 - riders994
@riders994 基本上 rbind(columns, rows) 返回线性规划的约束矩阵,rep(1, nr+nc) 是右侧的系数,而 as.vector(costs) 是目标函数。我使用了 rep 和其他 R 函数来构建这个特定线性规划问题的约束矩阵。如果你有一个不同的问题,你可能会使用不同的代码来得到那个矩阵。你可以从它的帮助页面上了解 rep?rep - josliber
@josliber,您能否指导一下类似的问题。这真的会很有帮助。https://stackoverflow.com/q/72238988/8019264 - MysticRenge

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接