feat: adiciona Modelo 3 minimizando aeronaves com a consideração do tempo de solo (TAT) de 40 minutos
This commit is contained in:
119
create_nb.py
119
create_nb.py
@@ -449,6 +449,125 @@ print("\\n== QUADRO DE HORÁRIOS DIÁRIOS ==")
|
||||
print(tabulate(tabela_horarios, headers=["Aeronave", "Origem", "Destino", "Tipo", "Partida", "Chegada", "Duração"], tablefmt="github"))
|
||||
"""))
|
||||
|
||||
# Cell 13: Markdown Modelo 3
|
||||
cells.append(nbf.v4.new_markdown_cell("""## 6. Modelo 3: Minimização de Aeronaves com TAT (Turnaround Time)
|
||||
Nesta variação do Modelo 2, adicionamos uma restrição crítica da vida real: o Tempo de Solo ou **Turnaround Time (TAT)**.
|
||||
Considerações:
|
||||
- TAT estipulado: 40 minutos (0.66 horas) por cada voo (tempo necessário para desembarque, reabastecimento, verificações e embarque).
|
||||
- O tempo total de dedicação de uma aeronave por ciclo passa a ser a soma do seu Tempo de Voo + 40 minutos de TAT no aeroporto de destino.
|
||||
"""))
|
||||
|
||||
# Cell 14: Code Modelo 3
|
||||
cells.append(nbf.v4.new_code_cell("""# 3. Modelagem Matemática Modelo 3 (Pulp) com TAT
|
||||
prob3 = pulp.LpProblem("Minimizar_Aeronaves_TAT", pulp.LpMinimize)
|
||||
|
||||
# Variáveis
|
||||
Y3 = pulp.LpVariable.dicts("Y3", [(o, d) for o in aeroportos_malha for d in aeroportos_malha], lowBound=0, cat='Integer')
|
||||
N3 = pulp.LpVariable("N3", lowBound=0, cat='Integer')
|
||||
|
||||
TAT_horas = 40.0 / 60.0
|
||||
|
||||
# Função Objetivo
|
||||
prob3 += N3 + 0.0001 * pulp.lpSum([Y3[(i, j)] * tempos_voo[(i, j)] for i in aeroportos_malha for j in aeroportos_malha])
|
||||
|
||||
# Restrição de fluxo
|
||||
for no in aeroportos_malha:
|
||||
chegadas = pulp.lpSum([D[(i, no)] + Y3[(i, no)] for i in aeroportos_malha])
|
||||
partidas = pulp.lpSum([D[(no, j)] + Y3[(no, j)] for j in aeroportos_malha])
|
||||
prob3 += chegadas == partidas
|
||||
|
||||
# Restrição de tempo com TAT
|
||||
# Cada voo (D ou Y) consome tempo de voo + TAT
|
||||
tempo_total_operacional = pulp.lpSum([(D[(i, j)] + Y3[(i, j)]) * (tempos_voo[(i, j)] + TAT_horas) for i in aeroportos_malha for j in aeroportos_malha])
|
||||
prob3 += tempo_total_operacional <= N3 * 24.0
|
||||
|
||||
# Solução
|
||||
prob3.solve(pulp.PULP_CBC_CMD(msg=False))
|
||||
|
||||
print("\\n== RESULTADO DO MODELO 3 (COM 40 MIN DE SOLO) ==")
|
||||
print(f"Status: {pulp.LpStatus[prob3.status]}")
|
||||
print(f"Número mínimo absoluto de aeronaves C-97 necessárias: {int(N3.varValue)}")
|
||||
|
||||
tempo_voo_puro = sum([(D[(i, j)] + Y3[(i, j)].varValue) * tempos_voo[(i, j)] for i in aeroportos_malha for j in aeroportos_malha])
|
||||
total_voos_realizados = sum([(D[(i, j)] + Y3[(i, j)].varValue) for i in aeroportos_malha for j in aeroportos_malha])
|
||||
tempo_solo_total = total_voos_realizados * TAT_horas
|
||||
|
||||
print(f"Tempo total de voo puro: {tempo_voo_puro:.2f} horas")
|
||||
print(f"Tempo total gasto em solo (TAT): {tempo_solo_total:.2f} horas")
|
||||
print(f"Tempo total operacional comprometido: {tempo_voo_puro + tempo_solo_total:.2f} horas")
|
||||
if N3.varValue > 0:
|
||||
print(f"Taxa de ocupação da frota (Tempo Operacional / Tempo Disponível): {((tempo_voo_puro + tempo_solo_total) / (N3.varValue * 24)) * 100:.1f}%\\n")
|
||||
|
||||
# GERAR TABELA DE HORÁRIOS COM TABULATE E DATETIME
|
||||
voos_para_fazer3 = []
|
||||
D_copy3 = {k: v for k, v in D.items()}
|
||||
|
||||
for i in aeroportos_malha:
|
||||
for j in aeroportos_malha:
|
||||
total_voos3 = D[(i, j)] + int(Y3[(i, j)].varValue)
|
||||
for _ in range(total_voos3):
|
||||
if D_copy3[(i, j)] > 0:
|
||||
tipo = 'Passageiro'
|
||||
D_copy3[(i, j)] -= 1
|
||||
else:
|
||||
tipo = 'Vazio (Reposicionamento)'
|
||||
voos_para_fazer3.append({'origem': i, 'destino': j, 'tipo': tipo, 'tempo': tempos_voo[(i, j)]})
|
||||
|
||||
tabela_horarios3 = []
|
||||
aeronave_id3 = 1
|
||||
|
||||
while voos_para_fazer3:
|
||||
voo_atual = voos_para_fazer3.pop(0)
|
||||
hora_atual = datetime.datetime(2025, 1, 1, 0, 0, 0)
|
||||
|
||||
tempo_delta = datetime.timedelta(hours=voo_atual['tempo'])
|
||||
hora_chegada = hora_atual + tempo_delta
|
||||
|
||||
tabela_horarios3.append([
|
||||
f"Aeronave {aeronave_id3}",
|
||||
voo_atual['origem'],
|
||||
voo_atual['destino'],
|
||||
voo_atual['tipo'],
|
||||
hora_atual.strftime('%H:%M'),
|
||||
hora_chegada.strftime('%H:%M'),
|
||||
f"{voo_atual['tempo']:.2f} h"
|
||||
])
|
||||
|
||||
# Próxima partida só depois do TAT de 40 min
|
||||
hora_atual = hora_chegada + datetime.timedelta(minutes=40)
|
||||
local_atual = voo_atual['destino']
|
||||
|
||||
while True:
|
||||
prox_voo = None
|
||||
for idx, v in enumerate(voos_para_fazer3):
|
||||
if v['origem'] == local_atual:
|
||||
if (hora_atual - datetime.datetime(2025, 1, 1, 0, 0, 0) + datetime.timedelta(hours=v['tempo'])).total_seconds() <= 24 * 3600:
|
||||
prox_voo = voos_para_fazer3.pop(idx)
|
||||
break
|
||||
|
||||
if prox_voo:
|
||||
tempo_delta = datetime.timedelta(hours=prox_voo['tempo'])
|
||||
hora_chegada = hora_atual + tempo_delta
|
||||
tabela_horarios3.append([
|
||||
f"Aeronave {aeronave_id3}",
|
||||
prox_voo['origem'],
|
||||
prox_voo['destino'],
|
||||
prox_voo['tipo'],
|
||||
hora_atual.strftime('%H:%M'),
|
||||
hora_chegada.strftime('%H:%M'),
|
||||
f"{prox_voo['tempo']:.2f} h"
|
||||
])
|
||||
hora_atual = hora_chegada + datetime.timedelta(minutes=40)
|
||||
local_atual = prox_voo['destino']
|
||||
else:
|
||||
break
|
||||
|
||||
aeronave_id3 += 1
|
||||
|
||||
print("== QUADRO DE HORÁRIOS DIÁRIOS (COM 40 MIN TAT) ==")
|
||||
print(tabulate(tabela_horarios3, headers=["Aeronave", "Origem", "Destino", "Tipo", "Partida", "Chegada", "Duração Voo"], tablefmt="github"))
|
||||
"""))
|
||||
|
||||
nb.cells = cells
|
||||
|
||||
with open('modelos.ipynb', 'w', encoding='utf-8') as f:
|
||||
|
||||
Reference in New Issue
Block a user