web-dev-qa-db-ja.com

RでExcelソルバーを複製する方法

Excelソルバーを使用して最適化問題を解決し、それをRで再現しようとしています。

OptimやROIなどの多くのパッケージを見つけましたが、それらはすべて、最適化するオブジェクトとしてベクトルのみを取り、変数が任意の連続値を取ることができるようです。私の場合、満たす必要がある制約行列があり、変数はバイナリ値しか取ることができません。

ここに私が解決したい問題があります:

A〜Dはマシン、1〜3はタスクであり、最初の行列の数値は、Xマシンを使用してYタスクを実行することによって生成された値です。制約は次のとおりです。A-Dが実行できるタスクは1つだけです(分割することはできません)。各タスクは機能し、1台のマシンでのみ機能します。

これが私が使用しているコードです:

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)

いくつかの質問:最大値を最適化するにはどうすればよいですか、この関数のデフォルトは最小値を最適化しているようです。それに制約を追加するにはどうすればよいですか?バイナリ変数に制限するにはどうすればよいですか?

15
Yoki

目的関数と制約行列のベクトルを作成し、最後にR LPソルバーの1つで解く必要があります。

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のような関数は、制約の行列を考慮しないため、およびバイナリ変数値に制限できないため、この問題にはあまり適していません。

15
josliber