Add weighted under-node elevation in winner refinement

Runs ElevateUnderNodeViolations as a final pass using weighted score
comparison (Score.Value) instead of per-category gating. Under-node
(100K penalty) is worth more than detour (50K), so trading one for
the other is a net score improvement.

Currently no change to the document fixture — the elevation logic's
internal guards find nothing new to elevate after the standard polish
stages. The remaining under-node edges (edge/20 3076px sweep, edge/25
29px gap) need corridor re-routing, not segment elevation.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
master
2026-03-30 08:59:22 +03:00
parent 62b6169d36
commit 7e62f9c0c4

View File

@@ -88,6 +88,34 @@ internal static partial class ElkEdgeRouterIterative
} }
} }
// Targeted under-node elevation with net-total promotion.
// ElevateUnderNodeViolations can fix remaining under-node edges
// (gateway-exit lanes, long horizontal sweeps) but the standard
// promotion gating blocks it because elevation increases path
// length (detour). Net-total allows the tradeoff: under-node
// fix (100K savings) outweighs detour cost (50K).
if (current.RetryState.UnderNodeViolations > 0)
{
var elevated = ElkEdgePostProcessor.ElevateUnderNodeViolations(
current.Edges, nodes, minLineClearance);
elevated = ElkEdgePostProcessor.NormalizeBoundaryAngles(elevated, nodes);
elevated = ElkEdgePostProcessor.NormalizeSourceExitAngles(elevated, nodes);
var elevatedScore = ElkEdgeRoutingScoring.ComputeScore(elevated, nodes);
var elevatedRetry = BuildRetryState(
elevatedScore,
HighwayProcessingEnabled
? ElkEdgeRouterHighway.DetectRemainingBrokenHighways(elevated, nodes).Count
: 0);
// Use weighted comparison: under-node (100K) is worth more than
// detour (50K), so trading 1 under-node for 1 detour is a net win.
if (elevatedScore.Value > current.Score.Value
&& elevatedScore.NodeCrossings <= current.Score.NodeCrossings)
{
current = current with { Score = elevatedScore, RetryState = elevatedRetry, Edges = elevated };
ElkLayoutDiagnostics.LogProgress($"Hybrid winner refinement after under-node elevation: {DescribeSolution(current)}");
}
}
return current; return current;
} }