File size: 1,624 Bytes
55e3496
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
"""
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