--promote-failures: reroute with the connections that failed moved first

Each round routes every connection that has failed so far ahead of the
rest, which keep their order. The promoted set only grows, so two groups
cannot take turns failing; the best round is kept.
This commit is contained in:
2026-09-27 22:34:06 -06:00
parent 0f5dacbd88
commit 01ca108831
7 changed files with 105 additions and 4 deletions
+8
View File
@@ -156,11 +156,14 @@ class GridRouter:
resolution: int = 1,
heuristic_weight: float = 1.0,
seed: int | None = None,
route_first: frozenset | None = None,
) -> None:
self.board = board
# None keeps the deterministic order; a seed shuffles which connection
# routes first, to measure how much a result owes to the order
self.seed = seed
# connections, as (net_no, one end, other end), to route before the rest
self.route_first = frozenset(route_first or ())
# how far (in cells) an escape stub may run to leave a walled-in pin
self._escape_cells = 12
self._crowded_cache: dict = {}
@@ -828,6 +831,9 @@ class GridRouter:
order = list(conns)
if self.seed is not None:
random.Random(self.seed).shuffle(order)
if self.route_first:
# stable: the promoted keep their order among themselves, as do the rest
order.sort(key=lambda c: (c.net_no, *_ends_of(c)) not in self.route_first)
for _ in range(passes):
changed = False
for conn in order:
@@ -1060,6 +1066,7 @@ def route_board(
resolution: int = 1,
heuristic_weight: float = 1.0,
seed: int | None = None,
route_first: frozenset | None = None,
) -> RouteResult:
"""Convenience wrapper: build a :class:`GridRouter` and route the board."""
router = GridRouter(
@@ -1076,5 +1083,6 @@ def route_board(
resolution=resolution,
heuristic_weight=heuristic_weight,
seed=seed,
route_first=route_first,
)
return router.route()