Files
git.stella-ops.org/src/__Libraries/StellaOps.ElkSharp/ElkEdgeRouterIterative.WinnerRefinement.Detours.cs

76 lines
3.2 KiB
C#

using System.Collections.Concurrent;
using System.Diagnostics;
using System.Globalization;
namespace StellaOps.ElkSharp;
internal static partial class ElkEdgeRouterIterative
{
private static CandidateSolution ApplyWinnerDetourPolish(
CandidateSolution solution,
ElkPositionedNode[] nodes,
double minLineClearance)
{
var focusSeverity = new Dictionary<string, int>(StringComparer.Ordinal);
ElkEdgeRoutingScoring.CountExcessiveDetourViolations(solution.Edges, nodes, focusSeverity, 10);
ElkEdgeRoutingScoring.CountGatewaySourceExitViolations(solution.Edges, nodes, focusSeverity, 10);
if (focusSeverity.Count > 0)
{
var batchedRootEdgeIds = focusSeverity
.OrderByDescending(pair => pair.Value)
.ThenBy(pair => pair.Key, StringComparer.Ordinal)
.Take(Math.Min(focusSeverity.Count, MaxWinnerPolishBatchedRootEdges + 2))
.Select(pair => pair.Key)
.ToArray();
var batchedFocusEdgeIds = ExpandWinningSolutionFocus(solution.Edges, batchedRootEdgeIds).ToArray();
if (batchedFocusEdgeIds.Length > 0)
{
var batchedCandidateEdges = ComposeTransactionalFinalDetourCandidate(
solution.Edges,
nodes,
minLineClearance,
batchedFocusEdgeIds);
batchedCandidateEdges = ChoosePreferredHardRuleLayout(solution.Edges, batchedCandidateEdges, nodes);
if (TryPromoteFinalDetourCandidate(
solution.Edges,
batchedCandidateEdges,
nodes,
solution.Score,
solution.RetryState,
out var batchedPromotedEdges))
{
var batchedPromotedScore = ElkEdgeRoutingScoring.ComputeScore(batchedPromotedEdges, nodes);
var batchedPromotedRetryState = BuildRetryState(
batchedPromotedScore,
HighwayProcessingEnabled
? ElkEdgeRouterHighway.DetectRemainingBrokenHighways(batchedPromotedEdges, nodes).Count
: 0);
solution = new CandidateSolution(
batchedPromotedScore,
batchedPromotedRetryState,
batchedPromotedEdges,
solution.StrategyIndex);
}
}
}
var candidateEdges = ApplyFinalDetourPolish(solution.Edges, nodes, minLineClearance, restrictedEdgeIds: null);
if (ReferenceEquals(candidateEdges, solution.Edges))
{
return solution;
}
var candidateScore = ElkEdgeRoutingScoring.ComputeScore(candidateEdges, nodes);
var candidateRetryState = BuildRetryState(
candidateScore,
HighwayProcessingEnabled
? ElkEdgeRouterHighway.DetectRemainingBrokenHighways(candidateEdges, nodes).Count
: 0);
return new CandidateSolution(candidateScore, candidateRetryState, candidateEdges, solution.StrategyIndex);
}
}