Compare commits
2 Commits
11821eaa93
...
7cd7458565
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7cd7458565 | ||
|
|
328a066849 |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -9,6 +9,7 @@ Desktop.ini
|
|||||||
# Local editor folders
|
# Local editor folders
|
||||||
.vscode/
|
.vscode/
|
||||||
.idea/
|
.idea/
|
||||||
|
.claude/
|
||||||
|
|
||||||
# Python cache
|
# Python cache
|
||||||
__pycache__/
|
__pycache__/
|
||||||
|
|||||||
119
HANDOFF_arara_oamrp.md
Normal file
119
HANDOFF_arara_oamrp.md
Normal file
@@ -0,0 +1,119 @@
|
|||||||
|
# HANDOFF — ARARA OAMRP (Aircraft Routing C-105 / FAB)
|
||||||
|
|
||||||
|
> Documento de transferência para o **Claude Code**.
|
||||||
|
> Projeto local: `arara_oamrp/`. Cole/abra este arquivo no Claude Code e siga as instruções de leitura antes de validar a formulação e gerar código.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 0. Enquadramento do problema
|
||||||
|
|
||||||
|
Modelo de **Aircraft Routing** para o Esquadrão ARARA (C-105), no estilo **OAMRP** (Al-Thani et al., 2016): sequenciamento **compacto** em **rede espaço-tempo**.
|
||||||
|
|
||||||
|
**NÃO** é Set Partitioning + Column Generation (modelo civil Bazargan). Desvios deliberados em relação ao caso civil:
|
||||||
|
|
||||||
|
1. **Cobertura ≤ 1** (seleção de missões), não particionamento `= 1`.
|
||||||
|
2. **Objetivo de maximização** de cobertura ponderada por prioridade, não minimização de custo.
|
||||||
|
3. Possibilidade de subconjunto de missões **obrigatórias (hard)**.
|
||||||
|
|
||||||
|
**Stack:** Python + PuLP (CBC para começar) → HiGHS como evolução.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 1. Calibração confirmada (respostas do Vitor)
|
||||||
|
|
||||||
|
| Item | Decisão |
|
||||||
|
|---|---|
|
||||||
|
| Frota | **4 aeronaves**, homogêneas (mesmo LRT, mesma performance) |
|
||||||
|
| Horizonte | **1 mês** |
|
||||||
|
| Discretização | **Estilo OAMRP** — eventos de voo com horários explícitos |
|
||||||
|
| TAT (turnaround) | **01h30** |
|
||||||
|
| Base de inspeção | Apenas **SBMN** (somente níveis **Base** e **Orgânico**; **Parque desconsiderado**) |
|
||||||
|
| Bases de operação | **10 bases da FAB** (derivar/confirmar a partir do CSV) |
|
||||||
|
| Traslado (ferry) | **Permitido** e **consome horas de célula** |
|
||||||
|
| Reset de horas | Inspeção **zera apenas aquela inspeção**; inspeções **não simultâneas** na mesma aeronave (podem ser sequenciais se requisitos cumpridos) |
|
||||||
|
| Prioridade | Escala **1 a 5** |
|
||||||
|
| Missões por dia | Uma cauda pode encadear **várias missões no mesmo dia** |
|
||||||
|
| Horas iniciais (f_k) | Criar **campos editáveis**; permitir **default aleatório** |
|
||||||
|
|
||||||
|
### Objetivo (lexicográfico)
|
||||||
|
- **L1 — Primário:** maximizar Σ (prioridade × missões cumpridas).
|
||||||
|
- **L2 — Secundário:** "entregar aeronave com menor LRT" *(ver Q3 — pendente de definição)*.
|
||||||
|
- **Restrição dura derivada do 6.1:** **no máximo 1 aeronave em inspeção ao mesmo tempo** → modelada como restrição de recurso (C11), não como objetivo.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2. Formulação matemática proposta (validar antes de codar)
|
||||||
|
|
||||||
|
### Conjuntos
|
||||||
|
- `K` — aeronaves (caudas), |K| = 4.
|
||||||
|
- `B` — bases (10). `B_insp ⊆ B = {SBMN}`.
|
||||||
|
- `M` — missões candidatas. `M_obr ⊆ M` — obrigatórias *(Q2)*.
|
||||||
|
- `T` — tipos de inspeção válidos *(Q1)*.
|
||||||
|
|
||||||
|
### Parâmetros
|
||||||
|
- `f⁰_{k,i}` — horas acumuladas iniciais da cauda `k` no relógio da inspeção `i` (editável / aleatório).
|
||||||
|
- `LRT_i` — intervalo (horas de célula) da inspeção `i`.
|
||||||
|
- `CAL_i` — limite calendárico (dias) da inspeção `i`.
|
||||||
|
- `DT_i` — tempo indisponível (downtime) da inspeção `i`.
|
||||||
|
- `h_m` — horas de voo da missão `m` (do CSV, por par O-D).
|
||||||
|
- `o_m, d_m` — origem/destino de `m`.
|
||||||
|
- `[e_m, l_m]` — janela de decolagem de `m`.
|
||||||
|
- `p_m ∈ {1..5}` — prioridade de `m`.
|
||||||
|
- `hferry_{b,b'}` — horas de traslado entre bases (do CSV/distância).
|
||||||
|
- `home_k` — base inicial da cauda `k`.
|
||||||
|
- `TAT = 1.5 h`.
|
||||||
|
|
||||||
|
### Variáveis de decisão
|
||||||
|
- `x_{k,m} ∈ {0,1}` — cauda `k` cumpre missão `m`.
|
||||||
|
- `y` — arcos de sequenciamento na rede espaço-tempo (missão→missão, ferry, inspeção) por cauda.
|
||||||
|
- `t_dep_{k,m}`, `t_arr_{k,m}` — tempos (contínuos).
|
||||||
|
- `z_{k,i}` (+ início `s_{k,i}`) — cauda `k` executa inspeção `i`.
|
||||||
|
- `F_{k,i}(·)` — estado de horas acumuladas no relógio `i` ao longo da rota (contínuo, zera na inspeção `i`).
|
||||||
|
|
||||||
|
### Restrições
|
||||||
|
- **C1 Cobertura:** Σ_k x_{k,m} ≤ 1 ∀m; **= 1** ∀m ∈ M_obr.
|
||||||
|
- **C2 Continuidade (fluxo):** cada cauda forma um caminho único ordenado no tempo, iniciando em `home_k`; grau de entrada = grau de saída nos nós.
|
||||||
|
- **C3 Continuidade espacial:** encadear `m→m'` exige `d_m = o_{m'}`, senão exige arco de **ferry**.
|
||||||
|
- **C4 Continuidade temporal + TAT:** `t_dep(próx) ≥ t_arr(ant) + TAT` (+ tempo de ferry, se houver reposicionamento).
|
||||||
|
- **C5 Janela:** `e_m ≤ t_dep_{k,m} ≤ l_m`.
|
||||||
|
- **C6 Orçamento de horas com reset:** ao longo da rota, horas acumuladas no relógio `i` ≤ `LRT_i`; voo/ferry somam horas; inspeção `i` zera o relógio `i`.
|
||||||
|
- **C7 Limite calendárico:** dias desde o último reset de `i` ≤ `CAL_i`.
|
||||||
|
- **C8 Local de inspeção:** inspeção `i` só ocorre com a cauda em `B_insp` (SBMN); a cauda precisa rotear até lá.
|
||||||
|
- **C9 Downtime:** durante `DT_i` a cauda fica indisponível; atividades seguintes começam após.
|
||||||
|
- **C10 Não-simultaneidade na mesma cauda:** duas inspeções da mesma cauda não se sobrepõem (podem ser back-to-back).
|
||||||
|
- **C11 Slot único de inspeção (recurso):** em qualquer instante, Σ_k [cauda em inspeção] ≤ 1.
|
||||||
|
|
||||||
|
### Função objetivo (lexicográfica)
|
||||||
|
1. **max** Σ_m p_m · (Σ_k x_{k,m})
|
||||||
|
2. **então** otimizar L2 *(Q3)*.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 3. Plano incremental de construção
|
||||||
|
|
||||||
|
1. **Modelo base** — cobertura ponderada + orçamento de horas (C1–C6).
|
||||||
|
2. **Inspeção com reset** em SBMN — C7–C11 + downtime/calendário.
|
||||||
|
3. **Realismo militar** — prioridade hard (M_obr), voos de posicionamento, janelas.
|
||||||
|
4. **Replanejamento + visualização** — re-otimização e dashboard.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 4. Instruções para o Claude Code (executar na pasta `arara_oamrp/`)
|
||||||
|
|
||||||
|
1. **Ler contexto:** abrir o arquivo de CONTEXTO/LOG e tudo em `docs/` para entender o estado atual.
|
||||||
|
2. **Auditar e podar:** o ChatGPT inseriu **acréscimos desnecessários** — revisar e remover o que fugir do OAMRP compacto, mas antes pergunte. Confirmar que **não** há resquício de Set Partitioning + Column Generation.
|
||||||
|
3. **Ler inspeções:** `relatorio_ciclo_inspecoes_c105_2805_2026-06-15` (JSON) → extrair, para cada inspeção válida *(Q1: seq 2,3,4,6,7,18,19,20,22,23)*, os campos `LRT_i` (horas), `CAL_i` (limite calendárico) e `DT_i` (tempo indisponível).
|
||||||
|
4. **Ler voos:** `db/processed/registro_voo_2025_consolidado.csv` → derivar as **10 bases**, as **horas de voo por par O-D** (`h_m`) e os tempos de **ferry**.
|
||||||
|
5. **Horas iniciais:** criar campos editáveis para `f⁰_{k,i}`, com opção de **default aleatório**.
|
||||||
|
6. **Validar a formulação** da Seção 2 com o Vitor antes de gerar PuLP. Construção **incremental**, confirmando cada etapa.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 5. Pendências a resolver (perguntar ao Vitor no Claude Code)
|
||||||
|
|
||||||
|
- **Q1 — Inspeções válidas:** confirmar a lista de seq **{2, 3, 4, 6, 7, 18, 19, 20, 22, 23}**.
|
||||||
|
- **Q2 — Obrigatórias:** SAR/EVAM entram como **hard** (M_obr, cobertura = 1) ou apenas como prioridade 5? *(o dataset hoje só traz prioridade 1–5)*
|
||||||
|
- **Q3 — Objetivo secundário "entregar aeronave com menor LRT":** definir o sentido exato. Duas leituras possíveis:
|
||||||
|
- **(a)** minimizar a **folga de horas ao fim do horizonte** (usar bem as horas disponíveis: não deixar cauda ociosa com muita célula sobrando que poderia ter voado);
|
||||||
|
- **(b)** **priorizar o emprego** das caudas mais próximas da inspeção primeiro (consumir antes quem está mais perto do limite).
|
||||||
|
- **Q4 — Bases:** validar as 10 bases que o Claude Code propuser a partir do CSV.
|
||||||
6
LOG.md
6
LOG.md
@@ -26,3 +26,9 @@ Legenda de autores:
|
|||||||
| 2026-06-15 | 19:56 | VTO | Consolidou transicoes `ROTA` do registro de voo 2025 | `db/pre_process/registro_voo_2025/preprocess_planilha_2025.py`; `db/processed/registro_voo_2025_consolidado.csv` | `ROTA` tratado como marcador de transicao; 1421 linhas originais viraram 1268 trechos consolidados; 135 trechos com `ROTA` foram convertidos para origem/destino reais. |
|
| 2026-06-15 | 19:56 | VTO | Consolidou transicoes `ROTA` do registro de voo 2025 | `db/pre_process/registro_voo_2025/preprocess_planilha_2025.py`; `db/processed/registro_voo_2025_consolidado.csv` | `ROTA` tratado como marcador de transicao; 1421 linhas originais viraram 1268 trechos consolidados; 135 trechos com `ROTA` foram convertidos para origem/destino reais. |
|
||||||
| 2026-06-15 | 19:56 | VTO | Validou o registro de voo 2025 consolidado | `db/pre_process/registro_voo_2025/validacao_registro_voo_2025.md`; `db/processed/registro_voo_2025_consolidado.csv` | Sem duplicidades, sem divergencias de duracao e sem sobreposicoes temporais; pendentes 1 registro sem OM, 1 trecho com pousos zero e 3 quebras de continuidade espacial. |
|
| 2026-06-15 | 19:56 | VTO | Validou o registro de voo 2025 consolidado | `db/pre_process/registro_voo_2025/validacao_registro_voo_2025.md`; `db/processed/registro_voo_2025_consolidado.csv` | Sem duplicidades, sem divergencias de duracao e sem sobreposicoes temporais; pendentes 1 registro sem OM, 1 trecho com pousos zero e 3 quebras de continuidade espacial. |
|
||||||
| 2026-06-15 | 19:56 | VTO | Removeu registro isolado da aeronave 2806 | `db/pre_process/registro_voo_2025/preprocess_planilha_2025.py`; `db/processed/registro_voo_2025.csv`; `db/processed/registro_voo_2025_consolidado.csv` | Linha original 793 excluida dos artefatos processados; registro final passou para 1420 linhas e consolidado para 1267 trechos; nao ha mais registro sem OM. |
|
| 2026-06-15 | 19:56 | VTO | Removeu registro isolado da aeronave 2806 | `db/pre_process/registro_voo_2025/preprocess_planilha_2025.py`; `db/processed/registro_voo_2025.csv`; `db/processed/registro_voo_2025_consolidado.csv` | Linha original 793 excluida dos artefatos processados; registro final passou para 1420 linhas e consolidado para 1267 trechos; nao ha mais registro sem OM. |
|
||||||
|
| 2026-06-15 | 19:56 | VTO | Criou modelo OAMRP v2 com dados reais de 2025 | `software/oamrp_v2.py`; `db/processed/resultado_oamrp_jan_2025.csv`; `README.md`; `docs/about.md`; `docs/changelog.md` | Rodada inicial de janeiro/2025 resolvida como otima pelo CBC; prioridade uniforme 1; base de manutencao SBMN; 50 de 61 missoes cumpridas. |
|
||||||
|
| 2026-06-15 | 21:00 | VTO | Criou modelo OAMRP v3 — Fase 1: rede espaço-tempo | `software/oamrp_v3.py`; `db/processed/resultado_oamrp_v3.csv` | Reescrita do zero com abstrações No/Arco e variável unificada y[k,arco]; C1–C6; TAT=1,5h; f0_{k,i} editável; top-10 bases por frequência; missões EVAM hard; 50/50 missões cobertas em jan/2025. |
|
||||||
|
| 2026-06-15 | 22:00 | VTO | Calibrou inspeções válidas (Q1) e respondeu Q2–Q4 | `software/oamrp_v3.py` | Removidas seq 18 e 23 do catálogo; EVAM marcado como M_obr (cobertura=1); L2 definido como minimizar folga de horas ao fim do horizonte; 10 bases por frequência. |
|
||||||
|
| 2026-06-15 | 22:30 | VTO | Implementou Fase 2: inspeções na rede espaço-tempo | `software/oamrp_v3.py` | Adicionados nós INSP_{k}_{seq} e arcos missao_insp/insp_missao; variáveis H_{k,i,nid} para rastreamento de horas com reset; C9 downtime; C11 slot único via disjuntivas. |
|
||||||
|
| 2026-06-15 | 23:00 | VTO | Substituiu dados reais por missões sintéticas cross-base | `software/oamrp_v3.py`; `db/processed/resultado_oamrp_sintetico.csv` | Dados reais de jan/2025 eram todos SBMN→SBMN (voos locais), não exercitando roteamento; gerador sintético cria 50 missões cross-base entre 10 bases com distâncias reais (haversine) e velocidade C-105; flag --sintetico na CLI. |
|
||||||
|
| 2026-06-15 | 23:30 | VTO | Implementou Fase 3: arcos de ferry (C3 relaxado) | `software/oamrp_v3.py` | Arcos inicio/missao_missao/missao_insp/insp_missao agora permitem bases diferentes com tempo de ferry (haversine/430 km/h); ferry consome horas de célula no relógio de inspeção (C6); relatório imprime segmentos de ferry na linha do tempo. |
|
||||||
|
|||||||
16
README.md
16
README.md
@@ -182,3 +182,19 @@ db/processed/registro_voo_2025_consolidado.csv
|
|||||||
```
|
```
|
||||||
|
|
||||||
O consolidado trata `ROTA` como marcador de transicao, nao como localidade operacional, e remove a linha original 793 da aeronave 2806 dos artefatos processados.
|
O consolidado trata `ROTA` como marcador de transicao, nao como localidade operacional, e remove a linha original 793 da aeronave 2806 dos artefatos processados.
|
||||||
|
|
||||||
|
## Modelo OAMRP v2
|
||||||
|
|
||||||
|
O arquivo `software/oamrp_v2.py` executa a primeira rodada do modelo com dados reais consolidados de 2025. Por padrao, ele usa janeiro/2025, as aeronaves `2800`, `2803`, `2809` e `2811`, e grava:
|
||||||
|
|
||||||
|
```text
|
||||||
|
db/processed/resultado_oamrp_jan_2025.csv
|
||||||
|
```
|
||||||
|
|
||||||
|
Para executar:
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
python software/oamrp_v2.py
|
||||||
|
```
|
||||||
|
|
||||||
|
A rodada inicial de janeiro/2025 foi resolvida como otima pelo CBC, com 50 de 61 missoes cumpridas.
|
||||||
|
|||||||
62
db/processed/resultado_oamrp_jan_2025.csv
Normal file
62
db/processed/resultado_oamrp_jan_2025.csv
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
status,aeronave_modelo,ordem,id,om,orig,dest,partida_utc,chegada_utc,dur_h,prioridade,periodo,aeronave_real_2025,linhas_origem
|
||||||
|
cumprida,2800,1,RV2025_OM1_E1_L4_C4,1,SBMN,SBMY,2025-01-02T11:55:00Z,2025-01-02T13:05:00Z,1.17,1,NOTURNO,2809,4
|
||||||
|
cumprida,2800,2,RV2025_OM1_E2_L5_C5,1,SBMY,SBMN,2025-01-02T14:30:00Z,2025-01-02T15:35:00Z,1.08,1,NOTURNO,2809,5
|
||||||
|
cumprida,2800,3,RV2025_OM6_E1_L12_C12,6,SBMN,SBBV,2025-01-06T19:30:00Z,2025-01-06T21:25:00Z,1.92,1,DIURNO,2811,12
|
||||||
|
cumprida,2800,4,RV2025_OM6_E2_L14_C14,6,SBBV,SBMN,2025-01-07T11:20:00Z,2025-01-07T13:20:00Z,2.00,1,DIURNO,2811,14
|
||||||
|
cumprida,2800,5,RV2025_OM8_E1_L17_C17,8,SBMN,SBPV,2025-01-08T10:35:00Z,2025-01-08T12:35:00Z,2.00,1,DIURNO,2803,17
|
||||||
|
cumprida,2800,6,RV2025_OM8_E2_L18_C18,8,SBPV,SBMN,2025-01-08T14:00:00Z,2025-01-08T16:00:00Z,2.00,1,DIURNO,2803,18
|
||||||
|
cumprida,2800,7,RV2025_OM10_E1_L19_C19,10,SBMN,SBMN,2025-01-08T22:30:00Z,2025-01-08T23:15:00Z,0.75,1,NOTURNO,2803,19
|
||||||
|
cumprida,2800,8,RV2025_OM11_E1_L23_C23,11,SBMN,SWKO,2025-01-10T12:10:00Z,2025-01-10T13:15:00Z,1.08,1,DIURNO,2803,23
|
||||||
|
cumprida,2800,9,RV2025_OM11_E2_L24_C24,11,SWKO,SBMN,2025-01-10T14:25:00Z,2025-01-10T15:25:00Z,1.00,1,DIURNO,2803,24
|
||||||
|
cumprida,2800,10,RV2025_OM13_E1_L30_C30,13,SBMN,SWKO,2025-01-12T12:20:00Z,2025-01-12T13:10:00Z,0.83,1,DIURNO,2809,30
|
||||||
|
cumprida,2800,11,RV2025_OM13_E2_L31_C31,13,SWKO,SBMN,2025-01-12T14:40:00Z,2025-01-12T15:25:00Z,0.75,1,DIURNO,2809,31
|
||||||
|
cumprida,2800,12,RV2025_OM14_E1_L32_C32,14,SBMN,SBBE,2025-01-12T16:55:00Z,2025-01-12T20:25:00Z,3.50,1,DIURNO,2809,32
|
||||||
|
cumprida,2800,13,RV2025_OM14_E2_L33_C37,14,SBBE,SBMN,2025-01-12T22:45:00Z,2025-01-13T02:05:00Z,3.33,1,NOTURNO,2809,33;37
|
||||||
|
cumprida,2800,14,RV2025_OM16_E1_L38_C38,16,SBMN,SBTT,2025-01-15T12:00:00Z,2025-01-15T15:05:00Z,3.08,1,DIURNO,2803,38
|
||||||
|
cumprida,2800,15,RV2025_OM16_E2_L39_C39,16,SBTT,SBMN,2025-01-15T17:35:00Z,2025-01-15T20:35:00Z,3.00,1,DIURNO,2803,39
|
||||||
|
cumprida,2800,16,RV2025_OM17_E3_L42_C45,17,SBMN,SBMN,2025-01-15T22:50:00Z,2025-01-15T23:50:00Z,1.00,1,NOTURNO,2809,42;43;44;45
|
||||||
|
cumprida,2800,17,RV2025_OM18_E1_L46_C46,18,SBMN,SBSN,2025-01-21T12:05:00Z,2025-01-21T13:40:00Z,1.58,1,DIURNO,2800,46
|
||||||
|
cumprida,2800,18,RV2025_OM18_E2_L47_C47,18,SBSN,SBTS,2025-01-21T14:45:00Z,2025-01-21T16:15:00Z,1.50,1,DIURNO,2800,47
|
||||||
|
cumprida,2800,19,RV2025_OM18_E3_L48_C48,18,SBTS,SBMN,2025-01-21T18:40:00Z,2025-01-21T20:40:00Z,2.00,1,DIURNO,2800,48
|
||||||
|
cumprida,2800,20,RV2025_OM19_E1_L49_C49,19,SBMN,SBMN,2025-01-22T14:55:00Z,2025-01-22T16:00:00Z,1.08,1,DIURNO,2800,49
|
||||||
|
cumprida,2800,21,RV2025_OM21_E2_L54_C54,21,SBMN,SBMN,2025-01-22T20:50:00Z,2025-01-22T21:25:00Z,0.58,1,DIURNO,2809,54
|
||||||
|
cumprida,2800,22,RV2025_OM23_E1_L57_C57,23,SBMN,SBCZ,2025-01-24T12:10:00Z,2025-01-24T15:55:00Z,3.75,1,DIURNO,2800,57
|
||||||
|
cumprida,2800,23,RV2025_OM23_E2_L58_C58,23,SBCZ,SBMN,2025-01-24T17:05:00Z,2025-01-24T20:55:00Z,3.83,1,DIURNO,2800,58
|
||||||
|
cumprida,2800,24,RV2025_OM25_E1_L64_C64,25,SBMN,SBMN,2025-01-28T13:25:00Z,2025-01-28T14:30:00Z,1.08,1,DIURNO,2809,64
|
||||||
|
cumprida,2800,25,RV2025_OM26_E1_L65_C70,26,SBMN,SBMN,2025-01-28T23:10:00Z,2025-01-29T00:50:00Z,1.67,1,NOTURNO,2809,65;66;67;70
|
||||||
|
cumprida,2800,26,RV2025_OM28_E1_L71_C71,28,SBMN,SBMN,2025-01-29T18:15:00Z,2025-01-29T19:25:00Z,1.17,1,DIURNO,2809,71
|
||||||
|
cumprida,2803,1,RV2025_OM2_E3_L6_C6,2,SBMN,SBMY,2025-01-02T17:00:00Z,2025-01-02T18:05:00Z,1.08,1,NOTURNO,2809,6
|
||||||
|
cumprida,2803,2,RV2025_OM2_E4_L7_C7,2,SBMY,SBMN,2025-01-02T20:00:00Z,2025-01-02T21:10:00Z,1.17,1,NOTURNO,2809,7
|
||||||
|
cumprida,2803,3,RV2025_OM5_E1_L11_C11,5,SBMN,SBPV,2025-01-06T19:10:00Z,2025-01-06T21:20:00Z,2.17,1,DIURNO,2803,11
|
||||||
|
cumprida,2803,4,RV2025_OM5_E2_L13_C13,5,SBPV,SBMN,2025-01-07T14:15:00Z,2025-01-07T16:15:00Z,2.00,1,DIURNO,2803,13
|
||||||
|
cumprida,2803,5,RV2025_OM9_E1_L20_C20,9,SBMN,SBBE,2025-01-09T12:30:00Z,2025-01-09T15:55:00Z,3.42,1,DIURNO,2803,20
|
||||||
|
cumprida,2803,6,RV2025_OM9_E2_L21_C21,9,SBBE,SBSN,2025-01-09T18:10:00Z,2025-01-09T20:00:00Z,1.83,1,DIURNO,2803,21
|
||||||
|
cumprida,2803,7,RV2025_OM15_E2_L35_C35,15,SBSN,SBTS,2025-01-12T14:25:00Z,2025-01-12T16:00:00Z,1.58,1,DIURNO,2803,35
|
||||||
|
cumprida,2803,8,RV2025_OM15_E3_L36_C36,15,SBTS,SBMN,2025-01-12T18:30:00Z,2025-01-12T20:35:00Z,2.08,1,DIURNO,2803,36
|
||||||
|
cumprida,2803,9,RV2025_OM20_E1_L51_C51,20,SBMN,SBMN,2025-01-22T14:55:00Z,2025-01-22T16:00:00Z,1.08,1,DIURNO,2803,51
|
||||||
|
cumprida,2803,10,RV2025_OM20_E2_L52_C52,20,SBMN,SBMN,2025-01-22T20:50:00Z,2025-01-22T21:25:00Z,0.58,1,DIURNO,2803,52
|
||||||
|
cumprida,2803,11,RV2025_OM29_E1_L72_C72,29,SBMN,SBMN,2025-01-29T22:50:00Z,2025-01-30T00:00:00Z,1.17,1,NOTURNO,2809,72
|
||||||
|
cumprida,2809,1,RV2025_OM3_E1_L8_C8,3,SBMN,SBMN,2025-01-03T14:45:00Z,2025-01-03T16:10:00Z,1.42,1,DIURNO,2809,8
|
||||||
|
cumprida,2809,2,RV2025_OM17_E2_L41_C41,17,SBMN,SBMN,2025-01-15T14:45:00Z,2025-01-15T15:40:00Z,0.92,1,DIURNO,2809,41
|
||||||
|
cumprida,2809,3,RV2025_OM21_E1_L53_C53,21,SBMN,SBMN,2025-01-22T14:55:00Z,2025-01-22T16:00:00Z,1.08,1,DIURNO,2809,53
|
||||||
|
cumprida,2809,4,RV2025_OM19_E2_L50_C50,19,SBMN,SBMN,2025-01-22T20:50:00Z,2025-01-22T21:25:00Z,0.58,1,DIURNO,2800,50
|
||||||
|
cumprida,2809,5,RV2025_OM24_E1_L59_C59,24,SBMN,SNRH,2025-01-24T12:30:00Z,2025-01-24T15:35:00Z,3.08,1,DIURNO,2803,59
|
||||||
|
cumprida,2809,6,RV2025_OM24_E2_L60_C60,24,SNRH,SBTT,2025-01-24T16:45:00Z,2025-01-24T17:40:00Z,0.92,1,DIURNO,2803,60
|
||||||
|
cumprida,2809,7,RV2025_OM24_E3_L61_C61,24,SBTT,SWEI,2025-01-25T14:05:00Z,2025-01-25T14:50:00Z,0.75,1,DIURNO,2803,61
|
||||||
|
cumprida,2809,8,RV2025_OM24_E4_L62_C62,24,SWEI,SBTF,2025-01-25T16:45:00Z,2025-01-25T18:40:00Z,1.92,1,DIURNO,2803,62
|
||||||
|
cumprida,2811,1,RV2025_OM17_E1_L40_C40,17,SBMN,SBMN,2025-01-15T13:30:00Z,2025-01-15T14:25:00Z,0.92,1,DIURNO,2809,40
|
||||||
|
cumprida,2811,2,RV2025_OM22_E1_L55_C55,22,SBMN,SBMN,2025-01-22T14:55:00Z,2025-01-22T15:55:00Z,1.00,1,DIURNO,2811,55
|
||||||
|
cumprida,2811,3,RV2025_OM22_E2_L56_C56,22,SBMN,SBMN,2025-01-22T20:50:00Z,2025-01-22T21:25:00Z,0.58,1,DIURNO,2811,56
|
||||||
|
cumprida,2811,4,RV2025_OM27_E1_L68_C68,27,SBMN,SBMY,2025-01-28T12:05:00Z,2025-01-28T13:05:00Z,1.00,1,DIURNO,2803,68
|
||||||
|
cumprida,2811,5,RV2025_OM27_E2_L69_C69,27,SBMY,SBMN,2025-01-28T14:35:00Z,2025-01-28T15:30:00Z,0.92,1,DIURNO,2803,69
|
||||||
|
nao_cumprida,,,RV2025_OM4_E1_L9_C9,4,SBAN,SWBC,2025-01-06T12:40:00Z,2025-01-06T13:50:00Z,1.17,1,DIURNO,2803,9
|
||||||
|
nao_cumprida,,,RV2025_OM4_E2_L10_C10,4,SWBC,SBMN,2025-01-06T15:40:00Z,2025-01-06T16:45:00Z,1.08,1,DIURNO,2803,10
|
||||||
|
nao_cumprida,,,RV2025_OM7_E1_L15_C15,7,SBMN,SBBV,2025-01-07T10:40:00Z,2025-01-07T12:30:00Z,1.83,1,DIURNO,2809,15
|
||||||
|
nao_cumprida,,,RV2025_OM7_E2_L16_C16,7,SBMN,SBBV,2025-01-07T14:00:00Z,2025-01-07T15:45:00Z,1.75,1,DIURNO,2809,16
|
||||||
|
nao_cumprida,,,RV2025_OM9_E3_L22_C22,9,SBSN,SBMN,2025-01-09T20:40:00Z,2025-01-09T22:15:00Z,1.58,1,DIURNO,2803,22
|
||||||
|
nao_cumprida,,,RV2025_OM12_E1_L25_C25,12,SBMN,SBUA,2025-01-11T12:50:00Z,2025-01-11T15:00:00Z,2.17,1,DIURNO,2809,25
|
||||||
|
nao_cumprida,,,RV2025_OM12_E2_L26_C26,12,SBUA,SBYA,2025-01-11T17:20:00Z,2025-01-11T18:10:00Z,0.83,1,DIURNO,2809,26
|
||||||
|
nao_cumprida,,,RV2025_OM12_E3_L27_C27,12,SBYA,SBTT,2025-01-11T18:45:00Z,2025-01-11T20:10:00Z,1.42,1,DIURNO,2809,27
|
||||||
|
nao_cumprida,,,RV2025_OM12_E4_L28_C29,12,SBTT,SBTT,2025-01-11T21:05:00Z,2025-01-12T00:00:00Z,2.92,1,DIURNO;NOTURNO,2809,28;29
|
||||||
|
nao_cumprida,,,RV2025_OM15_E1_L34_C34,15,SBMN,SBSN,2025-01-12T11:50:00Z,2025-01-12T13:30:00Z,1.67,1,DIURNO,2803,34
|
||||||
|
nao_cumprida,,,RV2025_OM24_E5_L63_C63,24,SBTF,SBMN,2025-01-25T19:20:00Z,2025-01-25T21:00:00Z,1.67,1,DIURNO,2803,63
|
||||||
|
51
db/processed/resultado_oamrp_sintetico.csv
Normal file
51
db/processed/resultado_oamrp_sintetico.csv
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
status,aeronave,ordem,id,om,orig,dest,partida_utc,chegada_utc,dur_h,prioridade,periodo,aeronave_real_2025,linhas_origem
|
||||||
|
cumprida,2800,1,SIM_014_SBMN_SBTS,14,SBMN,SBTS,2025-01-11T09:41:20.400000Z,2025-01-11T12:08:20.400000Z,2.45,1,DIURNO,,
|
||||||
|
cumprida,2800,2,SIM_034_SBTS_SBMN,34,SBTS,SBMN,2025-01-23T00:14:45.600000Z,2025-01-23T02:54:57.600000Z,2.67,1,DIURNO,,
|
||||||
|
cumprida,2803,1,SIM_001_SBMN_SBMY,1,SBMN,SBMY,2025-01-01T02:22:55.200000Z,2025-01-01T03:09:07.200000Z,0.77,1,DIURNO,,
|
||||||
|
cumprida,2803,2,SIM_024_SBMY_SBBV,24,SBMY,SBBV,2025-01-17T22:04:04.800000Z,2025-01-18T00:30:28.800000Z,2.44,1,DIURNO,,
|
||||||
|
cumprida,2803,3,SIM_038_SBBV_SBBE,38,SBBV,SBBE,2025-01-23T23:08:38.400000Z,2025-01-24T02:18:50.400000Z,3.17,1,DIURNO,,
|
||||||
|
cumprida,2803,4,SIM_041_SBBE_SBTS,41,SBBE,SBTS,2025-01-24T12:09:03.600000Z,2025-01-24T17:48:03.600000Z,5.65,1,DIURNO,,
|
||||||
|
cumprida,2803,5,SIM_045_SBTS_SBMN,45,SBTS,SBMN,2025-01-28T01:21:25.200000Z,2025-01-28T03:43:01.200000Z,2.36,1,DIURNO,,
|
||||||
|
nao_cumprida,,,SIM_002_SBBE_SBTT,2,SBBE,SBTT,2025-01-03T00:34:55.200000Z,2025-01-03T04:33:07.200000Z,3.97,1,DIURNO,,
|
||||||
|
nao_cumprida,,,SIM_003_SBMN_SBPV,3,SBMN,SBPV,2025-01-04T06:06:21.600000Z,2025-01-04T07:48:57.600000Z,1.71,1,DIURNO,,
|
||||||
|
nao_cumprida,,,SIM_004_SBMN_SBUA,4,SBMN,SBUA,2025-01-04T12:04:51.600000Z,2025-01-04T13:55:51.600000Z,1.85,1,DIURNO,,
|
||||||
|
nao_cumprida,,,SIM_005_SBSN_SBTS,5,SBSN,SBTS,2025-01-05T05:32:09.600000Z,2025-01-05T09:50:09.600000Z,4.30,1,DIURNO,,
|
||||||
|
nao_cumprida,,,SIM_006_SBSN_SBBE,6,SBSN,SBBE,2025-01-05T06:29:20.400000Z,2025-01-05T08:16:44.400000Z,1.79,1,DIURNO,,
|
||||||
|
nao_cumprida,,,SIM_007_SBTS_SBMN,7,SBTS,SBMN,2025-01-05T08:52:04.800000Z,2025-01-05T11:40:04.800000Z,2.80,1,DIURNO,,
|
||||||
|
nao_cumprida,,,SIM_008_SBBE_SBTS,8,SBBE,SBTS,2025-01-05T16:11:09.600000Z,2025-01-05T21:53:09.600000Z,5.70,1,DIURNO,,
|
||||||
|
nao_cumprida,,,SIM_009_SBMY_SBTS,9,SBMY,SBTS,2025-01-05T20:05:16.800000Z,2025-01-05T22:20:52.800000Z,2.26,1,DIURNO,,
|
||||||
|
nao_cumprida,,,SIM_010_SBTT_SBMN,10,SBTT,SBMN,2025-01-05T21:25:37.200000Z,2025-01-05T22:33:25.200000Z,1.13,1,DIURNO,,
|
||||||
|
nao_cumprida,,,SIM_011_SBBE_SBSN,11,SBBE,SBSN,2025-01-07T12:04:04.800000Z,2025-01-07T13:40:40.800000Z,1.61,1,DIURNO,,
|
||||||
|
nao_cumprida,,,SIM_012_SWBC_SBSN,12,SWBC,SBSN,2025-01-08T16:32:16.800000Z,2025-01-08T18:52:40.800000Z,2.34,1,DIURNO,,
|
||||||
|
nao_cumprida,,,SIM_013_SBMN_SBBV,13,SBMN,SBBV,2025-01-09T23:25:44.400000Z,2025-01-10T01:05:20.400000Z,1.66,1,DIURNO,,
|
||||||
|
nao_cumprida,,,SIM_015_SBMN_SBPV,15,SBMN,SBPV,2025-01-12T01:42:18Z,2025-01-12T03:21:54Z,1.66,1,DIURNO,,
|
||||||
|
nao_cumprida,,,SIM_016_SBPV_SBMN,16,SBPV,SBMN,2025-01-12T18:25:08.400000Z,2025-01-12T20:11:56.400000Z,1.78,1,DIURNO,,
|
||||||
|
nao_cumprida,,,SIM_017_SBSN_SBMN,17,SBSN,SBMN,2025-01-13T06:27:18Z,2025-01-13T07:41:42Z,1.24,1,DIURNO,,
|
||||||
|
nao_cumprida,,,SIM_018_SBSN_SBBV,18,SBSN,SBBV,2025-01-14T02:28:12Z,2025-01-14T04:36:36Z,2.14,1,DIURNO,,
|
||||||
|
nao_cumprida,,,SIM_019_SBBV_SBMN,19,SBBV,SBMN,2025-01-15T07:32:56.400000Z,2025-01-15T09:12:32.400000Z,1.66,1,DIURNO,,
|
||||||
|
nao_cumprida,,,SIM_020_SWBC_SBTS,20,SWBC,SBTS,2025-01-16T02:14:27.600000Z,2025-01-16T04:25:51.600000Z,2.19,1,DIURNO,,
|
||||||
|
nao_cumprida,,,SIM_021_SBMN_SBPV,21,SBMN,SBPV,2025-01-16T06:26:09.600000Z,2025-01-16T08:12:21.600000Z,1.77,1,DIURNO,,
|
||||||
|
nao_cumprida,,,SIM_022_SBMN_SBBV,22,SBMN,SBBV,2025-01-16T12:38:16.800000Z,2025-01-16T14:04:40.800000Z,1.44,1,DIURNO,,
|
||||||
|
nao_cumprida,,,SIM_023_SBBV_SWBC,23,SBBV,SWBC,2025-01-17T11:36:32.400000Z,2025-01-17T12:47:20.400000Z,1.18,1,DIURNO,,
|
||||||
|
nao_cumprida,,,SIM_025_SWBC_SBMN,25,SWBC,SBMN,2025-01-18T08:18:36Z,2025-01-18T09:11:24Z,0.88,1,DIURNO,,
|
||||||
|
nao_cumprida,,,SIM_026_SBUA_SBTT,26,SBUA,SBTT,2025-01-18T20:18:46.800000Z,2025-01-18T21:21:10.800000Z,1.04,1,DIURNO,,
|
||||||
|
nao_cumprida,,,SIM_027_SBTS_SBMY,27,SBTS,SBMY,2025-01-19T05:22:55.200000Z,2025-01-19T07:42:07.200000Z,2.32,1,DIURNO,,
|
||||||
|
nao_cumprida,,,SIM_028_SBMN_SBTT,28,SBMN,SBTT,2025-01-19T05:45:50.400000Z,2025-01-19T07:06:14.400000Z,1.34,1,DIURNO,,
|
||||||
|
nao_cumprida,,,SIM_029_SBTT_SBSN,29,SBTT,SBSN,2025-01-20T02:58:12Z,2025-01-20T05:46:12Z,2.80,1,DIURNO,,
|
||||||
|
nao_cumprida,,,SIM_030_SWBC_SBSN,30,SWBC,SBSN,2025-01-20T15:51:10.800000Z,2025-01-20T18:05:34.800000Z,2.24,1,DIURNO,,
|
||||||
|
nao_cumprida,,,SIM_031_SBMN_SBTT,31,SBMN,SBTT,2025-01-21T19:19:40.800000Z,2025-01-21T20:35:52.800000Z,1.27,1,DIURNO,,
|
||||||
|
nao_cumprida,,,SIM_032_SBMN_SBBE,32,SBMN,SBBE,2025-01-21T19:28:22.800000Z,2025-01-21T22:36:46.800000Z,3.14,1,DIURNO,,
|
||||||
|
nao_cumprida,,,SIM_033_SBBV_SBSN,33,SBBV,SBSN,2025-01-22T22:56:56.400000Z,2025-01-23T00:56:56.400000Z,2.00,1,DIURNO,,
|
||||||
|
nao_cumprida,,,SIM_035_SBTT_SBMN,35,SBTT,SBMN,2025-01-23T02:00:57.600000Z,2025-01-23T03:12:21.600000Z,1.19,1,DIURNO,,
|
||||||
|
nao_cumprida,,,SIM_036_SBPV_SWBC,36,SBPV,SWBC,2025-01-23T18:49:19.200000Z,2025-01-23T21:00:07.200000Z,2.18,1,DIURNO,,
|
||||||
|
nao_cumprida,,,SIM_037_SBBV_SBMN,37,SBBV,SBMN,2025-01-23T20:18:28.800000Z,2025-01-23T21:50:52.800000Z,1.54,1,DIURNO,,
|
||||||
|
nao_cumprida,,,SIM_039_SBSN_SBMN,39,SBSN,SBMN,2025-01-24T02:44:38.400000Z,2025-01-24T03:59:02.400000Z,1.24,1,DIURNO,,
|
||||||
|
nao_cumprida,,,SIM_040_SBSN_SBMN,40,SBSN,SBMN,2025-01-24T07:16:48Z,2025-01-24T08:30:36Z,1.23,1,DIURNO,,
|
||||||
|
nao_cumprida,,,SIM_042_SBBE_SBSN,42,SBBE,SBSN,2025-01-25T14:54:14.400000Z,2025-01-25T16:35:02.400000Z,1.68,1,DIURNO,,
|
||||||
|
nao_cumprida,,,SIM_043_SBMN_SBPV,43,SBMN,SBPV,2025-01-26T17:47:06Z,2025-01-26T19:21:54Z,1.58,1,DIURNO,,
|
||||||
|
nao_cumprida,,,SIM_044_SBBE_SBPV,44,SBBE,SBPV,2025-01-27T08:03:00Z,2025-01-27T12:37:48Z,4.58,1,DIURNO,,
|
||||||
|
nao_cumprida,,,SIM_046_SBMN_SBUA,46,SBMN,SBUA,2025-01-28T01:26:06Z,2025-01-28T03:14:42Z,1.81,1,DIURNO,,
|
||||||
|
nao_cumprida,,,SIM_047_SWBC_SBTS,47,SWBC,SBTS,2025-01-28T22:14:31.200000Z,2025-01-29T00:03:07.200000Z,1.81,1,DIURNO,,
|
||||||
|
nao_cumprida,,,SIM_048_SBSN_SBUA,48,SBSN,SBUA,2025-01-29T19:44:38.400000Z,2025-01-29T22:51:14.400000Z,3.11,1,DIURNO,,
|
||||||
|
nao_cumprida,,,SIM_049_SBMN_SBMY,49,SBMN,SBMY,2025-01-30T17:21:57.600000Z,2025-01-30T18:08:09.600000Z,0.77,1,DIURNO,,
|
||||||
|
nao_cumprida,,,SIM_050_SBTT_SBPV,50,SBTT,SBPV,2025-01-31T12:02:13.200000Z,2025-01-31T13:22:01.200000Z,1.33,1,DIURNO,,
|
||||||
|
51
db/processed/resultado_oamrp_v3.csv
Normal file
51
db/processed/resultado_oamrp_v3.csv
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
status,aeronave,ordem,id,om,orig,dest,partida_utc,chegada_utc,dur_h,prioridade,periodo,aeronave_real_2025,linhas_origem
|
||||||
|
cumprida,2800,1,RV2025_OM1_E2_L5_C5,1,SBMN,SBMN,2025-01-02T14:30:00Z,2025-01-02T15:35:00Z,1.08,1,NOTURNO,2809,5
|
||||||
|
cumprida,2800,2,RV2025_OM5_E2_L13_C13,5,SBMN,SBMN,2025-01-07T14:15:00Z,2025-01-07T16:15:00Z,2.00,1,DIURNO,2803,13
|
||||||
|
cumprida,2803,1,RV2025_OM7_E1_L15_C15,7,SBMN,SBMN,2025-01-07T10:40:00Z,2025-01-07T12:30:00Z,1.83,1,DIURNO,2809,15
|
||||||
|
cumprida,2803,2,RV2025_OM8_E1_L17_C17,8,SBMN,SBMN,2025-01-08T10:35:00Z,2025-01-08T12:35:00Z,2.00,1,DIURNO,2803,17
|
||||||
|
cumprida,2803,3,RV2025_OM12_E4_L28_C29,12,SBMN,SBMN,2025-01-11T21:05:00Z,2025-01-12T00:00:00Z,2.92,1,DIURNO;NOTURNO,2809,28;29
|
||||||
|
cumprida,2803,4,RV2025_OM15_E1_L34_C34,15,SBMN,SBMN,2025-01-12T11:50:00Z,2025-01-12T13:30:00Z,1.67,1,DIURNO,2803,34
|
||||||
|
cumprida,2809,1,RV2025_OM1_E1_L4_C4,1,SBMN,SBMN,2025-01-02T11:55:00Z,2025-01-02T13:05:00Z,1.17,1,NOTURNO,2809,4
|
||||||
|
cumprida,2811,1,RV2025_OM3_E1_L8_C8,3,SBMN,SBMN,2025-01-03T14:45:00Z,2025-01-03T16:10:00Z,1.42,1,DIURNO,2809,8
|
||||||
|
cumprida,2811,2,RV2025_OM4_E2_L10_C10,4,SBMN,SBMN,2025-01-06T15:40:00Z,2025-01-06T16:45:00Z,1.08,1,DIURNO,2803,10
|
||||||
|
cumprida,2811,3,RV2025_OM9_E1_L20_C20,9,SBMN,SBMN,2025-01-09T12:30:00Z,2025-01-09T15:55:00Z,3.42,1,DIURNO,2803,20
|
||||||
|
cumprida,2811,4,RV2025_OM9_E3_L22_C22,9,SBMN,SBMN,2025-01-09T20:40:00Z,2025-01-09T22:15:00Z,1.58,1,DIURNO,2803,22
|
||||||
|
cumprida,2811,5,RV2025_OM14_E1_L32_C32,14,SBMN,SBMN,2025-01-12T16:55:00Z,2025-01-12T20:25:00Z,3.50,1,DIURNO,2809,32
|
||||||
|
cumprida,2811,6,RV2025_OM17_E1_L40_C40,17,SBMN,SBMN,2025-01-15T13:30:00Z,2025-01-15T14:25:00Z,0.92,1,DIURNO,2809,40
|
||||||
|
cumprida,2811,7,RV2025_OM17_E3_L42_C45,17,SBMN,SBMN,2025-01-15T22:50:00Z,2025-01-15T23:50:00Z,1.00,1,NOTURNO,2809,42;43;44;45
|
||||||
|
nao_cumprida,,,RV2025_OM2_E3_L6_C6,2,SBMN,SBMN,2025-01-02T17:00:00Z,2025-01-02T18:05:00Z,1.08,1,NOTURNO,2809,6
|
||||||
|
nao_cumprida,,,RV2025_OM2_E4_L7_C7,2,SBMN,SBMN,2025-01-02T20:00:00Z,2025-01-02T21:10:00Z,1.17,1,NOTURNO,2809,7
|
||||||
|
nao_cumprida,,,RV2025_OM5_E1_L11_C11,5,SBMN,SBMN,2025-01-06T19:10:00Z,2025-01-06T21:20:00Z,2.17,1,DIURNO,2803,11
|
||||||
|
nao_cumprida,,,RV2025_OM6_E1_L12_C12,6,SBMN,SBMN,2025-01-06T19:30:00Z,2025-01-06T21:25:00Z,1.92,1,DIURNO,2811,12
|
||||||
|
nao_cumprida,,,RV2025_OM6_E2_L14_C14,6,SBMN,SBMN,2025-01-07T11:20:00Z,2025-01-07T13:20:00Z,2.00,1,DIURNO,2811,14
|
||||||
|
nao_cumprida,,,RV2025_OM7_E2_L16_C16,7,SBMN,SBMN,2025-01-07T14:00:00Z,2025-01-07T15:45:00Z,1.75,1,DIURNO,2809,16
|
||||||
|
nao_cumprida,,,RV2025_OM8_E2_L18_C18,8,SBMN,SBMN,2025-01-08T14:00:00Z,2025-01-08T16:00:00Z,2.00,1,DIURNO,2803,18
|
||||||
|
nao_cumprida,,,RV2025_OM10_E1_L19_C19,10,SBMN,SBMN,2025-01-08T22:30:00Z,2025-01-08T23:15:00Z,0.75,1,NOTURNO,2803,19
|
||||||
|
nao_cumprida,,,RV2025_OM9_E2_L21_C21,9,SBMN,SBMN,2025-01-09T18:10:00Z,2025-01-09T20:00:00Z,1.83,1,DIURNO,2803,21
|
||||||
|
nao_cumprida,,,RV2025_OM11_E1_L23_C23,11,SBMN,SBMN,2025-01-10T12:10:00Z,2025-01-10T13:15:00Z,1.08,1,DIURNO,2803,23
|
||||||
|
nao_cumprida,,,RV2025_OM11_E2_L24_C24,11,SBMN,SBMN,2025-01-10T14:25:00Z,2025-01-10T15:25:00Z,1.00,1,DIURNO,2803,24
|
||||||
|
nao_cumprida,,,RV2025_OM13_E1_L30_C30,13,SBMN,SBMN,2025-01-12T12:20:00Z,2025-01-12T13:10:00Z,0.83,1,DIURNO,2809,30
|
||||||
|
nao_cumprida,,,RV2025_OM15_E2_L35_C35,15,SBMN,SBMN,2025-01-12T14:25:00Z,2025-01-12T16:00:00Z,1.58,1,DIURNO,2803,35
|
||||||
|
nao_cumprida,,,RV2025_OM13_E2_L31_C31,13,SBMN,SBMN,2025-01-12T14:40:00Z,2025-01-12T15:25:00Z,0.75,1,DIURNO,2809,31
|
||||||
|
nao_cumprida,,,RV2025_OM15_E3_L36_C36,15,SBMN,SBMN,2025-01-12T18:30:00Z,2025-01-12T20:35:00Z,2.08,1,DIURNO,2803,36
|
||||||
|
nao_cumprida,,,RV2025_OM14_E2_L33_C37,14,SBMN,SBMN,2025-01-12T22:45:00Z,2025-01-13T02:05:00Z,3.33,1,NOTURNO,2809,33;37
|
||||||
|
nao_cumprida,,,RV2025_OM16_E1_L38_C38,16,SBMN,SBMN,2025-01-15T12:00:00Z,2025-01-15T15:05:00Z,3.08,1,DIURNO,2803,38
|
||||||
|
nao_cumprida,,,RV2025_OM17_E2_L41_C41,17,SBMN,SBMN,2025-01-15T14:45:00Z,2025-01-15T15:40:00Z,0.92,1,DIURNO,2809,41
|
||||||
|
nao_cumprida,,,RV2025_OM16_E2_L39_C39,16,SBMN,SBMN,2025-01-15T17:35:00Z,2025-01-15T20:35:00Z,3.00,1,DIURNO,2803,39
|
||||||
|
nao_cumprida,,,RV2025_OM18_E1_L46_C46,18,SBMN,SBMN,2025-01-21T12:05:00Z,2025-01-21T13:40:00Z,1.58,1,DIURNO,2800,46
|
||||||
|
nao_cumprida,,,RV2025_OM18_E2_L47_C47,18,SBMN,SBMN,2025-01-21T14:45:00Z,2025-01-21T16:15:00Z,1.50,1,DIURNO,2800,47
|
||||||
|
nao_cumprida,,,RV2025_OM18_E3_L48_C48,18,SBMN,SBMN,2025-01-21T18:40:00Z,2025-01-21T20:40:00Z,2.00,1,DIURNO,2800,48
|
||||||
|
nao_cumprida,,,RV2025_OM19_E1_L49_C49,19,SBMN,SBMN,2025-01-22T14:55:00Z,2025-01-22T16:00:00Z,1.08,1,DIURNO,2800,49
|
||||||
|
nao_cumprida,,,RV2025_OM20_E1_L51_C51,20,SBMN,SBMN,2025-01-22T14:55:00Z,2025-01-22T16:00:00Z,1.08,1,DIURNO,2803,51
|
||||||
|
nao_cumprida,,,RV2025_OM21_E1_L53_C53,21,SBMN,SBMN,2025-01-22T14:55:00Z,2025-01-22T16:00:00Z,1.08,1,DIURNO,2809,53
|
||||||
|
nao_cumprida,,,RV2025_OM22_E1_L55_C55,22,SBMN,SBMN,2025-01-22T14:55:00Z,2025-01-22T15:55:00Z,1.00,1,DIURNO,2811,55
|
||||||
|
nao_cumprida,,,RV2025_OM19_E2_L50_C50,19,SBMN,SBMN,2025-01-22T20:50:00Z,2025-01-22T21:25:00Z,0.58,1,DIURNO,2800,50
|
||||||
|
nao_cumprida,,,RV2025_OM20_E2_L52_C52,20,SBMN,SBMN,2025-01-22T20:50:00Z,2025-01-22T21:25:00Z,0.58,1,DIURNO,2803,52
|
||||||
|
nao_cumprida,,,RV2025_OM21_E2_L54_C54,21,SBMN,SBMN,2025-01-22T20:50:00Z,2025-01-22T21:25:00Z,0.58,1,DIURNO,2809,54
|
||||||
|
nao_cumprida,,,RV2025_OM22_E2_L56_C56,22,SBMN,SBMN,2025-01-22T20:50:00Z,2025-01-22T21:25:00Z,0.58,1,DIURNO,2811,56
|
||||||
|
nao_cumprida,,,RV2025_OM27_E1_L68_C68,27,SBMN,SBMN,2025-01-28T12:05:00Z,2025-01-28T13:05:00Z,1.00,1,DIURNO,2803,68
|
||||||
|
nao_cumprida,,,RV2025_OM25_E1_L64_C64,25,SBMN,SBMN,2025-01-28T13:25:00Z,2025-01-28T14:30:00Z,1.08,1,DIURNO,2809,64
|
||||||
|
nao_cumprida,,,RV2025_OM27_E2_L69_C69,27,SBMN,SBMN,2025-01-28T14:35:00Z,2025-01-28T15:30:00Z,0.92,1,DIURNO,2803,69
|
||||||
|
nao_cumprida,,,RV2025_OM26_E1_L65_C70,26,SBMN,SBMN,2025-01-28T23:10:00Z,2025-01-29T00:50:00Z,1.67,1,NOTURNO,2809,65;66;67;70
|
||||||
|
nao_cumprida,,,RV2025_OM28_E1_L71_C71,28,SBMN,SBMN,2025-01-29T18:15:00Z,2025-01-29T19:25:00Z,1.17,1,DIURNO,2809,71
|
||||||
|
nao_cumprida,,,RV2025_OM29_E1_L72_C72,29,SBMN,SBMN,2025-01-29T22:50:00Z,2025-01-30T00:00:00Z,1.17,1,NOTURNO,2809,72
|
||||||
|
@@ -172,3 +172,30 @@ O relatorio de validacao esta em:
|
|||||||
```text
|
```text
|
||||||
db/pre_process/registro_voo_2025/validacao_registro_voo_2025.md
|
db/pre_process/registro_voo_2025/validacao_registro_voo_2025.md
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Modelo OAMRP v2
|
||||||
|
|
||||||
|
O arquivo `software/oamrp_v2.py` e a primeira versao do modelo usando o registro de voo 2025 consolidado.
|
||||||
|
|
||||||
|
Entradas principais:
|
||||||
|
|
||||||
|
- `db/processed/registro_voo_2025_consolidado.csv`;
|
||||||
|
- janela padrao de `2025-01-01` ate `2025-02-01` exclusivo;
|
||||||
|
- aeronaves reais `2800`, `2803`, `2809` e `2811`;
|
||||||
|
- base inicial provisoria `SBMN`;
|
||||||
|
- base de manutencao `SBMN`;
|
||||||
|
- prioridade uniforme: todas as missoes recebem peso 1.
|
||||||
|
|
||||||
|
Saida principal:
|
||||||
|
|
||||||
|
```text
|
||||||
|
db/processed/resultado_oamrp_jan_2025.csv
|
||||||
|
```
|
||||||
|
|
||||||
|
Resultado da primeira execucao:
|
||||||
|
|
||||||
|
- status do solver: `Optimal`;
|
||||||
|
- missoes cumpridas: 50/61;
|
||||||
|
- prioridade obtida: 50/61.
|
||||||
|
|
||||||
|
Limitacao atual: o limite de horas foi deixado alto para validar primeiro a continuidade espacial/temporal. A calibracao com dados reais de manutencao ainda deve ser feita em etapa posterior.
|
||||||
|
|||||||
@@ -86,3 +86,52 @@ Formato:
|
|||||||
### Observacoes
|
### Observacoes
|
||||||
|
|
||||||
- A remocao foi aplicada no script de pre-processamento para manter reprodutibilidade.
|
- A remocao foi aplicada no script de pre-processamento para manter reprodutibilidade.
|
||||||
|
|
||||||
|
## v0.6 - VTO - 2026-06
|
||||||
|
|
||||||
|
### Adicionado
|
||||||
|
|
||||||
|
- Gerador de missões sintéticas cross-base (`gerar_missoes_sinteticas()`): 50 missões entre 10 bases com durações calculadas via haversine ÷ velocidade C-105 (430 km/h); flag `--sintetico`, `--n-missoes`, `--n-evam` na CLI.
|
||||||
|
- Fase 3: arcos de ferry em `construir_rede()` — arcos `inicio`, `missao_missao`, `missao_insp` e `insp_missao` agora permitem bases distintas com tempo de ferry calculado automaticamente.
|
||||||
|
- Ferry consome horas de célula no relógio de inspeção (C6: `carga = v.carga_h + a.horas_ferry`).
|
||||||
|
- Relatório imprime segmentos `[FERRY base1->base2 Xh]` na linha do tempo de cada aeronave.
|
||||||
|
- Resultado `db/processed/resultado_oamrp_sintetico.csv` para 50 missões sintéticas.
|
||||||
|
|
||||||
|
### Alterado
|
||||||
|
|
||||||
|
- Dicionário `BASES_COORDS` com coordenadas (lat, lon) das 10 bases operacionais do C-105.
|
||||||
|
|
||||||
|
## v0.5 - VTO - 2026-06
|
||||||
|
|
||||||
|
### Adicionado
|
||||||
|
|
||||||
|
- Modelo `software/oamrp_v3.py` — reescrita do zero com rede espaço-tempo (No/Arco) e variável unificada `y[k,arco]`.
|
||||||
|
- Fase 1 (C1–C6): fluxo de conservação, cobertura de missões, restrição de voo ativo, orçamento de horas por inspeção.
|
||||||
|
- Fase 2 (C7–C11): nós e arcos de inspeção na rede; variáveis `H[k,i,nid]` para relógio de horas com reset; C9 downtime; C11 slot único via variáveis disjuntivas `oo`.
|
||||||
|
- Documento `HANDOFF_arara_oamrp.md` com formulação matemática, decisões de calibração (Q1–Q5) e plano de build incremental.
|
||||||
|
- Resultado `db/processed/resultado_oamrp_v3.csv` para janeiro/2025.
|
||||||
|
|
||||||
|
### Alterado
|
||||||
|
|
||||||
|
- TAT corrigido para 1,5h (era 1,0h em v2).
|
||||||
|
- Top-10 bases por frequência no registro de voo 2025 (Q4).
|
||||||
|
- Missões EVAM marcadas como obrigatórias (Q2).
|
||||||
|
- Objetivo L2 definido como maximizar horas voadas (= minimizar folga ao fim do horizonte mensal) (Q3).
|
||||||
|
|
||||||
|
### Corrigido
|
||||||
|
|
||||||
|
- Bug de escopo de arco: arcos de início/fim agora carregam `aeronave_id` e só entram na variável `y` do aircraft correto.
|
||||||
|
- Bug `NameError tat_h` em C9b: substituído pela constante global `TAT_H`.
|
||||||
|
- Bug `AttributeError` em `escrever_resultado`: filtro por `n.tipo == "missao"` antes de acessar `n.missao`.
|
||||||
|
|
||||||
|
## v0.4 - VTO - 2026-06
|
||||||
|
|
||||||
|
### Adicionado
|
||||||
|
|
||||||
|
- Modelo `software/oamrp_v2.py` para rodar o OAMRP com o registro de voo 2025 consolidado.
|
||||||
|
- Resultado inicial `db/processed/resultado_oamrp_jan_2025.csv`.
|
||||||
|
|
||||||
|
### Observacoes
|
||||||
|
|
||||||
|
- Rodada padrao usa janeiro/2025, aeronaves reais `2800`, `2803`, `2809` e `2811`, base inicial provisoria `SBMN`, base de manutencao `SBMN` e prioridade uniforme 1.
|
||||||
|
- Primeira execucao retornou solucao otima com 50 de 61 missoes cumpridas.
|
||||||
|
|||||||
375
software/oamrp_v2.py
Normal file
375
software/oamrp_v2.py
Normal file
@@ -0,0 +1,375 @@
|
|||||||
|
"""
|
||||||
|
============================================================================
|
||||||
|
AIRCRAFT ROUTING - ESQUADRAO ARARA - V2
|
||||||
|
============================================================================
|
||||||
|
Primeira versao do modelo OAMRP usando dados reais pre-processados do
|
||||||
|
registro de voo 2025.
|
||||||
|
|
||||||
|
Diferencas em relacao ao v1:
|
||||||
|
- le o CSV consolidado gerado a partir da Planilha 2025;
|
||||||
|
- filtra uma janela de datas, com janeiro/2025 como padrao;
|
||||||
|
- usa aeronaves reais observadas no registro: 2800, 2803, 2809 e 2811;
|
||||||
|
- gera um CSV de resultado em db/processed/.
|
||||||
|
|
||||||
|
Esta versao ainda e uma rodada exploratoria. Todas as missoes recebem
|
||||||
|
prioridade 1 e a base de manutencao considerada e SBMN.
|
||||||
|
============================================================================
|
||||||
|
"""
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import argparse
|
||||||
|
import csv
|
||||||
|
from dataclasses import dataclass
|
||||||
|
from datetime import datetime, timezone
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
import pulp
|
||||||
|
|
||||||
|
|
||||||
|
BASE_DIR = Path(__file__).resolve().parents[1]
|
||||||
|
CSV_REGISTRO_PADRAO = BASE_DIR / "db" / "processed" / "registro_voo_2025_consolidado.csv"
|
||||||
|
CSV_RESULTADO_PADRAO = BASE_DIR / "db" / "processed" / "resultado_oamrp_jan_2025.csv"
|
||||||
|
|
||||||
|
DATA_INICIO_PADRAO = "2025-01-01"
|
||||||
|
DATA_FIM_PADRAO = "2025-02-01" # exclusivo
|
||||||
|
|
||||||
|
BASE_MANUTENCAO = "SBMN"
|
||||||
|
BASE_INICIAL = BASE_MANUTENCAO
|
||||||
|
TURNAROUND_MIN_H = 1.0
|
||||||
|
LIMITE_HORAS_F = 300.0
|
||||||
|
PRIORIDADE_PADRAO = 1
|
||||||
|
|
||||||
|
AERONAVES = [
|
||||||
|
# id base inicial horas acumuladas desde ultima inspecao
|
||||||
|
("2800", BASE_INICIAL, 0.0),
|
||||||
|
("2803", BASE_INICIAL, 0.0),
|
||||||
|
("2809", BASE_INICIAL, 0.0),
|
||||||
|
("2811", BASE_INICIAL, 0.0),
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass(frozen=True)
|
||||||
|
class Missao:
|
||||||
|
id: str
|
||||||
|
orig: str
|
||||||
|
dest: str
|
||||||
|
partida_utc: datetime
|
||||||
|
chegada_utc: datetime
|
||||||
|
prioridade: int
|
||||||
|
periodo: str
|
||||||
|
linhas_origem: str
|
||||||
|
aeronave_real: str
|
||||||
|
om: str
|
||||||
|
|
||||||
|
@property
|
||||||
|
def dur_h(self) -> float:
|
||||||
|
return (self.chegada_utc - self.partida_utc).total_seconds() / 3600
|
||||||
|
|
||||||
|
|
||||||
|
def parse_utc(valor: str) -> datetime:
|
||||||
|
texto = str(valor).strip()
|
||||||
|
if texto.endswith("Z"):
|
||||||
|
texto = texto[:-1] + "+00:00"
|
||||||
|
dt = datetime.fromisoformat(texto)
|
||||||
|
if dt.tzinfo is None:
|
||||||
|
dt = dt.replace(tzinfo=timezone.utc)
|
||||||
|
return dt.astimezone(timezone.utc)
|
||||||
|
|
||||||
|
|
||||||
|
def parse_data_inicio(valor: str) -> datetime:
|
||||||
|
return datetime.fromisoformat(valor).replace(tzinfo=timezone.utc)
|
||||||
|
|
||||||
|
|
||||||
|
def carregar_missoes(caminho: Path, inicio: datetime, fim: datetime) -> list[Missao]:
|
||||||
|
missoes: list[Missao] = []
|
||||||
|
with caminho.open(newline="", encoding="utf-8-sig") as arquivo:
|
||||||
|
leitor = csv.DictReader(arquivo)
|
||||||
|
for linha in leitor:
|
||||||
|
partida = parse_utc(linha["partida_utc"])
|
||||||
|
chegada = parse_utc(linha["chegada_utc"])
|
||||||
|
if not (inicio <= partida < fim):
|
||||||
|
continue
|
||||||
|
if chegada <= partida:
|
||||||
|
raise ValueError(f"Missao {linha['id_registro']}: chegada antes da partida")
|
||||||
|
missoes.append(
|
||||||
|
Missao(
|
||||||
|
id=linha["id_registro"],
|
||||||
|
orig=linha["localidade_dep"],
|
||||||
|
dest=linha["localidade_arr"],
|
||||||
|
partida_utc=partida,
|
||||||
|
chegada_utc=chegada,
|
||||||
|
prioridade=PRIORIDADE_PADRAO,
|
||||||
|
periodo=linha.get("periodo", ""),
|
||||||
|
linhas_origem=linha.get("linhas_origem", ""),
|
||||||
|
aeronave_real=linha.get("aeronave", ""),
|
||||||
|
om=linha.get("om", ""),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
return sorted(missoes, key=lambda m: (m.partida_utc, m.id))
|
||||||
|
|
||||||
|
|
||||||
|
def horas_relativas(missoes: list[Missao]) -> tuple[dict[str, dict[str, object]], datetime]:
|
||||||
|
horizonte_inicio = min(m.partida_utc for m in missoes)
|
||||||
|
dados = {}
|
||||||
|
for missao in missoes:
|
||||||
|
dados[missao.id] = {
|
||||||
|
"orig": missao.orig,
|
||||||
|
"dest": missao.dest,
|
||||||
|
"part": (missao.partida_utc - horizonte_inicio).total_seconds() / 3600,
|
||||||
|
"cheg": (missao.chegada_utc - horizonte_inicio).total_seconds() / 3600,
|
||||||
|
"prio": missao.prioridade,
|
||||||
|
"dur": missao.dur_h,
|
||||||
|
"obj": missao,
|
||||||
|
}
|
||||||
|
return dados, horizonte_inicio
|
||||||
|
|
||||||
|
|
||||||
|
def resolver(missoes: list[Missao]) -> dict[str, object]:
|
||||||
|
if not missoes:
|
||||||
|
raise ValueError("Nenhuma missao encontrada na janela informada")
|
||||||
|
|
||||||
|
miss, horizonte_inicio = horas_relativas(missoes)
|
||||||
|
acft = {a[0]: {"base": a[1], "f": a[2]} for a in AERONAVES}
|
||||||
|
ids = list(miss.keys())
|
||||||
|
ks = list(acft.keys())
|
||||||
|
|
||||||
|
conex = [
|
||||||
|
(i, j)
|
||||||
|
for i in ids
|
||||||
|
for j in ids
|
||||||
|
if i != j
|
||||||
|
and miss[i]["dest"] == miss[j]["orig"]
|
||||||
|
and miss[j]["part"] >= miss[i]["cheg"] + TURNAROUND_MIN_H
|
||||||
|
]
|
||||||
|
|
||||||
|
def pode_iniciar(k: str, i: str) -> bool:
|
||||||
|
return miss[i]["orig"] == acft[k]["base"]
|
||||||
|
|
||||||
|
mdl = pulp.LpProblem("ARARA_OAMRP_v2", pulp.LpMaximize)
|
||||||
|
|
||||||
|
x = {(k, i): pulp.LpVariable(f"x_{k}_{i}", cat="Binary") for k in ks for i in ids}
|
||||||
|
s = {
|
||||||
|
(k, i): pulp.LpVariable(f"s_{k}_{i}", cat="Binary")
|
||||||
|
for k in ks
|
||||||
|
for i in ids
|
||||||
|
if pode_iniciar(k, i)
|
||||||
|
}
|
||||||
|
c = {
|
||||||
|
(k, i, j): pulp.LpVariable(f"c_{k}_{i}_{j}", cat="Binary")
|
||||||
|
for k in ks
|
||||||
|
for (i, j) in conex
|
||||||
|
}
|
||||||
|
z = {i: pulp.LpVariable(f"z_{i}", cat="Binary") for i in ids}
|
||||||
|
|
||||||
|
mdl += pulp.lpSum(miss[i]["prio"] * z[i] for i in ids), "missoes_cumpridas_ponderadas"
|
||||||
|
|
||||||
|
for i in ids:
|
||||||
|
mdl += z[i] == pulp.lpSum(x[(k, i)] for k in ks), f"def_z_{i}"
|
||||||
|
|
||||||
|
for k in ks:
|
||||||
|
for i in ids:
|
||||||
|
entradas = pulp.lpSum(c[(k, jj, i)] for (jj, ii) in conex if ii == i)
|
||||||
|
inicio = s[(k, i)] if (k, i) in s else 0
|
||||||
|
mdl += inicio + entradas == x[(k, i)], f"in_{k}_{i}"
|
||||||
|
|
||||||
|
for k in ks:
|
||||||
|
for i in ids:
|
||||||
|
saidas = pulp.lpSum(c[(k, i, jj)] for (ii, jj) in conex if ii == i)
|
||||||
|
mdl += saidas <= x[(k, i)], f"out_{k}_{i}"
|
||||||
|
|
||||||
|
for k in ks:
|
||||||
|
inicios = [s[(k, i)] for i in ids if (k, i) in s]
|
||||||
|
if inicios:
|
||||||
|
mdl += pulp.lpSum(inicios) <= 1, f"start_{k}"
|
||||||
|
|
||||||
|
for k in ks:
|
||||||
|
mdl += (
|
||||||
|
pulp.lpSum(miss[i]["dur"] * x[(k, i)] for i in ids)
|
||||||
|
<= LIMITE_HORAS_F - acft[k]["f"]
|
||||||
|
), f"horas_{k}"
|
||||||
|
|
||||||
|
solver = pulp.PULP_CBC_CMD(msg=False)
|
||||||
|
mdl.solve(solver)
|
||||||
|
prio_otima = int(round(pulp.value(mdl.objective) or 0))
|
||||||
|
|
||||||
|
# Criterio secundario: entre solucoes com a mesma prioridade, minimiza horas
|
||||||
|
# totais atribuidas. Neste v2 isso evita voos extras irrelevantes se houver
|
||||||
|
# empate em prioridade.
|
||||||
|
mdl += pulp.lpSum(miss[i]["prio"] * z[i] for i in ids) == prio_otima, "fixa_prioridade"
|
||||||
|
mdl.sense = pulp.LpMinimize
|
||||||
|
mdl.setObjective(pulp.lpSum(miss[i]["dur"] * x[(k, i)] for k in ks for i in ids))
|
||||||
|
mdl.solve(solver)
|
||||||
|
|
||||||
|
return {
|
||||||
|
"modelo": mdl,
|
||||||
|
"miss": miss,
|
||||||
|
"acft": acft,
|
||||||
|
"ids": ids,
|
||||||
|
"ks": ks,
|
||||||
|
"conex": conex,
|
||||||
|
"x": x,
|
||||||
|
"s": s,
|
||||||
|
"c": c,
|
||||||
|
"z": z,
|
||||||
|
"horizonte_inicio": horizonte_inicio,
|
||||||
|
"prioridade_otima": prio_otima,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def rota_da_aeronave(sol: dict[str, object], k: str) -> list[str]:
|
||||||
|
ids = sol["ids"]
|
||||||
|
conex = sol["conex"]
|
||||||
|
s = sol["s"]
|
||||||
|
c = sol["c"]
|
||||||
|
inicio = [
|
||||||
|
i
|
||||||
|
for i in ids
|
||||||
|
if (k, i) in s and s[(k, i)].value() is not None and s[(k, i)].value() > 0.5
|
||||||
|
]
|
||||||
|
if not inicio:
|
||||||
|
return []
|
||||||
|
|
||||||
|
seq = [inicio[0]]
|
||||||
|
while True:
|
||||||
|
atual = seq[-1]
|
||||||
|
prox = [
|
||||||
|
j
|
||||||
|
for (ii, j) in conex
|
||||||
|
if ii == atual and c[(k, atual, j)].value() is not None and c[(k, atual, j)].value() > 0.5
|
||||||
|
]
|
||||||
|
if not prox:
|
||||||
|
break
|
||||||
|
seq.append(prox[0])
|
||||||
|
return seq
|
||||||
|
|
||||||
|
|
||||||
|
def escrever_resultado(sol: dict[str, object], caminho: Path) -> None:
|
||||||
|
caminho.parent.mkdir(parents=True, exist_ok=True)
|
||||||
|
miss = sol["miss"]
|
||||||
|
z = sol["z"]
|
||||||
|
linhas = []
|
||||||
|
for k in sol["ks"]:
|
||||||
|
for ordem, mid in enumerate(rota_da_aeronave(sol, k), start=1):
|
||||||
|
obj = miss[mid]["obj"]
|
||||||
|
linhas.append(
|
||||||
|
{
|
||||||
|
"aeronave_modelo": k,
|
||||||
|
"ordem": ordem,
|
||||||
|
"id": mid,
|
||||||
|
"om": obj.om,
|
||||||
|
"orig": obj.orig,
|
||||||
|
"dest": obj.dest,
|
||||||
|
"partida_utc": obj.partida_utc.isoformat().replace("+00:00", "Z"),
|
||||||
|
"chegada_utc": obj.chegada_utc.isoformat().replace("+00:00", "Z"),
|
||||||
|
"dur_h": f"{obj.dur_h:.2f}",
|
||||||
|
"prioridade": obj.prioridade,
|
||||||
|
"periodo": obj.periodo,
|
||||||
|
"aeronave_real_2025": obj.aeronave_real,
|
||||||
|
"linhas_origem": obj.linhas_origem,
|
||||||
|
"status": "cumprida",
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
for mid in sol["ids"]:
|
||||||
|
if not z[mid].value() or z[mid].value() <= 0.5:
|
||||||
|
obj = miss[mid]["obj"]
|
||||||
|
linhas.append(
|
||||||
|
{
|
||||||
|
"aeronave_modelo": "",
|
||||||
|
"ordem": "",
|
||||||
|
"id": mid,
|
||||||
|
"om": obj.om,
|
||||||
|
"orig": obj.orig,
|
||||||
|
"dest": obj.dest,
|
||||||
|
"partida_utc": obj.partida_utc.isoformat().replace("+00:00", "Z"),
|
||||||
|
"chegada_utc": obj.chegada_utc.isoformat().replace("+00:00", "Z"),
|
||||||
|
"dur_h": f"{obj.dur_h:.2f}",
|
||||||
|
"prioridade": obj.prioridade,
|
||||||
|
"periodo": obj.periodo,
|
||||||
|
"aeronave_real_2025": obj.aeronave_real,
|
||||||
|
"linhas_origem": obj.linhas_origem,
|
||||||
|
"status": "nao_cumprida",
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
colunas = [
|
||||||
|
"status",
|
||||||
|
"aeronave_modelo",
|
||||||
|
"ordem",
|
||||||
|
"id",
|
||||||
|
"om",
|
||||||
|
"orig",
|
||||||
|
"dest",
|
||||||
|
"partida_utc",
|
||||||
|
"chegada_utc",
|
||||||
|
"dur_h",
|
||||||
|
"prioridade",
|
||||||
|
"periodo",
|
||||||
|
"aeronave_real_2025",
|
||||||
|
"linhas_origem",
|
||||||
|
]
|
||||||
|
with caminho.open("w", newline="", encoding="utf-8-sig") as arquivo:
|
||||||
|
escritor = csv.DictWriter(arquivo, fieldnames=colunas)
|
||||||
|
escritor.writeheader()
|
||||||
|
escritor.writerows(linhas)
|
||||||
|
|
||||||
|
|
||||||
|
def imprimir_relatorio(sol: dict[str, object], resultado_csv: Path) -> None:
|
||||||
|
miss = sol["miss"]
|
||||||
|
z = sol["z"]
|
||||||
|
ids = sol["ids"]
|
||||||
|
cobertas = [i for i in ids if z[i].value() is not None and z[i].value() > 0.5]
|
||||||
|
prioridade_total = sum(int(miss[i]["prio"]) for i in ids)
|
||||||
|
prioridade_obtida = sum(int(miss[i]["prio"]) for i in cobertas)
|
||||||
|
|
||||||
|
print("=" * 72)
|
||||||
|
print(" OAMRP V2 - Registro de voo 2025 consolidado")
|
||||||
|
print("=" * 72)
|
||||||
|
print(f" Status solver: {pulp.LpStatus[sol['modelo'].status]}")
|
||||||
|
print(f" Horizonte inicia em UTC: {sol['horizonte_inicio'].isoformat().replace('+00:00', 'Z')}")
|
||||||
|
print(f" Missoes cumpridas: {len(cobertas)}/{len(ids)}")
|
||||||
|
print(f" Prioridade obtida: {prioridade_obtida}/{prioridade_total}")
|
||||||
|
print(f" Resultado CSV: {resultado_csv}")
|
||||||
|
|
||||||
|
for k in sol["ks"]:
|
||||||
|
seq = rota_da_aeronave(sol, k)
|
||||||
|
horas = sum(float(miss[i]["dur"]) for i in seq)
|
||||||
|
print(f"\n Aeronave {k}: {len(seq)} missoes | {horas:.1f}h")
|
||||||
|
for mid in seq[:12]:
|
||||||
|
obj = miss[mid]["obj"]
|
||||||
|
print(
|
||||||
|
f" {obj.partida_utc:%d/%m %H:%M}Z "
|
||||||
|
f"{obj.orig}->{obj.dest} OM {obj.om} ({mid})"
|
||||||
|
)
|
||||||
|
if len(seq) > 12:
|
||||||
|
print(f" ... mais {len(seq) - 12} missoes")
|
||||||
|
|
||||||
|
nao_cumpridas = [i for i in ids if i not in cobertas]
|
||||||
|
if nao_cumpridas:
|
||||||
|
print("\n Missoes nao cumpridas (primeiras 20):")
|
||||||
|
for mid in nao_cumpridas[:20]:
|
||||||
|
obj = miss[mid]["obj"]
|
||||||
|
print(f" {obj.partida_utc:%d/%m %H:%M}Z {obj.orig}->{obj.dest} OM {obj.om} ({mid})")
|
||||||
|
if len(nao_cumpridas) > 20:
|
||||||
|
print(f" ... mais {len(nao_cumpridas) - 20} missoes")
|
||||||
|
|
||||||
|
|
||||||
|
def main() -> None:
|
||||||
|
parser = argparse.ArgumentParser(description="Resolve OAMRP v2 com registro de voo real.")
|
||||||
|
parser.add_argument("--csv", type=Path, default=CSV_REGISTRO_PADRAO)
|
||||||
|
parser.add_argument("--inicio", default=DATA_INICIO_PADRAO)
|
||||||
|
parser.add_argument("--fim", default=DATA_FIM_PADRAO)
|
||||||
|
parser.add_argument("--resultado", type=Path, default=CSV_RESULTADO_PADRAO)
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
inicio = parse_data_inicio(args.inicio)
|
||||||
|
fim = parse_data_inicio(args.fim)
|
||||||
|
missoes = carregar_missoes(args.csv, inicio, fim)
|
||||||
|
sol = resolver(missoes)
|
||||||
|
escrever_resultado(sol, args.resultado)
|
||||||
|
imprimir_relatorio(sol, args.resultado)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
1392
software/oamrp_v3.py
Normal file
1392
software/oamrp_v3.py
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user