Problema:


Uma empresa de construção civil deseja maximizar o lucro obtido com a venda de dois tipos de apartamentos: A e B. Cada apartamento do tipo A ocupa 80 m² e custa R$ 200.000,00 para ser construído. Cada apartamento do tipo B ocupa 100 m² e custa R$ 250.000,00 para ser construído. A empresa dispõe de um terreno de 4000 m² e um orçamento de R$ 10.000.000,00. Além disso, a demanda por apartamentos do tipo A é de no máximo 40 unidades e a demanda por apartamentos do Tipo B é de no máximo 30 unidades. O preço de venda de cada apartamento do Tipo A é de R$ 300.000,00 e o preço de venda de cada apartamento do tipo B é de R$ 400.000,00.



Tarefa 1: Descrição Matemática


Apresentar o modelo completo seguindo os passos apresentados na disciplina: critério de otimalidade, definir precisamente as variáveis de decisão, escrever matematicamente a função objetivo e as restrições.

Solução

Deseja-se otimizar o lucro sendo assim nossa função objetivo é:


Função Objetivo:

Max Z = x(300.000 - 200.000) + y(400.000 - 250.000)

Max Z = 100.000x + 150.000y

Sendo:

x= Quantidade de Apartamentos do Tipo A

y= Quantidade de Apartamentos do Tipo B


Restrições:

R1: 80x + 100y ≤ 4000;                                     A soma das áreas dos Aptos deve ser menor que 40000

R2: 200.000x + 250.000y ≤ 10.000.000 ;    O valor máximo de toda a construção é 10.000.000.

R3: x ≤ 40 ;                                                           A demanda maxima dos Aptos tipo A são 40 unidades.

R4: y ≤ 30;                                                            A demanda maxima dos Aptos tipo B são 30 unidades.

x, y ≥ 0;                                                                Os valores de x e y não podem ser nulos.

Dados=read.csv2("G:/Meu Drive/MESTRADO/Teoria da Decisao/dados_trabalho_final.csv")
View(Dados)
n = 2 #número de variáveis
m = 5 #número de restrições
coef.restricoes = as.matrix(Dados[1:m,2:(n+1)])
direcao.restricoes = Dados$direcao[1:m]
limites.restricoes = Dados$b[1:m]
func.objetivo = as.vector(t(Dados[(m+1),2:(n+1)]))
solucao.problema = 
  lpSolve::lp(direction = "max",
              objective.in = func.objetivo,  
              const.mat = coef.restricoes,
              const.dir = direcao.restricoes,
              const.rhs = limites.restricoes, 
              all.int=T)
# valor da função objetivo
solucao.problema$objval
## [1] 5700000
# Valores para as variáveis de decisão
solucao.problema$solution
## [1] 15 28

Isto é:

Deverão ser construidas 15 unidades de apartamentos do Tipo A e 28 unidades de apartamentos do Tipo B, para a obtenção do lucro máximo de R$5.700.000,00



Tarefa 2: Solução Gráfica


Aplicar o método gráfico para solucionar o problema

Solução

Figura 1 – Método Gráfico


Figura 2 – Método Gráfico (De forma mais aproximada)



Seguindo a direção do vetor gradiente temos como ponto máximo o Ponto B, porém como solução do problema não são aceitas respostas não inteiras, dessa forma o ponto máximo inteiro é (15, 28).

Aplicando este ponto na equação Z = 100.000x + 150.000y, temos Z = k = 5700000.


Animação 1 – Método Gráfico



Tarefa 3: Algoritmo Simplex


Aplicar o algoritmo simplex para solucionar o problema, apresentando todos os passos e todo o processo de cálculo.



Forma Simplex


Sendo a função:
Max Z = 100.000x + 150.000y


E suas restrições:

R1: 80x + 100y ≤ 4000;                                     A soma das áreas dos Aptos deve ser menor que 40000

R2: 200.000x + 250.000y ≤ 10.000.000 ;    O valor máximo de toda a construção é 10.000.000.

R3: x ≤ 40 ;                                                           A demanda maxima dos Aptos tipo A são 40 unidades.

R4: y ≤ 30;                                                            A demanda maxima dos Aptos tipo B são 30 unidades.

x, y ≥ 0;                                                                Os valores de x e y não podem ser nulos.



Devemos transformar o problema para a forma padrão do algoritmo simplex.

Max Z = 100000x1 + 150000x2 + 0x3 + 0x4 + 0x5 + 0x6


Transformando o algoritmo para a forma de minimização:

Min Z = -100000x1 - 150000x2 + 0x3 + 0x4 + 0x5 + 0x6



R1: 80x1 + 100x2 + x3 + 0x4 + 0x5 + 0x6 = 4000

R2: R1: 200000x1 + 250000x2 + 0x3 + x4 + 0x5 + 0x6 = 10000000

R3: x1 + 0x2 + 0x3 + 0x4 + x5 + 0x6 = 40

R4: 0x1 +x2 + 0x3 + 0x4 + 0x5 + x6 =30

x,y ≥ 0



Contadores Simplex

N1 = 1, N2 = 2

B1 = 3, B2 = 4, B3 = 5, B4 = 6

c = ( -100000, -150000, 0, 0, 0, 0 )

x = ( x1, x2, x3, x4, x5, x6)


b = ( 4000, 10000000, 40, 30)


Agora, realizaremos o particionamento:

cN = ( -100000, -150000) e cB = (0, 0, 0, 0)

xN = ( x1, x2) e xB = ( x3, x4, x5, x6)




Iteração 01




Portanto, não passou no teste de otimalidade!


Menor tamanho de passo é o e4 = 30. Portanto B4 = 6 sairá da base

Novos Contadores Simplex

N1 = 1, N2 = 6

B1 = 3, B2 = 4, B3 = 5, B4 = 2



Iteração 02





cN = ( -100000, -150000) e cB = (0, 0, 0, 0)

xN = ( x1, x2) e xB = ( x3, x4, x5, x6)









   Portanto, não passou no teste de otimalidade!





Menor tamanho de passo é o e2 = 1,25. Portanto B2 = 4 sairá da base

Novos Contadores Simplex

N1 = 4, N2 = 6

B1 = 3, B2 = 1, B3 = 5, B4 = 2


Iteração 03




cN = ( 0, 0) e cB = ( 0, -100000, 0, -150000)

xN = ( x4, x6) e xB = ( x3, x1, x5, x2)






Portanto, passou no teste de otimalidade!

Logo, a solução (x1=12,5; x2=30) é viável. É ótima?

Como 12,5 não é um número inteiro, ainda não é a solução que buscamos.

Avaliando a solução ótima encontrada nos itens anteriores (1 e 2), através do R e da solução gráfica, verificamos que a solução obtida pelo método simplex é uma solução viável e atende os critérios de parada do algoritmo.

No entanto, não se trata da solução ótima (x1 = 15; x2 = 28), encontrada a partir dos métodos anteriores.


Tarefa 4: Estratégia do Algoritmo


Utilizar as soluções de cada iteração do algoritmo simplex mostrando no gráfico a estratégia do algoritmo, ou seja, de que ponto partiu, para onde foi até chegar ou não na solução ótima.



Figura 3 – Estratégia do Algoritmo Simplex



O processo de cálculo do algoritmo simplex se iniciou pela primeira iteração através da solução corrente (x1 = 0; x2 = 0) no ponto A (0; 0) do gráfico acima.

Como a solução não atendeu os critérios de otimalidade, o passo seguinte foi realizar o processo de troca de base dos contadores (seta 1), onde encontrou-se o novo possível vértice viável para a iteração 2 (x1 = 0; x2 = 30), representado pelo ponto C (0; 30) do gráfico.

Do mesmo modo da primeira iteração, o ponto também não atendeu os critérios de otimalidade, levando a outro processo de troca de base dos contadores (seta 2), ou seja, uma terceira iteração. Para essa iteração 3, encontrou-se o novo possível vértice viável (x1 = 12,5; x2 = 30), representado pelo ponto B (12,5 ; 30), o qual atendeu os critérios de parada do algoritmo no teste de otimalidade (C’Nj ≥ 0).

Entretanto, como já constatado no item anterior e conforme pode ser visualizado no gráfico, a solução ótima, ou seja, a que proporciona o maior lucro para a empresa, é representada pelo ponto (15; 28) do gráfico, indicado como “RESPOSTA”.



Tarefa 5: Análise de Sensibilidade



Segundo a FÁVERO(2013), análise de sensibilidade do modelo em função de alterações em um dos coeficientes da função objetivo, sem alterar a solução básica original do modelo (a solução básica permanece ótima). Como um dos coeficientes da função objetivo é alterado, o valor da função objetivo z também muda.

Nesta análise de sensibilidade fixamos o lucro recebido pelo Apartamento do tipo A e variamos o Apartamento do tipo B. Observe os resultados:

options(scipen = 999)
library(lpSolve)

dados <- read.csv2("G:/Meu Drive/MESTRADO/Teoria da Decisao/dados_trabalho_final.csv")

# Função para resolver o problema com uma função objetivo específica
resolver_problema <- function(func_objetivo) {
  solucao_problema <- lpSolve::lp(direction = "max",
                                  objective.in = func_objetivo,  
                                  const.mat = coef.restricoes,
                                  const.dir = direcao.restricoes,
                                  const.rhs = limites.restricoes, 
                                  all.int = T)
  return(solucao_problema$objval)
}

# Definindo o número de funções objetivo (5 nesse caso)
num_fos <- 5

# Criando uma tabela para armazenar os resultados
resultados <- matrix(0, nrow = num_fos, ncol = 4)
colnames(resultados) <- c("Funcao_Objetivo", "Coeficiente_de_x", "Coeficiente_de_y", "Lucro_Maximo")

# Definindo as variações da função objetivo
funcoes_objetivo <- list(
  c(100000, 160000),
  c(100000, 155000),
  c(100000, 150000),
  c(100000, 145000),
  c(100000, 140000)
)

# Resolvendo o problema para cada função objetivo
for (i in 1:num_fos) {
  func_objetivo <- as.vector(t(funcoes_objetivo[[i]]))
  lucro_maximo <- resolver_problema(func_objetivo)
  coef_x <- funcoes_objetivo[[i]][1]
  coef_y <- funcoes_objetivo[[i]][2]
  resultados[i, ] <- c(paste("FO", i), coef_x, coef_y, lucro_maximo)
}

# Exibindo a tabela de resultados
print(resultados)
##      Funcao_Objetivo Coeficiente_de_x Coeficiente_de_y Lucro_Maximo
## [1,] "FO 1"          "100000"         "160000"         "5980000"   
## [2,] "FO 2"          "100000"         "155000"         "5840000"   
## [3,] "FO 3"          "100000"         "150000"         "5700000"   
## [4,] "FO 4"          "100000"         "145000"         "5560000"   
## [5,] "FO 5"          "100000"         "140000"         "5420000"


Como esperado o lucro máximo aumenta se aumentamos o lucro do Apartamento do tipo B, e reduz no caso contrário.

Referências


ALCOFORADO, L. F, Aula 2: Modelagem, 18/04/2023. Apresentação de Power Point.

ALCOFORADO, L. F, Aula 3: Modelagem 25/04/2023. Apresentação de Power Point.

ALCOFORADO, L. F, Aula 4: Modelagem – Uso de software 02/05/2023. Apresentação de Power Point.

ALCOFORADO, L. F, Aula 5: Modelagem – Uso de software 09/05/2023. Apresentação de Power Point.

ALCOFORADO, L. F, Aula 7: Solução Gráfica 23/05/2023. Apresentação de Power Point.

ALCOFORADO, L. F, Aula 8: Método Simplex 30/05/2023. Apresentação de Power Point.

ALCOFORADO, L. F, Aula 9: Método Simplex 06/06/2023. Apresentação de Power Point.

FÁVERO, Luiz Paulo; BELFIORE, Patrícia. Pesquisa operacional para os cursos de engenharia. Rio de Janeiro: Elsevier, 2013.