Otimização Linear:
A Programação Linear é um dos pilares da Pesquisa Operacional.
Otimização Linear, ou Programação Linear (PL), é um método matemático para tomar a melhor decisão em um problema, maximizando ou minimizando um objetivo (como lucro ou custo) sujeito a um conjunto de restrições representadas por equações lineares. Ela é aplicada na pesquisa operacional para resolver situações complexas do mundo real, como planejamento de produção, definindo as quantidades ideais de produtos a fabricar para otimizar o lucro, ou criando misturas com o menor custo possível, respeitando a disponibilidade de componentes.
Função Objetivo é linear: min ou max da função linear abaixo.

Restrições tambem linear: Limitações de recursos (materiais, tempo, mão de obra), expressas como inequações (<= ou >=) ou equações (=) lineares.
s.a.: Ax >= b x>=0
Objetivo: Maximizar o lucro ou minimizar custos, expresso como uma função linear .

Elementos Principais:
- Função Objetivo:Uma função matemática (linear) que expressa o objetivo do problema, como maximizar o lucro ou minimizar o custo.
- Variáveis de Decisão:As variáveis que precisam ser determinadas para atingir o objetivo (ex: quantidade de cada produto a ser produzida).
- Restrições:Condições que limitam as variáveis de decisão, expressas como igualdades ou desigualdades lineares (ex: disponibilidade de ingredientes, demanda máxima ou mínima de um produto).
Objetivos exemplos:
- Ter unico otimizador global.
- Ter infinitos otimizadores globais
- Ser infactivel.
- Ser factivel, mas sem otimizador.
- em python podemos utilizar as bibliotecas linprog, mip, pub
1) Unica solução:

Obs: por padrao no linprog bounds = ( 0, None ), que são as restrições da “Unica solução”

2) Infinitas soluções:

Obs.: Aqui as restrições acima estão em A_eq e b_eq

3) Infactivel


4) Ilimitado


Alguns Exemplo de otimizador em python:
Exemplo:
Problema: Maximizar
Z=3x+4y
s.a. x+2y≤10, 2x+y≤12, x≥0, y≥0
# prog linear interpretação geometricaimport numpy as npimport matplotlib.pyplot as plt# grade para xx = np.linspace(0, 8, 400)# restrições (em forma y = ...)y1 = (10 - x) / 2 # x + 2y = 10 -> y = (10 - x)/2y2 = 12 - 2*x # 2x + y = 12 -> y = 12 - 2xplt.figure(figsize=(10, 8))# linhas das restriçõesplt.plot(x, y1, label=r'$x + 2y \leq 10$', linewidth=2)plt.plot(x, y2, label=r'$2x + y \leq 12$', linewidth=2)# não-negatividade (eixos)plt.axvline(0, linewidth=2) # x = 0plt.axhline(0, linewidth=2) # y = 0# região viável: abaixo das duas retas e acima de y=0y_feasible = np.minimum(y1, y2)y_feasible = np.maximum(y_feasible, 0)plt.fill_between(x, 0, y_feasible, alpha=0.25, label='Região viável')# vértices (calculados/confirmados)# Interseção das retas:# x + 2y = 10# 2x + y = 12 -> solução: x=14/3, y=8/3vertices = [ (0, 0), (0, 5), # quando x=0 na 1ª restrição: 2y=10 -> y=5 (e satisfaz a 2ª) (14/3, 8/3), # interseção (6, 0) # quando y=0 na 2ª restrição: 2x=12 -> x=6 (e satisfaz a 1ª)]# função objetivo (max)def Z(x, y): return 3*x + 4*y# plotar vértices e anotar valor da função objetivofor (vx, vy) in vertices: plt.plot(vx, vy, 'ko', markersize=8) plt.annotate( f'({vx:.2f}, {vy:.2f})\nZ={Z(vx, vy):.2f}', xy=(vx, vy), xytext=(vx + 0.25, vy + 0.25) )# destacar o ótimobest = max(vertices, key=lambda p: Z(p[0], p[1]))plt.plot(best[0], best[1], 'k*', markersize=14, label='Ótimo')plt.xlim(-0.5, 8)plt.ylim(-0.5, 8)plt.xlabel('x')plt.ylabel('y')plt.grid(alpha=0.3)plt.legend()plt.title(f'Visão Geométrica: ótimo no vértice ({best[0]:.2f}, {best[1]:.2f})')plt.show()print("Vértice ótimo:", best, "com Z =", Z(best[0], best[1]))
