--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
+35 -1
View File
@@ -5,7 +5,13 @@ from __future__ import annotations
from pathlib import Path
from freeroute.cli import main
from freeroute.route.orders import best_of_orders, candidate_seeds, route_once, score
from freeroute.route.orders import (
best_of_orders,
candidate_seeds,
promote_failures,
route_once,
score,
)
FIXTURES = Path(__file__).resolve().parent.parent / "dsn" / "fixtures"
# Greedy (no rip-up), the default order strands a net here and seeds 1 to 3 do not.
@@ -42,3 +48,31 @@ def test_cli_orders_writes_the_best_session(tmp_path, capsys):
assert "tried 3 orders, kept --seed 1" in err
assert "not routed" not in err
assert out.read_text().startswith("(session")
def test_promoting_the_failed_connection_routes_it():
best, rounds = promote_failures(RIPUP, "grid", GREEDY, rounds=3)
assert rounds == [(1, 0), (0, 0)] # stops once nothing fails
assert score(best) == (0, 0)
def test_nothing_promoted_is_the_plain_order():
plain = route_once(RIPUP, "grid", {}, None)
empty = route_once(RIPUP, "grid", {"route_first": frozenset()}, None)
assert plain == empty
def test_cli_promote_failures(tmp_path, capsys):
out = tmp_path / "p.ses"
rc = main(
[
str(FIXTURES / "ripup_needed.dsn"),
"--no-rip-up",
"--promote-failures",
"3",
"-do",
str(out),
]
)
assert rc == 0
assert "2 rounds, unrouted 1, 0" in capsys.readouterr().err
+1
View File
@@ -156,6 +156,7 @@ def test_cli_supported_combinations_are_accepted(tmp_path):
"max_passes": ["-mp", "4"],
"seed": ["--seed", "3"],
"orders": ["--orders", "2"],
"promote": ["--promote-failures", "2"],
}
for engine, options in ENGINE_OPTIONS.items():
for option in options: