From ab41ea8c39b808a48e576d375a3cb663243cc956 Mon Sep 17 00:00:00 2001 From: ShiboSoftwareDev Date: Fri, 7 Aug 2026 20:23:33 +0200 Subject: [PATCH 1/2] Reject infeasible greedy final routes --- lib/core.ts | 33 ++++++++++--------- ...final-route-single-layer-crossing.snap.svg | 20 ++++------- ...-final-route-single-layer-crossing.test.ts | 8 ++--- 3 files changed, 29 insertions(+), 32 deletions(-) diff --git a/lib/core.ts b/lib/core.ts index c224a31..bdd19cb 100644 --- a/lib/core.ts +++ b/lib/core.ts @@ -587,28 +587,32 @@ export class TinyHyperGraphSolver extends BaseSolver { return } + if (currentCandidate.portId === state.goalPortId) { + this.onPathFound(currentCandidate) + return + } + const neighbors = topology.regionIncidentPorts[currentCandidate.nextRegionId] for (const neighborPortId of neighbors) { const assignedNetId = state.portAssignment[neighborPortId] + const neighborIsGoal = neighborPortId === state.goalPortId if (this.isPortReservedForDifferentNet(neighborPortId)) continue - if (neighborPortId === state.goalPortId) { - if (assignedNetId !== -1 && assignedNetId !== state.currentRouteNetId) { - continue - } - this.onPathFound(currentCandidate) - return - } if (assignedNetId !== -1 && assignedNetId !== state.currentRouteNetId) { continue } if (neighborPortId === currentCandidate.portId) continue - if (problem.portSectionMask[neighborPortId] === 0) continue + if (!neighborIsGoal && problem.portSectionMask[neighborPortId] === 0) { + continue + } const g = this.computeG(currentCandidate, neighborPortId) if (!Number.isFinite(g)) continue - const h = this.computeH(neighborPortId) + if (neighborIsGoal) { + this.onPathFound(currentCandidate) + return + } const nextRegionId = topology.incidentPortRegion[neighborPortId][0] === @@ -623,6 +627,7 @@ export class TinyHyperGraphSolver extends BaseSolver { continue } + const h = this.computeH(neighborPortId) const newCandidate = { prevRegionId: currentCandidate.nextRegionId, nextRegionId, @@ -633,11 +638,6 @@ export class TinyHyperGraphSolver extends BaseSolver { prevCandidate: currentCandidate, } - if (neighborPortId === state.goalPortId) { - this.onPathFound(newCandidate) - return - } - const candidateHopId = this.getHopId(neighborPortId, nextRegionId) if (g >= this.getCandidateBestCost(candidateHopId)) continue @@ -1536,8 +1536,11 @@ export class TinyHyperGraphSolver extends BaseSolver { class GreedyFinalRouteSolver extends TinyHyperGraphSolver { override computeG( currentCandidate: Candidate, - _neighborPortId: PortId, + neighborPortId: PortId, ): number { + const constraintAwareCost = super.computeG(currentCandidate, neighborPortId) + if (!Number.isFinite(constraintAwareCost)) return constraintAwareCost + return currentCandidate.g } } diff --git a/tests/solver/__snapshots__/greedy-final-route-single-layer-crossing.snap.svg b/tests/solver/__snapshots__/greedy-final-route-single-layer-crossing.snap.svg index 5561c9c..064c6a8 100644 --- a/tests/solver/__snapshots__/greedy-final-route-single-layer-crossing.snap.svg +++ b/tests/solver/__snapshots__/greedy-final-route-single-layer-crossing.snap.svg @@ -3,9 +3,8 @@ region: region-0 z: 0" points="535.5427445183542,175.0677506775068 314.79871889627987,175.0677506775068" fill="none" stroke="hsla(266, 70%, 50%, 0.8)" stroke-width="1px"/>