Implementa OAMRP v3 com rede espaco-tempo e restricoes de inspecao (Fases 1-2)

Reescrita do zero em software/oamrp_v3.py: abstracao No/Arco, variavel
unificada y[k,arco], C1-C6 (Fase 1) e C7-C11 com relogio de horas,
downtime e disjuntivas de slot unico (Fase 2). TAT corrigido para 1,5h;
top-10 bases; EVAM obrigatoria; L2 = maximizar horas voadas.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Cesa-V
2026-06-15 23:29:44 -03:00
parent 11821eaa93
commit 328a066849
5 changed files with 1404 additions and 0 deletions

119
HANDOFF_arara_oamrp.md Normal file
View 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 (C1C6).
2. **Inspeção com reset** em SBMN — C7C11 + 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 15)*
- **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.