Tighter A* estimate on the orthogonal track, and --heuristic-weight
The grid search estimated the remaining distance as a straight line even when only orthogonal steps exist; Manhattan is the tighter estimate those moves admit and still never overestimates. --heuristic-weight W (default 1) makes it weighted A*: routes at most W times the shortest (tested).
This commit is contained in:
@@ -138,8 +138,10 @@ class GridRouter:
|
||||
via_half: int | None = None,
|
||||
edge_clearance: int | None = None,
|
||||
resolution: int = 1,
|
||||
heuristic_weight: float = 1.0,
|
||||
) -> None:
|
||||
self.board = board
|
||||
self.heuristic_weight = max(float(heuristic_weight), 1.0)
|
||||
self.trace_width = max(trace_width, 1)
|
||||
self.clearance = max(clearance, 0)
|
||||
self.half_width = self.trace_width // 2
|
||||
@@ -471,7 +473,13 @@ class GridRouter:
|
||||
heapq.heappush(open_heap, (tentative + self._h(nxt, goal_cell), nxt))
|
||||
|
||||
def _h(self, node: Node, goal_cell: Cell) -> float:
|
||||
return math.hypot(node[0] - goal_cell[0], node[1] - goal_cell[1])
|
||||
dx, dy = abs(node[0] - goal_cell[0]), abs(node[1] - goal_cell[1])
|
||||
# the tightest estimate the allowed moves admit (Manhattan when only
|
||||
# orthogonal steps exist), scaled by heuristic_weight: above 1 the
|
||||
# search heads for the goal instead of flooding open board, for a
|
||||
# route at most that factor longer than the shortest
|
||||
base = dx + dy if self._orthogonal else math.hypot(dx, dy)
|
||||
return self.heuristic_weight * base
|
||||
|
||||
# --- commit / rip -------------------------------------------------------
|
||||
|
||||
@@ -687,6 +695,7 @@ def route_board(
|
||||
via_half: int | None = None,
|
||||
edge_clearance: int | None = None,
|
||||
resolution: int = 1,
|
||||
heuristic_weight: float = 1.0,
|
||||
) -> RouteResult:
|
||||
"""Convenience wrapper: build a :class:`GridRouter` and route the board."""
|
||||
router = GridRouter(
|
||||
@@ -701,5 +710,6 @@ def route_board(
|
||||
via_half=via_half,
|
||||
edge_clearance=edge_clearance,
|
||||
resolution=resolution,
|
||||
heuristic_weight=heuristic_weight,
|
||||
)
|
||||
return router.route()
|
||||
|
||||
Reference in New Issue
Block a user