public static IEnumerable<int?> Find(DirectedWeightedGraph graph, int source) { var dist = new int?[graph.NodesCount]; dist[source] = 0; var closestNodes = new PriorityQueue<int, int>(dist.Select((d, i) => new KeyValuePair<int, int>(i, d.GetValueOrDefault(int.MaxValue)))); var exploredNodes = new HashSet<int>(); while (closestNodes.Count != 0) { var node = closestNodes.ExtractHighestPriorityElement(); exploredNodes.Add(node); foreach (var edge in graph.GetEdges(node).Where(e => !exploredNodes.Contains(e.EndNode))) { if (dist[node] != null) { var alt = dist[node].Value + edge.Weight; if (alt < dist[edge.EndNode].GetValueOrDefault(int.MaxValue)) { dist[edge.EndNode] = alt; closestNodes.ChangePriority(edge.EndNode, alt); } } } } return dist; }
public static int GetMinimumSpanningTreeLength(DirectedWeightedGraph graph) { int length = 0; var dist = new int[graph.NodesCount]; const int StartNode = 0; dist[StartNode] = 0; for (int i = 0; i < dist.Length; i++) { if (i != StartNode) { dist[i] = int.MaxValue; } } var closestNodes = new PriorityQueue<int, int>(dist.Select((d, i) => new KeyValuePair<int, int>(i, d))); var exploredNodes = new HashSet<int>(); while (exploredNodes.Count != graph.NodesCount) { var node = closestNodes.ExtractHighestPriorityElement(); length += dist[node]; exploredNodes.Add(node); foreach (var edge in graph.GetEdges(node).Where(e => !exploredNodes.Contains(e.EndNode))) { var alt = edge.Weight; if (alt < dist[edge.EndNode]) { dist[edge.EndNode] = alt; closestNodes.ChangePriority(edge.EndNode, alt); } } } return length; }
public void ExtractHighestPriorityElementTest() { const int N = 100; var minHeap = new PriorityQueue<int, int>(Enumerable.Range(0, N).Select(x => new KeyValuePair<int, int>(x, x)).Reverse()); for (int i = 0; i < N; i++) { minHeap.ExtractHighestPriorityElement().Should().Be(i); } }
public static int GetMaxSpacing(DirectedWeightedGraph graph, int clusterCount) { int currentClusterCount = graph.NodesCount; var unionFind = new UnionFind(currentClusterCount); var edges = new PriorityQueue<WeightedEdge, int>(graph.GetEdges().Select(e => new KeyValuePair<WeightedEdge, int>(e, e.Weight))); while (currentClusterCount >= clusterCount) { var edge = edges.ExtractHighestPriorityElement(); var cluster1 = unionFind.Find(edge.StartNode); var cluster2 = unionFind.Find(edge.EndNode); if (cluster1 != cluster2) { if (currentClusterCount == clusterCount) { return edge.Weight; } unionFind.Union(cluster1, cluster2); currentClusterCount--; } } return 0; }