web-dev-qa-db-fra.com

Comment répliquer le solveur Excel dans R

J'ai utilisé le solveur Excel pour résoudre un problème d'optimisation et j'essaie de le reproduire dans R.

J'ai trouvé de nombreux packages comme optim, ROI etc., mais il semble que tous ne prennent qu'un vecteur comme objet à optimiser et permettent aux variables de prendre n'importe quelle valeur continue. Dans mon cas, j'ai une matrice de contraintes qui doit également être satisfaite et mes variables ne peuvent prendre que des valeurs binaires.

Voici le problème que je veux résoudre:

A-D sont des machines, 1-3 sont des tâches et le nombre dans la première matrice est la valeur générée en utilisant la machine X pour effectuer la tâche Y. Les contraintes sont: A-D peut faire et ne peut faire qu'une seule tâche (ne peut pas se diviser); chaque tâche peut être exécutée et ne peut être exécutée que par une seule machine.

Voici le code que j'utilise:

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)

Quelques questions: Comment puis-je optimiser au maximum, semble que cette fonction optimise par défaut au minimum? Comment puis-je y ajouter des contraintes? Comment puis-je me limiter aux variables binaires?

15
Yoki

Vous devez construire un vecteur pour la fonction objectif et une matrice de contraintes, pour finalement résoudre avec l'un des solveurs 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))

Vous pouvez maintenant saisir la solution et la fonction objectif:

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

Notez que des fonctions comme optim ne sont pas bien adaptées à ce problème à la fois parce qu'elles ne prennent pas en compte les matrices de contraintes et aussi parce qu'elles ne peuvent pas se limiter aux valeurs de variables binaires.

15
josliber