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 void PriorityQueue() { PriorityQueue<int> pq = new PriorityQueue<int>(LinqExt.TakeMore); pq.Enqueue(1, 1); pq.Enqueue(9, 9); pq.Enqueue(2, 2); pq.Enqueue(5, 5); Assert.IsTrue(pq.First() == 9, "Wrong Priority"); Assert.IsTrue(pq.Dequeue() == 9, "Wrong Priority"); Assert.IsTrue(pq.Dequeue() == 5, "Wrong Priority"); pq.ChangePriority(1, 29); Assert.IsTrue(pq.First() == 1, "Wrong Priority, 1 should be first priority now with priority 29"); pq.Enqueue(3, 2); //add item with same priority pq.Enqueue(4, 2); //add item with same priority Assert.IsTrue(pq.Last() == 4, "Wrong Priority, 4 should be last"); pq.Enqueue(30, 30); // mix case Assert.IsTrue(pq.First() == 30, "Wrong Priority, 30 should be first priority"); pq.Enqueue(31, 30); // mix case Assert.IsTrue(pq.First() == 30, "Wrong Priority, 30 should still be first priority"); pq.Enqueue(5, 2); //add item with same priority pq.Enqueue(6, 2); //add item with same priority Assert.IsTrue(pq.Last() == 6, "Wrong Priority, 6 should be last"); }
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; }