""" Decoder — Convert QAOA measurement outcomes to valid topologies. Filters and ranks candidate configurations. """ from __future__ import annotations import pandapower as pp from src.grid.power_flow import check_radial_connected, evaluate_topology def decode_and_evaluate( net: pp.pandapowerNet, candidates: list[dict], ) -> list[dict]: """Take QAOA candidates, validate radiality, run power flow, and rank. Parameters ---------- net : pp.pandapowerNet candidates : list[dict] Each has ``open_lines`` and ``fval`` from QAOA. Returns ------- list[dict] Evaluated candidates sorted by total_loss_kw (ascending). Each has: open_lines, feasible, converged, total_loss_kw, etc. """ evaluated = [] for cand in candidates: open_lines = cand["open_lines"] # Check radiality if not check_radial_connected(net, open_lines): evaluated.append({ "open_lines": open_lines, "feasible": False, "converged": False, "qaoa_fval": cand.get("fval"), }) continue # Run AC power flow result = evaluate_topology(net, open_lines) result["feasible"] = True result["qaoa_fval"] = cand.get("fval") evaluated.append(result) # Sort: feasible + converged first, then by loss def sort_key(x): if x.get("converged") and x.get("feasible"): return (0, x.get("total_loss_kw", float("inf"))) return (1, float("inf")) evaluated.sort(key=sort_key) return evaluated