1
0

feat: remove astar, use bfs instead

This commit is contained in:
2026-06-25 12:31:09 +08:00
parent 625628cc1a
commit 7fa0f56495
7 changed files with 406 additions and 166 deletions

View File

@@ -2,9 +2,10 @@ import bisect
from itertools import chain, product
from functools import cached_property
from .common import Resolver
from .bfs import BfsResolver
from ..dataset import DatasetCollection, Dataset
from ..common import Circuit, DeviceKind, JointKind
from ..query import Request, Response, ResponseDeduper
from ..common import Circuit, DeviceKind, JointKind, CircuitValueTrait
from ..query import Request, Response
class LutItem:
@@ -14,25 +15,20 @@ class LutItem:
__circuit: Circuit
"""The circuit represented by this item."""
__device_kind: DeviceKind
"""The device kind applied for this circuit."""
__value: float
"""The value of this circuit."""
def __init__(self, circuit: Circuit, device_kind: DeviceKind):
self.__circuit = circuit
self.__device_kind = device_kind
self.__value = self.__circuit.compute(device_kind)
@property
def circuit(self) -> Circuit:
return self.__circuit
@cached_property
@property
def value(self) -> float:
"""
The computed value of the circuit.
:return: The computed value.
"""
return self.__circuit.compute(self.__device_kind)
return self.__value
class LutResolver(Resolver):
@@ -59,22 +55,12 @@ class LutResolver(Resolver):
)
def __build_lut(self, dataset: Dataset, device_kind: DeviceKind) -> list[LutItem]:
values = dataset.values
joints = tuple(JointKind)
lut = [
LutItem(circuit, device_kind)
for circuit in chain(
(Circuit.from_one_device(v1) for v1 in values),
(
Circuit.from_two_devices(v1, v2, j2)
for v1, v2, j2 in product(values, values, joints)
),
(
Circuit.from_three_devices(v1, v2, j2, v3, j3)
for v1, v2, j2, v3, j3 in product(
values, values, joints, values, joints
)
),
BfsResolver.iter_one_device_circuit(dataset),
BfsResolver.iter_two_devices_circuit(dataset),
BfsResolver.iter_three_devices_circuit(dataset),
)
]
lut.sort(key=lambda item: item.value)
@@ -91,8 +77,8 @@ class LutResolver(Resolver):
lut = self.__inductor_lut
target = request.target_value
count_limit = min(request.count_limit, 100)
deduper = ResponseDeduper()
count_limit = request.count_limit
bucket: list[Circuit] = []
# Locate the insertion point of target in the sorted LUT.
# left/right start at the two nearest neighbours and expand outward.
@@ -106,7 +92,7 @@ class LutResolver(Resolver):
# difference order, so the first N items within tolerance are exactly
# the N best matches.
while left >= 0 or right < len(lut):
if len(deduper) >= count_limit:
if len(bucket) >= count_limit:
break
if left < 0:
@@ -134,6 +120,6 @@ class LutResolver(Resolver):
right = len(lut)
continue
deduper.add(item.circuit)
bucket.append(item.circuit)
return Response(request, deduper)
return Response(request, bucket)