Definição
● A Programação Linear Inteira (PLI) é um caso
particular da Programação Linear (PL)
● As variáveis (ou pelo menos uma parte delas)
devem assumir valores inteiros
● Também conhecida com Programação Inteira e
Aplicações
● As aplicações decorrem quando variáveis com
valores reais não possuem um significado razoável
● Ex: Se x representa o número de funcionários a
serem contratados o valor 4.16 não representa um valor praticável. Decisões do tipo sim ou
Características
● Espaço de busca discreto
● Em muitos casos práticos o conjunto de
soluções é finito
● Difícil tratamento: NP-Difícil ou NP-Completo
Exemplo
● Seja um conjunto de 50 cidades
● Um indivíduo precisa passar por todas elas
vendendo produtos e depois retornar a cidade origem
● O objetivo é encontrar a rota que minimiza a
distância percorrida
● Este é o Problema do Caixeiro Viajante ou
Enumeração
● Enumerar todas as soluções e encontrar a
melhor é possível, mas inviável na maioria dos casos
● Alguns problemas não possuem um poliedro
bem formado, com um lado ilimitado, logo o número de soluções é infinito
● Em alguns casos exitem soluções demais para
Enumeração
● Existem (n-1)!/2 soluções ● 49! =
6082818640342675608722521633212953768875528313 79210240000000000 ~ 6X1062
● Os computadores modernos realizam 4x109 instruções por
segundo aproximadamente
● Supondo que uma solução tivesse sua qualidade avaliada
em uma única instrução (o que não é verdade)
● São necessários aproximadamente 2X1045 anos para
Exemplo
● Uma determinada empresa produz dois
produtos, x1 e x2 e quer determinar a
quantidade de produtos a serem feitos de forma a maximizar o seu lucro
● O produto x1 dá uma unidade de lucro, o
Exemplo
● Ambos os produtos requerem dois tipos de
matéria-prima
● O produto x1 consume uma unidade de cada
matéria-prima, já o produto x2 consome 20 unidades da primeira matéria-prima e uma unidade da segunda matéria-prima
Exemplo
● A produção está limitada ao estoque de cada
matéria-prima que é de 50 unidades da primeira e 20 unidades da segunda
Exemplo
max x1+19x2 s. a. x1+20x2≤50 x1+ x2≤20 x1, x2∈ℤ x1, x2≥0Exemplo
max x1+19x2 s. a. x1+20x2≤50 x1+ x2≤20 x1, x2∈ℤ x1, x2≥0 Lucro Matéria-prima 1 Matéria-prima 2 integralidade Não negatividadeSimplex
● O Algoritmo Simplex pode ser usado como
aproximação
● Ignora-se as restrições de integralidade e
resolve-se o problema como se ele fosse contínuo
Exemplo
max x1+19x2 s. a. x1+20x2≤50 x1+ x2≤20 x1, x2≥0Removendo a restrição de integralidade temos uma solução linear
x1=18,42 x2=1,58
Exemplo
Analisando as soluções Inteiras próximas a solução ótima temos
X1=18 x2=1 → fo(x) = 37
X1=19 x2=1 é a solução ótima? X1=18 x2=2 → inviável
X1=19 x2=1 → fo(x) = 38 X1=19 x2=2 → inviável
Exemplo
● A solução ótima deste problema é x1=10, x2=2
● A função objetivo neste caso é 48, longe do 38
da solução anterior
● A solução pode ser obtida através do algoritmo
Branch-and-Bound Inicialização
● Seja o conjunto L o conjunto de problemas a ser
resolvido. Seja z o valor da melhor solução inteira encontrado no processo de solução
● No início L é um conjunto vazio e z indeterminado ● Retira-se as restrições de integralidade do
problema original
● Insere-se o problema contínuo em L ● Enquanto L tiver elementos faça:
Branch-and-Bound
● Retira-se um problema de L, referenciado por p
Branch-and-Bound
● Retira-se um problema de L, referenciado por p
● Caso a solução de p seja inteira atualiza-se o
valor de z caso necessário
● Caso a solução de p seja inviável p é
Branch-and-Bound
Branch-and-Bound
● Caso a solução seja contínua e pior que z, p
deve ser descartado
● Caso a solução seja contínua e melhor que z,
deve-se escolher uma variável qualquer do problema, com valor contínuo, e realizar a operação de ramificação
Branch-and-Bound
● Seja s a solução de p. Escolhe-se uma variável
fracionária qualquer referenciada por y. Seja sy o valor da variável y em s.
● Na ramificação são criados dois novos
problemas: p’ e p’’
● Em p’ é inserida a restrição y >= teto(s
y)
● Em P’’ é inserida a restrição y <= piso(s
y)
Branch-and-Bound
X1=? X2=? Z=? Descartado Em análiseBranch-and-Bound
X1=18,42 X2=1,58 fo(X)=48,42 Z=? DescartadoBranch-and-Bound
● No exemplo, podemos tomar a variável
x1=18,42
● Em p’ acrescenta-se a restrição x1>=19
Branch-and-Bound
X1=18,42 X2=1,58 fo(X)=48,42 X1=? X2=? fo(X)=? x1>=19 X1=? X2=? fo(X)=? x1<=18 Z=? DescartadoBranch-and-Bound
● O algoritmo realiza as operações de
ramificação e descarte enquanto houver problemas no conjunto L
● Melhor caso: a cada passo um problema é
descartado
● Pior caso: a cada passo um problema é
Branch-and-Bound
X1=18,42X2=1,58 fo(X)=48,42 Z=?
Branch-and-Bound
X1=18,42 X2=1,58 fo(X)=48,42 X1=? X2=? fo(X)=? x1>=19 X1=? X2=? fo(X)=? x1<=18 Z=? Descartado Em análiseBranch-and-Bound
X1=18,42 X2=1,58 fo(X)=48,42 X1=19 X2=1 fo(X)=38 x1>=19 X1=? X2=? fo(X)=? x1<=18 Z=? DescartadoBranch-and-Bound
X1=18,42 X2=1,58 fo(X)=48,42 X1=19 X2=1 fo(X)=38 x1>=19 X1=? X2=? fo(X)=? x1<=18 Z=? Descartado Em análise Solução InteiraBranch-and-Bound
X1=18,42 X2=1,58 fo(X)=48,42 X1=19 X2=1 fo(X)=38 x1>=19 X1=? X2=? fo(X)=? x1<=18 Z=38 Descartado Solução InteiraBranch-and-Bound
X1=18,42 X2=1,58 fo(X)=48,42 X1=19 X2=1 fo(X)=38 x1>=19 X1=? X2=? fo(X)=? x1<=18 Z=38 Descartado Em análiseBranch-and-Bound
X1=18,42 X2=1,58 fo(X)=48,42 X1=19 X2=1 fo(X)=38 x1>=19 X1=18 X2=1,6 fo(X)=48,4 x1<=18 Z=38 DescartadoBranch-and-Bound
X1=18,42 X2=1,58 fo(X)=48,42 X1=19 X2=1 fo(X)=38 x1>=19 X1=18 X2=1,6 fo(X)=48,4 x1<=18 X1=? X2=? fo(X)=? x2>=2 X1=? X2=? fo(X)=? x2<=1 Z=38 Descartado Em análiseBranch-and-Bound
X1=18,42 X2=1,58 fo(X)=48,42 X1=19 X2=1 fo(X)=38 x1>=19 X1=18 X2=1,6 fo(X)=48,4 x1<=18 X1=10 X2=2 fo(X)=48 x2>=2 X1=? X2=? fo(X)=? x2<=1 Z=38 Descartado Solução InteiraBranch-and-Bound
X1=18,42 X2=1,58 fo(X)=48,42 X1=19 X2=1 fo(X)=38 x1>=19 X1=18 X2=1,6 fo(X)=48,4 x1<=18 X1=10 X2=2 fo(X)=48 x2>=2 X1=? X2=? fo(X)=? x2<=1 Z=48 Descartado Em análiseBranch-and-Bound
X1=18,42 X2=1,58 fo(X)=48,42 X1=19 X2=1 fo(X)=38 x1>=19 X1=18 X2=1,6 fo(X)=48,4 x1<=18 X1=10 X2=2 fo(X)=48 x2>=2 X1=18 X2=1 fo(X)=37 x2<=1 Z=48 DescartadoBranch-and-Bound
X1=18,42 X2=1,58 fo(X)=48,42 X1=19 X2=1 fo(X)=38 x1>=19 X1=18 X2=1,6 fo(X)=48,4 x1<=18 X1=10 X2=2 fo(X)=48 x2>=2 X1=18 X2=1 fo(X)=37 x2<=1 Z=48 Descartado Em análise Solução InteiraBranch-and-Bound
X1=18,42 X2=1,58 fo(X)=48,42 X1=19 X2=1 fo(X)=38 x1>=19 X1=18 X2=1,6 fo(X)=48,4 x1<=18 X1=10 X2=2 fo(X)=48 x2>=2 X1=18 X2=1 fo(X)=37 x2<=1 Z=48 DescartadoBranch-and-Bound
● Seja L um Conjunto de subproblemas
● Seja fo(s) a função objetivo de uma solução s
● Seja s* a melhor solução inteira encontrada ao
longo da busca
Branch-and-Bound
Algoritmo branchAndBound( PPL p ) Início
Seja s a solução de p Se (s for inteira) Então Retorne s
Branch-and-Bound
L = {}, z = null, s*=null
Seja x uma das variáveis fracionarias de s PPL p1=p, p2=p Adicione em p1 a restrição Adicione em p2 a restrição Inserir p1 em L Inserir p2 em L x≤ piso(sx) x≥teto(sx)
Branch-and-Bound
Enquanto (L não estiver vazia) Faça Remova um elemento r de L
Seja sr a solução de r
Se (Inviável(sr) | z != null & fo(sr) pior que z) Então Descarte r
Branch-and-Bound
Se (sr for inteira ) então
Se(z==null | fo(sr) melhor que z ) Então z=fo(sr)
s* = sr Fim Se
Branch-and-Bound
PPL paux1=r, paux2=r
Seja x’ uma variável fracionária de sr Adicione em paux1 a restrição
Adicione em paux2 a restrição Inserir paux1 em L
Inserir paux2 em L
Fim Se // solução de r é fracionária
x '≤ piso(srx ') x '≥teto(srx ')
Branch-and-Bound
retorne s*
Fim Se //solução Fracionária Fim
Exemplo
max x1+19x2 s. a. x1+20x2≤50 x1+ x2≤20 x1, x2∈ℤ x1, x2≥0Graficamente
x1 x2
5 u.m. x1
Graficamente
x1 x2 5 u.m. x1 X1 + x2 <=20Graficamente
x1 x2 5 u.m. x1 X1 + x2 <=20 X1+20x2 <=50Graficamente
x1 x2 2 u.m. x1 X1 + x2 <=20 X1+20x2 <=50Graficamente
x1 x2 2 u.m. x1 X1 + x2 <=20 X1+20x2 <=50Graficamente
x1 x2 2 u.m. x1 X1 + x2 <=20 X1+20x2 <=50Graficamente
x1 x2 2 u.m. x1 X1 + x2 <=20 X1 >= 19 X1+20x2 <=50Graficamente
x1 x2 2 u.m. x1 X1 + x2 <=20 X1 >= 19 X1+20x2 <=50Graficamente
x1 x2 2 u.m. x1 X1 + x2 <=20 X1 <=18 X1+20x2 <=50Graficamente
x1 x2 2 u.m. x1 X1 + x2 <=20 X1 <=18 X1+20x2 <=50Graficamente
x1 x2 2 u.m. x1 X1 + x2 <=20 X1+20x2 <=50Graficamente
x1 x2 2 u.m. x1 X1 + x2 <=20 X1+20x2 <=50Graficamente
x1 x2 2 u.m. x1 X1 + x2 <=20 X1 <=18 X1+20x2 <=50 x2 <=1Graficamente
x1 x2 2 u.m. x1 X1 + x2 <=20 X1+20x2 <=50 X1 <=18 x2 >=2Exercício 1 -Implementando no IBM
OPLIDE
● Crie um novo projeto
● Ao criar o projeto marque para adicionar as
IBM OPL
dvar int+ x1; dvar int+ x2; maximize 1*x1+19*x2; subject to{ 1*x1+ 20*x2 <=50; x1 + x2 <=20; }Exercício 2 – Uma Formulação
Matemática mais elegante
max
∑
i∈ produtos producaoilucroi s. a.∑
i∈ produtosproducaoiconsumoji≤estoquej, ∀ j∈materiais
Criando um modelo mais elegante
{string} produtos={"x1","x2"}; {string} materiais={"m1","m2"}; float lucro[produtos] = [1, 19]; float consumo[materiais][produtos]=[[1,20],[1,1]]; float estoque[materiais]=[50,20];dvar int+ producao[produtos]; maximize
sum (i in produtos)lucro[i]*producao[i]; subject to{
forall(j in materiais)
sum (i in produtos) consumo[j][i]*producao[i] <=estoque[j]; }
Exercício 3 -Separando o modelo
dos dados
● Crie um arquivo de dados
● Mande incluir na configuração que você está utilizando ● Insira os dados no arquivo (o formato do arquivo é
diferente do formato da OPL)
● Generalize o modelo usando o operador reticencias
Dados
produtos = { "x1" "x2" }; materiais = { "m1" "m2" }; consumo = [ [1 20] [1 1] ]; lucro = [1 19]; estoque = [50 20];Modelo Geral
{string} produtos=...; {string} materiais=...; float lucro[produtos] =...; float consumo[materiais][produtos]=...; float estoque[materiais]=...;dvar int+ producao[produtos]; maximize
sum (i in produtos)lucro[i]*producao[i]; subject to{
forall(j in materiais)
sum (i in produtos) consumo[j][i]*producao[i] <=estoque[j]; }
Exercício 4- Usando a interface de
texto
● Crie um arquivo de texto com extensão lp
● Cloque neste arquivo as equações no formato
lp (amplamente difundido). Use um programa para gerar o arquivo se necessário
● Na interface de comandos invoque o cplex
● Use o comando read para ler o arquivo
● Use o comando optimize para resolver o
Arquivo LP
\ENCODING=ISO-8859-1\Problem name: modeloProducao Maximize obj: x_1 + 19 x_2 Subject To c1: x_1 + 20 x_2 <= 50 c2: x_1 + x_2 <= 20 Bounds x_1 >= 0 x_2 >= 0 Generals x_1 x_2 End
Exercício 5 – Problema da Dieta
Inteiro
● Possivelmente o primeiro problema de otimização tratado como ppl ● O corpo humano tem uma série de requisitos mínimos de vitaminas
e sais minerais que precisam ser ingeridos por dia
● Exitem alguns alimentos a disposição de um “cheff”, cada um deles
com uma determinada quantidade de cada nutrientes conforme a tabela a seguir
● Cada porção de alimento possui um preço(também incluso na
tabela)
● O objetivo é montar uma refeição que atenda as exigências
mínimas de cada nutriente (exposta a seguir) usando a menor quantidade de dinheiro possível
Exigências
● Vitaminas: mínimo 500 mg
● Calorias: mínimo 2000 kcal
Alimentos/nutrientes
Alimentos/
nutrientes Calorias ferro vitaminas preço
Arroz 128 0,1 0 0,1
Feijão 76 1,3 0 0,5
Cerveja 40 0 40 1
Cenoura 29 0,1 20 0,5