A programação linear possui muitas aplicações nas Ciências Sociais e Exatas.
Nesse post mostrarei como solucionar problemas de programação linear no R por meio da biblioteca lpSolveAPI.
Considere o seguinte problema de programação linear:
O primeiro passo no R para a resolução desse problema é invocar a biblioteca lpSolveAPI, para isso utilizamos o seguinte comando:
#Chama a biblioteca library(lpSolveAPI)
Como o problema possui somente duas variáveis vamos criá-lo com o nome de modelo.lp1 inicialmente sem nenhuma restrição:
#Define a criação de um modelo com 0 restrições e 2 variáveis modelo.lp1 <- make.lp(0, 2) #Dá o nome ao problema de programação linear name.lp(modelo.lp1, "Exemplo 1 - Aula de MMQD 1")Note que o comando make.lp recebe dois argumentos, o primeiro informa quantas restrições existem no problema e o segundo quantas variáveis. Inicialmente, colocamos zero restrições pois iremos adicioná-las dinamicamente nos próximos passos. Já o comando name.lp recebe dois argumentos, o primeiro argumento é o objeto modelo.lp1 que nós criamos e o segundo é o nome (ou descrição) do problema. Uma vez definida as principais características do problema de programação linear precisamos definir o domínio das variáveis e o tipo de problema (maximização ou minimização). Como nosso problema é um problema de maximação, escrevemos:
#Define as características do modelo lp.control(modelo.lp1, sense="max")Nesse comando, atribuímos ao modelo.lp1 o sentido de Maximização (isso é sense=''max'') para a função objetivo. Caso desejássemos Minimizar ao invés de maximizar escreveríamos sense=''min''. Como a função objetivo é escrita na forma $Minimize: Z=5x_{1} +6x_{2}$ devemos informar ao R que os coeficientes da função objetivo são, $5$ e $6$ respectivamente. Isso é feito por meio da seguinte sintaxe:
#Define a função objetivo set.objfn(modelo.lp1, c(5,6))Em seguida, como o problema pode assumir valores $x_{1}\geq 0,x_{2}\geq 0$ atribuímos os seguintes limites para as variáveis de decisão:
#Define os limites da região factível set.bounds(modelo.lp1, lower = c(0,0), upper = c(Inf, Inf)) #Tipo das variáveis de decisão set.type(modelo.lp1, c(1,2), type = c("real"))No comando set.bounds informamos que a primeira variável possui limite inferior (lower) igual a zero e limite superior (upper) igual a infinito (Inf). O mesmo fazemos para a segunda variável, nesse caso dizemos que o limite inferior (lower) é igual a zero e o limite superior (upper) é igual a infinito (Inf). A ordem aqui importa, ou seja, caso a primeira variável estivesse contida entre zero e infinito e a segunda variável estivesse contida entre os valores 1 e 4 deveríamos escrever set.bounds(modelo.lp1, lower = c(0,1), upper = c(Inf, 4)). O comando set.type define o tipo de variável para cada uma das variáveis de decisão. É possível escolher as seguintes opções:
- integer - A variável só pode assumir valores inteiros.
- binary - A variável só pode assumir valores binários, isso é, 1 ou zero.
- real - A variável pode assumir valores nos reais.
#Define os coeficientes da primeira restrição coef1 <- c(1,0) #Adiciona a restrição add.constraint(modelo.lp1, coef1, "<=", 6)Para a segunda restrição $2x_{2} \le 12\Rightarrow 0x_{1}+2x_{2} \le 12$, a adição é feita da seguinte forma:
#Define os coeficientes da segunda restrição coef2 <- c(0,2) #Adiciona a restrição add.constraint(modelo.lp1, coef2, "<=", 12)Finalmente, a última restrição $3x_{1}+2x_{2}\le 18$ é adicionada fazendo-se:
#Define os coeficientes da terceira restrição coef3 <- c(3,2) #Adiciona a restrição add.constraint(modelo.lp1, coef3, "<=", 18)Uma vez que o problema tenha sido configurado, todas as informações associadas a ele estão armazenadas no objeto modelo.lp1. Podemos visualizar essas informações fazendo:
#Mostra as informações do modelo print(modelo.lp1)Podemos também visualizar esse problema, uma vez que é um problema bidimensional, isso é, contém somente duas variáveis de decisão:
#Plota a região factível plot(modelo.lp1)Finalmente, para resolvê-lo, fazemos:
#Resolve o problema primal solve(modelo.lp1) resultado<-get.primal.solution(modelo.lp1) print(resultado)Entretanto, como os resultados não estão em um formato muito explicativo, vamos transformá-los em uma tabela (isso é um data.frame) e colocar títulos nas linhas e nas colunas:
#Transforma o resultado em uma tabela solucao<-as.data.frame(resultado) #Coloca os nomes nas colunas e nas linhas da tabela names(solucao)<-c("Valores") rownames(solucao)<-c("Função Objetivo", "Variável de folga 1","Variável de folga 2", "Variável de folga 3","Solução X1", "Solução X2") #Mostra os resultados com os nomes print(solucao)