public static IReadOnlyDictionary <GraphNode <T>, GraphNode <T> > RunDijkstraFrom(UndirectedGraph <T> graph, T src) { if (!graph.Nodes.TryGetValue(new GraphNode <T>(src), out var source)) { return(null); } var predecessors = new Dictionary <GraphNode <T>, GraphNode <T> >();//keeps track of the shortest path predecessor //using Dijkstra's algorithm var priorityQ = new MinHeap <GraphNode <T> >(new GraphNode <T>(default(T))); foreach (var node in graph.Nodes) { node.Weight = source.Equals(node) ? 0 : int.MaxValue; priorityQ.Add(node); predecessors[source] = null; } while (priorityQ.Count != 0) { var minNode = priorityQ.GetMin(); minNode.Color = Color.Colored;//indicating that these nodes are done if (!graph.Neighbors.ContainsKey(minNode)) { priorityQ.ExtractMin(); continue; } foreach (var neighbor in graph.Neighbors[minNode]) { graph.Nodes.TryGetValue(neighbor, out var neighborNode); if (neighborNode.Color == Color.Colored) { continue; } var edge = graph.GetEdge(minNode, neighbor); //if (!graph.Edges.TryGetValue(new Edge<T>(minNode, neighbor), out var edge)) // throw new InvalidDataException($"failed to find edge to neighbor {minNode.Label}->{neighbor.Label}"); if (neighborNode.Weight > minNode.Weight + edge.Weight) { neighborNode.Weight = minNode.Weight + edge.Weight; predecessors[neighborNode] = minNode; } } priorityQ.ExtractMin(); } return(predecessors); }
//for directed Graph public static IReadOnlyDictionary <GraphNode <T>, GraphNode <T> > RunDijkstraFrom(DirectedGraph <T> graph, T src) { if (!graph.Nodes.TryGetValue(new GraphNode <T>(src), out var source)) { return(null); } var predecessors = new Dictionary <GraphNode <T>, GraphNode <T> >();//keeps track of the shortest path predecessor //using Dijkstra's algorithm var priorityQ = new MinHeap <GraphNode <T> >(new GraphNode <T>(default(T))); foreach (var node in graph.Nodes) { node.Weight = source.Equals(node) ? 0 : int.MaxValue; priorityQ.Add(node); predecessors[source] = null; } while (priorityQ.Count != 0) { var minNode = priorityQ.GetMin(); if (!graph.Neighbors.ContainsKey(minNode)) { priorityQ.ExtractMin(); continue; } foreach (var neighbor in graph.Neighbors[minNode]) { graph.Nodes.TryGetValue(neighbor, out var neighborNode); var edges = graph.GetEdges(minNode, neighbor); foreach (var edge in edges) { if (neighborNode.Weight > minNode.Weight + edge.Weight) { neighborNode.Weight = minNode.Weight + edge.Weight; predecessors[neighborNode] = minNode; } } } priorityQ.ExtractMin(); } return(predecessors); }