Created
December 29, 2020 02:21
-
-
Save anselmobattisti/972b1ac1411041c8a5d33820334a53a2 to your computer and use it in GitHub Desktop.
Implementação do problema das múltiplas mochilas em Python.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from mip import * | |
import random | |
# Constantes | |
RANDOM_SEED = 1 | |
NUM_PRODUTOS = 10 | |
NUM_MOCHILAS = 2 | |
# Variável que armazena os Dados | |
produtos = {} | |
mochilas = {} | |
gerar_produtos(produtos) | |
gerar_mochilas(mochilas) | |
# Todos os produtos | |
imprimir_produtos(produtos) | |
# Todas as mochilas | |
imprimir_mochilas(mochilas) | |
# Modelo | |
modelo = Model(sense=MAXIMIZE) | |
# Variáveis de decisão | |
carga = {} # qual produto será colcoado em cada mochila | |
for m in mochilas: | |
for p in produtos: | |
carga[(m, p)] = modelo.add_var(var_type=BINARY) | |
# Restrições | |
# a) O mesmo produto não pode ser colocado nas duas mochilas | |
for p in produtos: | |
modelo += xsum(carga[(m, p)] for m in mochilas) <= 1 | |
# b) A soma dos pesos dos produtos alocados em uma mochila não devem ser maior do que a carga máxima suportada pela mochila | |
for m in mochilas: | |
modelo += xsum(carga[(m, p)] * produtos[p]['peso'] for p in produtos) <= mochilas[m]['carga_maxima'] | |
# Função Objetivo | |
modelo.objective = maximize( | |
xsum(carga[(m, p)] * produtos[p]['valor'] | |
for m in mochilas | |
for p in produtos | |
if (m, p) in carga | |
) | |
) | |
modelo.optimize() | |
# Resultado | |
print("\n=====") | |
print("Valor Total em Todas as Mochilas {}".format(modelo.objective_values)) | |
print("=====") | |
for m in mochilas: | |
print("\nCarga da Mochila {} com capacidade de {}g".format(m, mochilas[m]['carga_maxima'])) | |
valor_total = 0 | |
carga_total = 0 | |
for p in produtos: | |
if (carga[(m, p)].x == 1): | |
valor_total += produtos[p]['valor'] | |
carga_total += produtos[p]['peso'] | |
print("{} \tR$ {},00 \t{}g".format(p, produtos[p]['valor'], produtos[p]['peso'])) | |
print("-\nValor Total: R$ {},00 \nCarga Total: {}g\nCapacidade Ociosa: {}g".format(valor_total, carga_total, (mochilas[m]['carga_maxima']-carga_total))) | |
# Gerar produtos com peso e valor aleatórios | |
def gerar_produtos(prod): | |
random.seed(RANDOM_SEED) | |
for i in range(NUM_PRODUTOS): | |
cod = 'p_{}'.format(i) | |
valor = random.choice(range(1,10)) # Valor em reais | |
peso = random.choice(range(100,999)) # Valor em reais | |
prod[cod] = { | |
'valor': valor, | |
'peso': peso | |
} | |
# Imprimir os produtos | |
def imprimir_produtos(prod): | |
print("PRODUTOS") | |
print("Cód \tValor \t\tPeso") | |
for p in prod: | |
print("{}\tR$ {},00 \t{}g".format(p, prod[p]['valor'], prod[p]['peso'])) | |
# Gera mochilas com pesos aleatórias | |
def gerar_mochilas(moc): | |
random.seed(RANDOM_SEED) | |
for i in range(NUM_MOCHILAS): | |
cod = 'm_{}'.format(i) | |
carga_maxima = random.choice(range(500,2000)) # Carga máxima em gramas | |
moc[cod] = { | |
'carga_maxima': carga_maxima | |
} | |
# Imprime as mochilas | |
def imprimir_mochilas(moc): | |
print("\nMOCHILAS") | |
print("Cód \tCarga Máxima") | |
for m in moc: | |
print("{} \t{}g".format(m, moc[m]['carga_maxima'])) |
boa tarde Prof, assistir sua aula no youtube, utilizei seu script, e inclui alguns ajustes, e gerei um grafico.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
#=========================================================================#
ATIVAR OS PACOTES
from mip import *
import random
import pandas as pd
import matplotlib.pyplot as plt
from tabulate import tabulate
#=========================================================================#
#=========================================================================#
CONSTANTES
RANDOM_SEED = 120
NUM_PRODUTOS = 12
NUM_MOCHILAS = 5
#=========================================================================#
#=========================================================================#
Inicializa o gerador aleatório
random.seed(RANDOM_SEED)
#=========================================================================#
#=========================================================================#
GERAR PRODUTOS E MOCHILAS
produtos = {
f'p_{i}': {'valor': random.randint(10, 150), # valores(R$)
'peso': random.randint(100, 250)} # valores(gramas)
for i in range(NUM_PRODUTOS)
}
#-------------------------------------------------------------------------#
mochilas = {
f'm_{i}': {'carga_maxima': random.randint(1500, 5000)} # valor(gramas)
for i in range(NUM_MOCHILAS)
}
#=========================================================================#
#=========================================================================#
FUNÇÃO PARA IMPRIMIR TABELA FORMATADA
def imprimir_tabela(titulo, dados):
print("\n" + "=" * 50)
print(f"{titulo}")
print("=" * 50)
df = pd.DataFrame.from_dict(dados, orient='index')
print(tabulate(df, headers='keys', tablefmt='fancy_grid'))
print("=" * 50)
#=========================================================================#
#=========================================================================#
FUNÇÃO OBJETIVO (MODELO MATEMÁTICO)
modelo = Model(sense=MAXIMIZE)
#=========================================================================#
VARIÁVEIS DE DECISÃO
carga = {(m, p): modelo.add_var(var_type=BINARY)
for m in mochilas
for p in produtos}
#=========================================================================#
RESTRIÇÕES
Mesmo Produto Não Pode Ser Colocado em DUAS Mochilas ao Mesmo Tempo
for p in produtos:
modelo += xsum(carga[m, p] for m in mochilas) <= 1
Soma Peso dos Produtos NÃO deve ser Maior Carga Máxima
for m in mochilas:
modelo += xsum(carga[m, p] * produtos[p]['peso']
for p in produtos) <= mochilas[m]['carga_maxima']
#=========================================================================#
#=========================================================================#
FUNÇÃO OBJETIVO
modelo.objective = maximize(
xsum(carga[m, p] * produtos[p]['valor']
for m in mochilas
for p in produtos)
)
modelo.optimize()
#=========================================================================#
#=========================================================================#
#----------------------------- RESULTADOS --------------------------------#
Imprimir Produtos/Mochilas de forma Organizada
imprimir_tabela("PRODUTOS DISPONÍVEIS", produtos)
imprimir_tabela("MOCHILAS DISPONÍVEIS", mochilas)
print("\n" + "="*50)
print(f"VALOR TOTAL DAS MOCHILAS: R$ {modelo.objective_value:.2f}")
print("="*50)
Criar listas para o gráfico
nomes_mochilas = []
cargas_totais = []
capacidades = []
data_mochilas = []
#=========================================================================#
#=========================================================================#
Alocação dos Produtos nas Mochilas
print("\nDISTRIBUIÇÃO DOS PRODUTOS NAS MOCHILAS:")
for m in mochilas:
produtos_mochila = [
(p, produtos[p]['valor'], produtos[p]['peso'])
for p in produtos if carga[m, p].x == 1
]
carga_total = sum(peso for _, _, peso in produtos_mochila)
valor_total = sum(valor for _, valor, _ in produtos_mochila)
#=========================================================================#
#=========================================================================#
TABELA DE RESUMO DAS MOCHILAS
df_resumo = pd.DataFrame(data_mochilas,
columns=['Mochila',
'Valor Total (R$)',
'Carga Total (g)',
'Espaço Livre (g)'])
print("\n📊 RESUMO DAS MOCHILAS")
print(tabulate(df_resumo, headers='keys',
tablefmt='fancy_grid'))
print("="*50)
#=========================================================================#
#=========================================================================#
📊 GRÁFICO DE BARRAS EMPILHADAS (CARGA POR MOCHILA)
plt.figure(figsize=(10, 6))
plt.bar(nomes_mochilas, capacidades, color='gray',
alpha=0.5, label='Capacidade Total')
plt.bar(nomes_mochilas, cargas_totais, color='blue',
alpha=0.8, label='Carga Utilizada')
Adicionar Valores nas Barras
for i, v in enumerate(cargas_totais):
plt.text(i, v + 50, f"{v}g", ha='center', fontsize=12, fontweight='bold')
plt.xlabel("Mochilas", fontsize=14)
plt.ylabel("Peso (g)", fontsize=14)
plt.title("Distribuição de Carga nas Mochilas", fontsize=16, fontweight='bold')
plt.legend()
plt.grid(axis='y', linestyle='--', alpha=0.7)
plt.show()
#=========================================================================#