Refactor ElkSharp hybrid routing and document speed path
This commit is contained in:
@@ -0,0 +1,127 @@
|
||||
using System.Collections.Concurrent;
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
|
||||
namespace StellaOps.ElkSharp;
|
||||
|
||||
internal static partial class ElkEdgeRouterIterative
|
||||
{
|
||||
private static IEnumerable<string> ExpandWinningSolutionFocus(
|
||||
IReadOnlyCollection<ElkRoutedEdge> edges,
|
||||
IEnumerable<string> focusEdgeIds)
|
||||
{
|
||||
var edgesById = edges.ToDictionary(edge => edge.Id, StringComparer.Ordinal);
|
||||
var expanded = new HashSet<string>(StringComparer.Ordinal);
|
||||
|
||||
foreach (var edgeId in focusEdgeIds)
|
||||
{
|
||||
if (!expanded.Add(edgeId) || !edgesById.TryGetValue(edgeId, out var edge))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach (var peer in edges)
|
||||
{
|
||||
if (string.Equals(peer.Id, edge.Id, StringComparison.Ordinal))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (string.Equals(peer.SourceNodeId, edge.SourceNodeId, StringComparison.Ordinal)
|
||||
|| string.Equals(peer.TargetNodeId, edge.TargetNodeId, StringComparison.Ordinal)
|
||||
|| string.Equals(peer.SourceNodeId, edge.TargetNodeId, StringComparison.Ordinal)
|
||||
|| string.Equals(peer.TargetNodeId, edge.SourceNodeId, StringComparison.Ordinal))
|
||||
{
|
||||
expanded.Add(peer.Id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return expanded.OrderBy(edgeId => edgeId, StringComparer.Ordinal);
|
||||
}
|
||||
|
||||
private static IEnumerable<string> ExpandSharedLanePolishFocus(
|
||||
IReadOnlyCollection<ElkRoutedEdge> edges,
|
||||
IReadOnlyCollection<ElkPositionedNode> nodes,
|
||||
string focusEdgeId)
|
||||
{
|
||||
var edgesById = edges.ToDictionary(edge => edge.Id, StringComparer.Ordinal);
|
||||
if (!edgesById.TryGetValue(focusEdgeId, out var focusEdge))
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
var focusedEdgeIds = new HashSet<string>(StringComparer.Ordinal)
|
||||
{
|
||||
focusEdgeId,
|
||||
};
|
||||
var sharedNodeIds = new HashSet<string>(StringComparer.Ordinal);
|
||||
|
||||
foreach (var (leftEdgeId, rightEdgeId) in ElkEdgeRoutingScoring.DetectSharedLaneConflicts(edges, nodes))
|
||||
{
|
||||
string partnerEdgeId;
|
||||
if (string.Equals(leftEdgeId, focusEdgeId, StringComparison.Ordinal))
|
||||
{
|
||||
partnerEdgeId = rightEdgeId;
|
||||
}
|
||||
else if (string.Equals(rightEdgeId, focusEdgeId, StringComparison.Ordinal))
|
||||
{
|
||||
partnerEdgeId = leftEdgeId;
|
||||
}
|
||||
else
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!edgesById.TryGetValue(partnerEdgeId, out var partnerEdge))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
focusedEdgeIds.Add(partnerEdgeId);
|
||||
CollectSharedConflictNodeIds(focusEdge, partnerEdge, sharedNodeIds);
|
||||
}
|
||||
|
||||
if (sharedNodeIds.Count == 0)
|
||||
{
|
||||
return ExpandWinningSolutionFocus(edges, [focusEdgeId]);
|
||||
}
|
||||
|
||||
foreach (var edge in edges)
|
||||
{
|
||||
if (focusedEdgeIds.Contains(edge.Id))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((edge.SourceNodeId is not null && sharedNodeIds.Contains(edge.SourceNodeId))
|
||||
|| (edge.TargetNodeId is not null && sharedNodeIds.Contains(edge.TargetNodeId)))
|
||||
{
|
||||
focusedEdgeIds.Add(edge.Id);
|
||||
}
|
||||
}
|
||||
|
||||
return focusedEdgeIds.OrderBy(edgeId => edgeId, StringComparer.Ordinal);
|
||||
}
|
||||
|
||||
private static void CollectSharedConflictNodeIds(
|
||||
ElkRoutedEdge edge,
|
||||
ElkRoutedEdge partner,
|
||||
ISet<string> sharedNodeIds)
|
||||
{
|
||||
if (edge.SourceNodeId is not null
|
||||
&& (string.Equals(edge.SourceNodeId, partner.SourceNodeId, StringComparison.Ordinal)
|
||||
|| string.Equals(edge.SourceNodeId, partner.TargetNodeId, StringComparison.Ordinal)))
|
||||
{
|
||||
sharedNodeIds.Add(edge.SourceNodeId);
|
||||
}
|
||||
|
||||
if (edge.TargetNodeId is not null
|
||||
&& (string.Equals(edge.TargetNodeId, partner.SourceNodeId, StringComparison.Ordinal)
|
||||
|| string.Equals(edge.TargetNodeId, partner.TargetNodeId, StringComparison.Ordinal)))
|
||||
{
|
||||
sharedNodeIds.Add(edge.TargetNodeId);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user