""" Gera o arquivo de OFRAG (Ordem de Fragmentação) sintético para o Esquadrão Arara. Cada OFRAG autoriza uma missão específica e define: - Prioridade operacional (1=urgente … 5=baixa) - Tipo de missão (Logística, Médico, Pessoal, Reabastecimento, Reconhecimento) - Base de origem e destino Uso: python software/gerar_ofrag.py --seed 42 --n 50 --saida db/processed/ofrag.csv """ import argparse import csv import random from datetime import datetime, timezone from pathlib import Path # --------------------------------------------------------------------------- # Importa constantes e função de geração do modelo principal # --------------------------------------------------------------------------- import sys sys.path.insert(0, str(Path(__file__).resolve().parent)) from oamrp_v3 import ( BASES_COORDS, TIPOS_MISSAO, _PESOS_PRIO, gerar_missoes_sinteticas, ) BASE_DIR = Path(__file__).resolve().parents[1] OFRAG_PADRAO = BASE_DIR / "db" / "processed" / "ofrag.csv" _TIPOS_EVAM = ["Médico", "Logística"] # EVAM normalmente carrega carga urgente def gerar_ofrag( n: int = 50, seed: int = 42, saida: Path = OFRAG_PADRAO, ) -> None: inicio = datetime(2025, 1, 1, tzinfo=timezone.utc) missoes, _ = gerar_missoes_sinteticas(n=n, seed=seed, inicio=inicio, n_evam=5) rng = random.Random(seed + 1) # semente diferente para tipos saida.parent.mkdir(parents=True, exist_ok=True) colunas = [ "id_ofrag", "missao_id", "om", "orig", "dest", "prioridade", "tipo_missao", "observacao", ] with saida.open("w", newline="", encoding="utf-8-sig") as f: w = csv.DictWriter(f, fieldnames=colunas) w.writeheader() for idx, m in enumerate(missoes, start=1): if m.obrigatoria: prio = 1 tipo = rng.choice(_TIPOS_EVAM) obs = "EVAM — execução obrigatória" else: prio = rng.choices(range(1, 6), weights=_PESOS_PRIO)[0] tipo = rng.choices(TIPOS_MISSAO, weights=[20, 15, 25, 25, 15])[0] obs = "" w.writerow({ "id_ofrag": f"OFRAG-2025-{idx:03d}", "missao_id": m.id, "om": m.om, "orig": m.orig, "dest": m.dest, "prioridade": prio, "tipo_missao": tipo, "observacao": obs, }) print(f" OFRAG gerado: {saida} ({len(missoes)} ordens)") _resumir(saida) def _resumir(saida: Path) -> None: from collections import Counter prios: Counter = Counter() tipos: Counter = Counter() with saida.open(newline="", encoding="utf-8-sig") as f: for row in csv.DictReader(f): prios[int(row["prioridade"])] += 1 tipos[row["tipo_missao"]] += 1 print("\n Distribuição de prioridades:") for p in sorted(prios): bar = "#" * prios[p] print(f" Prio {p}: {prios[p]:3d} {bar}") print("\n Distribuição de tipos:") for t, c in tipos.most_common(): print(f" {t:<20} {c:3d}") def main() -> None: parser = argparse.ArgumentParser(description="Gerador de OFRAG sintético — Arara C-105") parser.add_argument("--seed", type=int, default=42) parser.add_argument("--n", type=int, default=50, help="Número de missões") parser.add_argument("--saida", type=Path, default=OFRAG_PADRAO) args = parser.parse_args() gerar_ofrag(n=args.n, seed=args.seed, saida=args.saida) if __name__ == "__main__": main()