refactor: converte modelagem matemática de horas decimais para minutos inteiros
This commit is contained in:
222
modelos.ipynb
222
modelos.ipynb
@@ -2,7 +2,7 @@
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "eeb50313",
|
||||
"id": "79f9c4cd",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# Alocação de Frotas (Fleet Scheduling) - Aeronaves C-97\n",
|
||||
@@ -21,13 +21,13 @@
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 1,
|
||||
"id": "3345f6bf",
|
||||
"id": "54f43903",
|
||||
"metadata": {
|
||||
"execution": {
|
||||
"iopub.execute_input": "2026-06-07T23:44:10.042075Z",
|
||||
"iopub.status.busy": "2026-06-07T23:44:10.041422Z",
|
||||
"iopub.status.idle": "2026-06-07T23:44:10.717819Z",
|
||||
"shell.execute_reply": "2026-06-07T23:44:10.717190Z"
|
||||
"iopub.execute_input": "2026-06-07T23:48:22.236217Z",
|
||||
"iopub.status.busy": "2026-06-07T23:48:22.236030Z",
|
||||
"iopub.status.idle": "2026-06-07T23:48:22.868108Z",
|
||||
"shell.execute_reply": "2026-06-07T23:48:22.867334Z"
|
||||
}
|
||||
},
|
||||
"outputs": [],
|
||||
@@ -53,7 +53,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "bb838c8d",
|
||||
"id": "56cb48ea",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## 1. Leitura e Limpeza dos Dados\n",
|
||||
@@ -63,13 +63,13 @@
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 2,
|
||||
"id": "af65863f",
|
||||
"id": "47598c7a",
|
||||
"metadata": {
|
||||
"execution": {
|
||||
"iopub.execute_input": "2026-06-07T23:44:10.719344Z",
|
||||
"iopub.status.busy": "2026-06-07T23:44:10.719122Z",
|
||||
"iopub.status.idle": "2026-06-07T23:44:11.177567Z",
|
||||
"shell.execute_reply": "2026-06-07T23:44:11.176910Z"
|
||||
"iopub.execute_input": "2026-06-07T23:48:22.869683Z",
|
||||
"iopub.status.busy": "2026-06-07T23:48:22.869463Z",
|
||||
"iopub.status.idle": "2026-06-07T23:48:23.259672Z",
|
||||
"shell.execute_reply": "2026-06-07T23:48:23.259069Z"
|
||||
}
|
||||
},
|
||||
"outputs": [],
|
||||
@@ -101,7 +101,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "f4e097f0",
|
||||
"id": "6c58dbc1",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## 2. Análise dos Esquadrões e Matrículas (Aeronaves)\n",
|
||||
@@ -111,13 +111,13 @@
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 3,
|
||||
"id": "01c6de00",
|
||||
"id": "5a0bbad7",
|
||||
"metadata": {
|
||||
"execution": {
|
||||
"iopub.execute_input": "2026-06-07T23:44:11.179085Z",
|
||||
"iopub.status.busy": "2026-06-07T23:44:11.178943Z",
|
||||
"iopub.status.idle": "2026-06-07T23:44:11.193498Z",
|
||||
"shell.execute_reply": "2026-06-07T23:44:11.192832Z"
|
||||
"iopub.execute_input": "2026-06-07T23:48:23.261299Z",
|
||||
"iopub.status.busy": "2026-06-07T23:48:23.261168Z",
|
||||
"iopub.status.idle": "2026-06-07T23:48:23.273090Z",
|
||||
"shell.execute_reply": "2026-06-07T23:48:23.272489Z"
|
||||
}
|
||||
},
|
||||
"outputs": [
|
||||
@@ -176,7 +176,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "03d676ac",
|
||||
"id": "112d4888",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## 3. Análise Estatística das Demandas Diárias\n",
|
||||
@@ -187,13 +187,13 @@
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 4,
|
||||
"id": "d1d53c92",
|
||||
"id": "fcd3f8cd",
|
||||
"metadata": {
|
||||
"execution": {
|
||||
"iopub.execute_input": "2026-06-07T23:44:11.195008Z",
|
||||
"iopub.status.busy": "2026-06-07T23:44:11.194881Z",
|
||||
"iopub.status.idle": "2026-06-07T23:44:11.521316Z",
|
||||
"shell.execute_reply": "2026-06-07T23:44:11.520564Z"
|
||||
"iopub.execute_input": "2026-06-07T23:48:23.274563Z",
|
||||
"iopub.status.busy": "2026-06-07T23:48:23.274434Z",
|
||||
"iopub.status.idle": "2026-06-07T23:48:23.596693Z",
|
||||
"shell.execute_reply": "2026-06-07T23:48:23.596151Z"
|
||||
}
|
||||
},
|
||||
"outputs": [
|
||||
@@ -424,7 +424,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "5a340e61",
|
||||
"id": "13a07f72",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Diagrama de Rede dos Trechos\n",
|
||||
@@ -434,13 +434,13 @@
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 5,
|
||||
"id": "233d1236",
|
||||
"id": "cebc71a4",
|
||||
"metadata": {
|
||||
"execution": {
|
||||
"iopub.execute_input": "2026-06-07T23:44:11.522783Z",
|
||||
"iopub.status.busy": "2026-06-07T23:44:11.522643Z",
|
||||
"iopub.status.idle": "2026-06-07T23:44:11.652315Z",
|
||||
"shell.execute_reply": "2026-06-07T23:44:11.651816Z"
|
||||
"iopub.execute_input": "2026-06-07T23:48:23.598286Z",
|
||||
"iopub.status.busy": "2026-06-07T23:48:23.598153Z",
|
||||
"iopub.status.idle": "2026-06-07T23:48:23.718347Z",
|
||||
"shell.execute_reply": "2026-06-07T23:48:23.717643Z"
|
||||
}
|
||||
},
|
||||
"outputs": [
|
||||
@@ -497,7 +497,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "19a69fa7",
|
||||
"id": "561a020b",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## 4. Fleet Assignment Model (FAM) - Nível Brasil\n",
|
||||
@@ -514,13 +514,13 @@
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 6,
|
||||
"id": "77122760",
|
||||
"id": "191b2c03",
|
||||
"metadata": {
|
||||
"execution": {
|
||||
"iopub.execute_input": "2026-06-07T23:44:11.654036Z",
|
||||
"iopub.status.busy": "2026-06-07T23:44:11.653900Z",
|
||||
"iopub.status.idle": "2026-06-07T23:44:11.681677Z",
|
||||
"shell.execute_reply": "2026-06-07T23:44:11.681090Z"
|
||||
"iopub.execute_input": "2026-06-07T23:48:23.719928Z",
|
||||
"iopub.status.busy": "2026-06-07T23:48:23.719652Z",
|
||||
"iopub.status.idle": "2026-06-07T23:48:23.746255Z",
|
||||
"shell.execute_reply": "2026-06-07T23:48:23.745701Z"
|
||||
}
|
||||
},
|
||||
"outputs": [
|
||||
@@ -609,7 +609,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "d52acdc3",
|
||||
"id": "b16a0622",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## 5. Modelo 2: Minimização de Aeronaves\n",
|
||||
@@ -623,13 +623,13 @@
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 7,
|
||||
"id": "e4289b56",
|
||||
"id": "c24cc47b",
|
||||
"metadata": {
|
||||
"execution": {
|
||||
"iopub.execute_input": "2026-06-07T23:44:11.683322Z",
|
||||
"iopub.status.busy": "2026-06-07T23:44:11.683175Z",
|
||||
"iopub.status.idle": "2026-06-07T23:44:13.105611Z",
|
||||
"shell.execute_reply": "2026-06-07T23:44:13.105024Z"
|
||||
"iopub.execute_input": "2026-06-07T23:48:23.747882Z",
|
||||
"iopub.status.busy": "2026-06-07T23:48:23.747749Z",
|
||||
"iopub.status.idle": "2026-06-07T23:48:25.090530Z",
|
||||
"shell.execute_reply": "2026-06-07T23:48:25.089931Z"
|
||||
}
|
||||
},
|
||||
"outputs": [
|
||||
@@ -642,26 +642,26 @@
|
||||
"== RESULTADO DO MODELO 2 ==\n",
|
||||
"Status: Optimal\n",
|
||||
"Número mínimo absoluto de aeronaves C-97 necessárias: 1\n",
|
||||
"Tempo total de voo diário (incluindo reposicionamento vazio): 16.70 horas\n",
|
||||
"Taxa de ocupação da frota (Tempo Voo / Tempo Disponível): 69.6%\n",
|
||||
"Tempo total de voo diário (incluindo reposicionamento vazio): 1004 min (16.73 h)\n",
|
||||
"Taxa de ocupação da frota (Tempo Voo / Tempo Disponível): 69.7%\n",
|
||||
"\n",
|
||||
"Voos de Reposicionamento Vazio Gerados (Y) para fechar o ciclo diário:\n",
|
||||
" -> De SBAN para SBSJ: 1 voo(s) vazio(s) | Tempo de voo: 2.1h\n",
|
||||
" -> De SBAN para SBSJ: 1 voo(s) vazio(s) | Tempo de voo: 129 min\n",
|
||||
"\n",
|
||||
"== QUADRO DE HORÁRIOS DIÁRIOS ==\n",
|
||||
"| Aeronave | Origem | Destino | Tipo | Partida | Chegada | Duração |\n",
|
||||
"|------------|----------|-----------|--------------------------|-----------|-----------|-----------|\n",
|
||||
"| Aeronave 1 | SBGL | SBGR | Passageiro | 00:00 | 00:51 | 0.86 h |\n",
|
||||
"| Aeronave 1 | SBGR | SBGL | Passageiro | 00:51 | 01:43 | 0.86 h |\n",
|
||||
"| Aeronave 1 | SBGL | SBBR | Passageiro | 01:43 | 04:02 | 2.33 h |\n",
|
||||
"| Aeronave 1 | SBBR | SBGL | Passageiro | 04:02 | 06:22 | 2.33 h |\n",
|
||||
"| Aeronave 1 | SBGL | SBSJ | Passageiro | 06:22 | 07:03 | 0.69 h |\n",
|
||||
"| Aeronave 1 | SBSJ | SBGL | Passageiro | 07:03 | 07:45 | 0.69 h |\n",
|
||||
"| Aeronave 2 | SBGR | SBBR | Passageiro | 00:00 | 02:10 | 2.17 h |\n",
|
||||
"| Aeronave 2 | SBBR | SBGR | Passageiro | 02:10 | 04:20 | 2.17 h |\n",
|
||||
"| Aeronave 3 | SBBR | SBAN | Passageiro | 00:00 | 00:18 | 0.30 h |\n",
|
||||
"| Aeronave 3 | SBAN | SBSJ | Vazio (Reposicionamento) | 00:18 | 02:26 | 2.14 h |\n",
|
||||
"| Aeronave 3 | SBSJ | SBBR | Passageiro | 02:26 | 04:35 | 2.15 h |\n"
|
||||
"| Aeronave 1 | SBSJ | SBGL | Passageiro | 00:00 | 00:42 | 42 min |\n",
|
||||
"| Aeronave 1 | SBGL | SBSJ | Passageiro | 00:42 | 01:24 | 42 min |\n",
|
||||
"| Aeronave 1 | SBSJ | SBBR | Passageiro | 01:24 | 03:33 | 129 min |\n",
|
||||
"| Aeronave 1 | SBBR | SBGL | Passageiro | 03:33 | 05:53 | 140 min |\n",
|
||||
"| Aeronave 1 | SBGL | SBBR | Passageiro | 05:53 | 08:13 | 140 min |\n",
|
||||
"| Aeronave 1 | SBBR | SBAN | Passageiro | 08:13 | 08:31 | 18 min |\n",
|
||||
"| Aeronave 1 | SBAN | SBSJ | Vazio (Reposicionamento) | 08:31 | 10:40 | 129 min |\n",
|
||||
"| Aeronave 2 | SBGL | SBGR | Passageiro | 00:00 | 00:52 | 52 min |\n",
|
||||
"| Aeronave 2 | SBGR | SBGL | Passageiro | 00:52 | 01:44 | 52 min |\n",
|
||||
"| Aeronave 3 | SBBR | SBGR | Passageiro | 00:00 | 02:10 | 130 min |\n",
|
||||
"| Aeronave 3 | SBGR | SBBR | Passageiro | 02:10 | 04:20 | 130 min |\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
@@ -695,15 +695,15 @@
|
||||
" aeroportos_malha.add(d)\n",
|
||||
"aeroportos_malha = list(aeroportos_malha)\n",
|
||||
"\n",
|
||||
"# Matriz de tempo de voo entre todos os nós da malha (para reposicionamento)\n",
|
||||
"tempos_voo = {}\n",
|
||||
"# Matriz de tempo de voo entre todos os nós da malha em MINUTOS (inteiro)\n",
|
||||
"tempos_voo_min = {}\n",
|
||||
"for o in aeroportos_malha:\n",
|
||||
" for d in aeroportos_malha:\n",
|
||||
" if o == d:\n",
|
||||
" tempos_voo[(o, d)] = 0\n",
|
||||
" tempos_voo_min[(o, d)] = 0\n",
|
||||
" else:\n",
|
||||
" dist = calc_distancia(o, d)\n",
|
||||
" tempos_voo[(o, d)] = dist / vel_media_c97\n",
|
||||
" tempos_voo_min[(o, d)] = int(round((dist / vel_media_c97) * 60))\n",
|
||||
"\n",
|
||||
"# Demanda fixa D_{i,j}\n",
|
||||
"D = {(o, d): 0 for o in aeroportos_malha for d in aeroportos_malha}\n",
|
||||
@@ -722,7 +722,7 @@
|
||||
"\n",
|
||||
"# Função Objetivo: Minimizar N\n",
|
||||
"# Para desempatar soluções com mesmo N, damos um pequeno peso pro tempo de reposicionamento vazio (para pegar o roteamento mais curto também)\n",
|
||||
"prob2 += N + 0.0001 * pulp.lpSum([Y[(i, j)] * tempos_voo[(i, j)] for i in aeroportos_malha for j in aeroportos_malha])\n",
|
||||
"prob2 += N + 0.0001 * pulp.lpSum([Y[(i, j)] * tempos_voo_min[(i, j)] for i in aeroportos_malha for j in aeroportos_malha])\n",
|
||||
"\n",
|
||||
"# Restrição de conservação de fluxo para cada aeroporto (Chegadas == Partidas)\n",
|
||||
"for no in aeroportos_malha:\n",
|
||||
@@ -730,9 +730,9 @@
|
||||
" partidas = pulp.lpSum([D[(no, j)] + Y[(no, j)] for j in aeroportos_malha])\n",
|
||||
" prob2 += chegadas == partidas\n",
|
||||
"\n",
|
||||
"# Restrição de tempo (O tempo total de voo da malha não pode exceder N * 24h)\n",
|
||||
"tempo_total_voo = pulp.lpSum([(D[(i, j)] + Y[(i, j)]) * tempos_voo[(i, j)] for i in aeroportos_malha for j in aeroportos_malha])\n",
|
||||
"prob2 += tempo_total_voo <= N * 24.0\n",
|
||||
"# Restrição de tempo (O tempo total de voo da malha não pode exceder N * 1440 min)\n",
|
||||
"tempo_total_voo = pulp.lpSum([(D[(i, j)] + Y[(i, j)]) * tempos_voo_min[(i, j)] for i in aeroportos_malha for j in aeroportos_malha])\n",
|
||||
"prob2 += tempo_total_voo <= N * 1440\n",
|
||||
"\n",
|
||||
"# Solução\n",
|
||||
"prob2.solve(pulp.PULP_CBC_CMD(msg=False))\n",
|
||||
@@ -741,17 +741,17 @@
|
||||
"print(f\"Status: {pulp.LpStatus[prob2.status]}\")\n",
|
||||
"print(f\"Número mínimo absoluto de aeronaves C-97 necessárias: {int(N.varValue)}\")\n",
|
||||
"\n",
|
||||
"tempo_gasto = sum([(D[(i, j)] + Y[(i, j)].varValue) * tempos_voo[(i, j)] for i in aeroportos_malha for j in aeroportos_malha])\n",
|
||||
"print(f\"Tempo total de voo diário (incluindo reposicionamento vazio): {tempo_gasto:.2f} horas\")\n",
|
||||
"tempo_gasto = sum([(D[(i, j)] + int(Y[(i, j)].varValue)) * tempos_voo_min[(i, j)] for i in aeroportos_malha for j in aeroportos_malha])\n",
|
||||
"print(f\"Tempo total de voo diário (incluindo reposicionamento vazio): {int(tempo_gasto)} min ({tempo_gasto/60:.2f} h)\")\n",
|
||||
"if N.varValue > 0:\n",
|
||||
" print(f\"Taxa de ocupação da frota (Tempo Voo / Tempo Disponível): {(tempo_gasto / (N.varValue * 24)) * 100:.1f}%\\n\")\n",
|
||||
" print(f\"Taxa de ocupação da frota (Tempo Voo / Tempo Disponível): {(tempo_gasto / (N.varValue * 1440)) * 100:.1f}%\\n\")\n",
|
||||
"\n",
|
||||
"print(\"Voos de Reposicionamento Vazio Gerados (Y) para fechar o ciclo diário:\")\n",
|
||||
"gerou_vazio = False\n",
|
||||
"for i in aeroportos_malha:\n",
|
||||
" for j in aeroportos_malha:\n",
|
||||
" if Y[(i, j)].varValue > 0:\n",
|
||||
" print(f\" -> De {i} para {j}: {int(Y[(i, j)].varValue)} voo(s) vazio(s) | Tempo de voo: {tempos_voo[(i,j)]*Y[(i,j)].varValue:.1f}h\")\n",
|
||||
" print(f\" -> De {i} para {j}: {int(Y[(i, j)].varValue)} voo(s) vazio(s) | Tempo de voo: {tempos_voo_min[(i,j)]*int(Y[(i,j)].varValue)} min\")\n",
|
||||
" gerou_vazio = True\n",
|
||||
"if not gerou_vazio:\n",
|
||||
" print(\" Nenhum voo de reposicionamento vazio foi necessário! A malha já é circular/balanceada.\")\n",
|
||||
@@ -775,7 +775,7 @@
|
||||
" D_copy[(i, j)] -= 1\n",
|
||||
" else:\n",
|
||||
" tipo = 'Vazio (Reposicionamento)'\n",
|
||||
" voos_para_fazer.append({'origem': i, 'destino': j, 'tipo': tipo, 'tempo': tempos_voo[(i, j)]})\n",
|
||||
" voos_para_fazer.append({'origem': i, 'destino': j, 'tipo': tipo, 'tempo': tempos_voo_min[(i, j)]})\n",
|
||||
"\n",
|
||||
"# 2. Simular a alocação sequencial de horários\n",
|
||||
"tabela_horarios = []\n",
|
||||
@@ -785,7 +785,7 @@
|
||||
" voo_atual = voos_para_fazer.pop(0)\n",
|
||||
" hora_atual = datetime.datetime(2025, 1, 1, 0, 0, 0)\n",
|
||||
" \n",
|
||||
" tempo_delta = datetime.timedelta(hours=voo_atual['tempo'])\n",
|
||||
" tempo_delta = datetime.timedelta(minutes=int(voo_atual['tempo']))\n",
|
||||
" hora_chegada = hora_atual + tempo_delta\n",
|
||||
" \n",
|
||||
" tabela_horarios.append([\n",
|
||||
@@ -795,7 +795,7 @@
|
||||
" voo_atual['tipo'],\n",
|
||||
" hora_atual.strftime('%H:%M'),\n",
|
||||
" hora_chegada.strftime('%H:%M'),\n",
|
||||
" f\"{voo_atual['tempo']:.2f} h\"\n",
|
||||
" f\"{voo_atual['tempo']} min\"\n",
|
||||
" ])\n",
|
||||
" \n",
|
||||
" hora_atual = hora_chegada\n",
|
||||
@@ -806,12 +806,12 @@
|
||||
" prox_voo = None\n",
|
||||
" for idx, v in enumerate(voos_para_fazer):\n",
|
||||
" if v['origem'] == local_atual:\n",
|
||||
" if (hora_atual - datetime.datetime(2025, 1, 1, 0, 0, 0) + datetime.timedelta(hours=v['tempo'])).total_seconds() <= 24 * 3600:\n",
|
||||
" if (hora_atual - datetime.datetime(2025, 1, 1, 0, 0, 0) + datetime.timedelta(minutes=int(v['tempo']))).total_seconds() <= 1440 * 60:\n",
|
||||
" prox_voo = voos_para_fazer.pop(idx)\n",
|
||||
" break\n",
|
||||
" \n",
|
||||
" if prox_voo:\n",
|
||||
" tempo_delta = datetime.timedelta(hours=prox_voo['tempo'])\n",
|
||||
" tempo_delta = datetime.timedelta(minutes=int(prox_voo['tempo']))\n",
|
||||
" hora_chegada = hora_atual + tempo_delta\n",
|
||||
" tabela_horarios.append([\n",
|
||||
" f\"Aeronave {aeronave_id}\",\n",
|
||||
@@ -820,7 +820,7 @@
|
||||
" prox_voo['tipo'],\n",
|
||||
" hora_atual.strftime('%H:%M'),\n",
|
||||
" hora_chegada.strftime('%H:%M'),\n",
|
||||
" f\"{prox_voo['tempo']:.2f} h\"\n",
|
||||
" f\"{prox_voo['tempo']} min\"\n",
|
||||
" ])\n",
|
||||
" hora_atual = hora_chegada\n",
|
||||
" local_atual = prox_voo['destino']\n",
|
||||
@@ -835,7 +835,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "2daf591f",
|
||||
"id": "f18a2ffb",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## 6. Modelo 3: Minimização de Aeronaves com TAT (Turnaround Time)\n",
|
||||
@@ -848,13 +848,13 @@
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 8,
|
||||
"id": "4d54330a",
|
||||
"id": "13888b4d",
|
||||
"metadata": {
|
||||
"execution": {
|
||||
"iopub.execute_input": "2026-06-07T23:44:13.108816Z",
|
||||
"iopub.status.busy": "2026-06-07T23:44:13.108593Z",
|
||||
"iopub.status.idle": "2026-06-07T23:44:13.126370Z",
|
||||
"shell.execute_reply": "2026-06-07T23:44:13.125849Z"
|
||||
"iopub.execute_input": "2026-06-07T23:48:25.091858Z",
|
||||
"iopub.status.busy": "2026-06-07T23:48:25.091719Z",
|
||||
"iopub.status.idle": "2026-06-07T23:48:25.108636Z",
|
||||
"shell.execute_reply": "2026-06-07T23:48:25.108109Z"
|
||||
}
|
||||
},
|
||||
"outputs": [
|
||||
@@ -866,25 +866,25 @@
|
||||
"== RESULTADO DO MODELO 3 (COM 40 MIN DE SOLO) ==\n",
|
||||
"Status: Optimal\n",
|
||||
"Número mínimo absoluto de aeronaves C-97 necessárias: 2\n",
|
||||
"Tempo total de voo puro: 16.70 horas\n",
|
||||
"Tempo total gasto em solo (TAT): 7.33 horas\n",
|
||||
"Tempo total operacional comprometido: 24.04 horas\n",
|
||||
"Tempo total de voo puro: 1004 min (16.73 h)\n",
|
||||
"Tempo total gasto em solo (TAT): 440 min (7.33 h)\n",
|
||||
"Tempo total operacional comprometido: 1444 min (24.07 h)\n",
|
||||
"Taxa de ocupação da frota (Tempo Operacional / Tempo Disponível): 50.1%\n",
|
||||
"\n",
|
||||
"== QUADRO DE HORÁRIOS DIÁRIOS (COM 40 MIN TAT) ==\n",
|
||||
"| Aeronave | Origem | Destino | Tipo | Partida | Chegada | Duração Voo |\n",
|
||||
"|------------|----------|-----------|--------------------------|-----------|-----------|---------------|\n",
|
||||
"| Aeronave 1 | SBGL | SBGR | Passageiro | 00:00 | 00:51 | 0.86 h |\n",
|
||||
"| Aeronave 1 | SBGR | SBGL | Passageiro | 01:31 | 02:23 | 0.86 h |\n",
|
||||
"| Aeronave 1 | SBGL | SBBR | Passageiro | 03:03 | 05:22 | 2.33 h |\n",
|
||||
"| Aeronave 1 | SBBR | SBGL | Passageiro | 06:02 | 08:22 | 2.33 h |\n",
|
||||
"| Aeronave 1 | SBGL | SBSJ | Passageiro | 09:02 | 09:43 | 0.69 h |\n",
|
||||
"| Aeronave 1 | SBSJ | SBGL | Passageiro | 10:23 | 11:05 | 0.69 h |\n",
|
||||
"| Aeronave 2 | SBGR | SBBR | Passageiro | 00:00 | 02:10 | 2.17 h |\n",
|
||||
"| Aeronave 2 | SBBR | SBGR | Passageiro | 02:50 | 05:00 | 2.17 h |\n",
|
||||
"| Aeronave 3 | SBBR | SBAN | Passageiro | 00:00 | 00:18 | 0.30 h |\n",
|
||||
"| Aeronave 3 | SBAN | SBSJ | Vazio (Reposicionamento) | 00:58 | 03:06 | 2.14 h |\n",
|
||||
"| Aeronave 3 | SBSJ | SBBR | Passageiro | 03:46 | 05:55 | 2.15 h |\n"
|
||||
"| Aeronave 1 | SBSJ | SBGL | Passageiro | 00:00 | 00:42 | 42 min |\n",
|
||||
"| Aeronave 1 | SBGL | SBSJ | Passageiro | 01:22 | 02:04 | 42 min |\n",
|
||||
"| Aeronave 1 | SBSJ | SBBR | Passageiro | 02:44 | 04:53 | 129 min |\n",
|
||||
"| Aeronave 1 | SBBR | SBGL | Passageiro | 05:33 | 07:53 | 140 min |\n",
|
||||
"| Aeronave 1 | SBGL | SBBR | Passageiro | 08:33 | 10:53 | 140 min |\n",
|
||||
"| Aeronave 1 | SBBR | SBAN | Passageiro | 11:33 | 11:51 | 18 min |\n",
|
||||
"| Aeronave 1 | SBAN | SBSJ | Vazio (Reposicionamento) | 12:31 | 14:40 | 129 min |\n",
|
||||
"| Aeronave 2 | SBGL | SBGR | Passageiro | 00:00 | 00:52 | 52 min |\n",
|
||||
"| Aeronave 2 | SBGR | SBGL | Passageiro | 01:32 | 02:24 | 52 min |\n",
|
||||
"| Aeronave 3 | SBBR | SBGR | Passageiro | 00:00 | 02:10 | 130 min |\n",
|
||||
"| Aeronave 3 | SBGR | SBBR | Passageiro | 02:50 | 05:00 | 130 min |\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
@@ -896,10 +896,10 @@
|
||||
"Y3 = pulp.LpVariable.dicts(\"Y3\", [(o, d) for o in aeroportos_malha for d in aeroportos_malha], lowBound=0, cat='Integer')\n",
|
||||
"N3 = pulp.LpVariable(\"N3\", lowBound=0, cat='Integer')\n",
|
||||
"\n",
|
||||
"TAT_horas = 40.0 / 60.0\n",
|
||||
"TAT_min = 40\n",
|
||||
"\n",
|
||||
"# Função Objetivo\n",
|
||||
"prob3 += N3 + 0.0001 * pulp.lpSum([Y3[(i, j)] * tempos_voo[(i, j)] for i in aeroportos_malha for j in aeroportos_malha])\n",
|
||||
"prob3 += N3 + 0.0001 * pulp.lpSum([Y3[(i, j)] * tempos_voo_min[(i, j)] for i in aeroportos_malha for j in aeroportos_malha])\n",
|
||||
"\n",
|
||||
"# Restrição de fluxo\n",
|
||||
"for no in aeroportos_malha:\n",
|
||||
@@ -909,8 +909,8 @@
|
||||
"\n",
|
||||
"# Restrição de tempo com TAT\n",
|
||||
"# Cada voo (D ou Y) consome tempo de voo + TAT\n",
|
||||
"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])\n",
|
||||
"prob3 += tempo_total_operacional <= N3 * 24.0\n",
|
||||
"tempo_total_operacional = pulp.lpSum([(D[(i, j)] + Y3[(i, j)]) * (tempos_voo_min[(i, j)] + TAT_min) for i in aeroportos_malha for j in aeroportos_malha])\n",
|
||||
"prob3 += tempo_total_operacional <= N3 * 1440\n",
|
||||
"\n",
|
||||
"# Solução\n",
|
||||
"prob3.solve(pulp.PULP_CBC_CMD(msg=False))\n",
|
||||
@@ -919,15 +919,15 @@
|
||||
"print(f\"Status: {pulp.LpStatus[prob3.status]}\")\n",
|
||||
"print(f\"Número mínimo absoluto de aeronaves C-97 necessárias: {int(N3.varValue)}\")\n",
|
||||
"\n",
|
||||
"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])\n",
|
||||
"total_voos_realizados = sum([(D[(i, j)] + Y3[(i, j)].varValue) for i in aeroportos_malha for j in aeroportos_malha])\n",
|
||||
"tempo_solo_total = total_voos_realizados * TAT_horas\n",
|
||||
"tempo_voo_puro = sum([(D[(i, j)] + int(Y3[(i, j)].varValue)) * tempos_voo_min[(i, j)] for i in aeroportos_malha for j in aeroportos_malha])\n",
|
||||
"total_voos_realizados = sum([(D[(i, j)] + int(Y3[(i, j)].varValue)) for i in aeroportos_malha for j in aeroportos_malha])\n",
|
||||
"tempo_solo_total = total_voos_realizados * TAT_min\n",
|
||||
"\n",
|
||||
"print(f\"Tempo total de voo puro: {tempo_voo_puro:.2f} horas\")\n",
|
||||
"print(f\"Tempo total gasto em solo (TAT): {tempo_solo_total:.2f} horas\")\n",
|
||||
"print(f\"Tempo total operacional comprometido: {tempo_voo_puro + tempo_solo_total:.2f} horas\")\n",
|
||||
"print(f\"Tempo total de voo puro: {tempo_voo_puro} min ({tempo_voo_puro/60:.2f} h)\")\n",
|
||||
"print(f\"Tempo total gasto em solo (TAT): {tempo_solo_total} min ({tempo_solo_total/60:.2f} h)\")\n",
|
||||
"print(f\"Tempo total operacional comprometido: {tempo_voo_puro + tempo_solo_total} min ({(tempo_voo_puro + tempo_solo_total)/60:.2f} h)\")\n",
|
||||
"if N3.varValue > 0:\n",
|
||||
" 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\")\n",
|
||||
" print(f\"Taxa de ocupação da frota (Tempo Operacional / Tempo Disponível): {((tempo_voo_puro + tempo_solo_total) / (N3.varValue * 1440)) * 100:.1f}%\\n\")\n",
|
||||
"\n",
|
||||
"# GERAR TABELA DE HORÁRIOS COM TABULATE E DATETIME\n",
|
||||
"voos_para_fazer3 = []\n",
|
||||
@@ -942,7 +942,7 @@
|
||||
" D_copy3[(i, j)] -= 1\n",
|
||||
" else:\n",
|
||||
" tipo = 'Vazio (Reposicionamento)'\n",
|
||||
" voos_para_fazer3.append({'origem': i, 'destino': j, 'tipo': tipo, 'tempo': tempos_voo[(i, j)]})\n",
|
||||
" voos_para_fazer3.append({'origem': i, 'destino': j, 'tipo': tipo, 'tempo': tempos_voo_min[(i, j)]})\n",
|
||||
"\n",
|
||||
"tabela_horarios3 = []\n",
|
||||
"aeronave_id3 = 1\n",
|
||||
@@ -951,7 +951,7 @@
|
||||
" voo_atual = voos_para_fazer3.pop(0)\n",
|
||||
" hora_atual = datetime.datetime(2025, 1, 1, 0, 0, 0)\n",
|
||||
" \n",
|
||||
" tempo_delta = datetime.timedelta(hours=voo_atual['tempo'])\n",
|
||||
" tempo_delta = datetime.timedelta(minutes=int(voo_atual['tempo']))\n",
|
||||
" hora_chegada = hora_atual + tempo_delta\n",
|
||||
" \n",
|
||||
" tabela_horarios3.append([\n",
|
||||
@@ -961,7 +961,7 @@
|
||||
" voo_atual['tipo'],\n",
|
||||
" hora_atual.strftime('%H:%M'),\n",
|
||||
" hora_chegada.strftime('%H:%M'),\n",
|
||||
" f\"{voo_atual['tempo']:.2f} h\"\n",
|
||||
" f\"{voo_atual['tempo']} min\"\n",
|
||||
" ])\n",
|
||||
" \n",
|
||||
" # Próxima partida só depois do TAT de 40 min\n",
|
||||
@@ -972,12 +972,12 @@
|
||||
" prox_voo = None\n",
|
||||
" for idx, v in enumerate(voos_para_fazer3):\n",
|
||||
" if v['origem'] == local_atual:\n",
|
||||
" if (hora_atual - datetime.datetime(2025, 1, 1, 0, 0, 0) + datetime.timedelta(hours=v['tempo'])).total_seconds() <= 24 * 3600:\n",
|
||||
" if (hora_atual - datetime.datetime(2025, 1, 1, 0, 0, 0) + datetime.timedelta(minutes=int(v['tempo']))).total_seconds() <= 1440 * 60:\n",
|
||||
" prox_voo = voos_para_fazer3.pop(idx)\n",
|
||||
" break\n",
|
||||
" \n",
|
||||
" if prox_voo:\n",
|
||||
" tempo_delta = datetime.timedelta(hours=prox_voo['tempo'])\n",
|
||||
" tempo_delta = datetime.timedelta(minutes=int(prox_voo['tempo']))\n",
|
||||
" hora_chegada = hora_atual + tempo_delta\n",
|
||||
" tabela_horarios3.append([\n",
|
||||
" f\"Aeronave {aeronave_id3}\",\n",
|
||||
@@ -986,7 +986,7 @@
|
||||
" prox_voo['tipo'],\n",
|
||||
" hora_atual.strftime('%H:%M'),\n",
|
||||
" hora_chegada.strftime('%H:%M'),\n",
|
||||
" f\"{prox_voo['tempo']:.2f} h\"\n",
|
||||
" f\"{prox_voo['tempo']} min\"\n",
|
||||
" ])\n",
|
||||
" hora_atual = hora_chegada + datetime.timedelta(minutes=40)\n",
|
||||
" local_atual = prox_voo['destino']\n",
|
||||
|
||||
Reference in New Issue
Block a user