Пример #1
0
        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);
        }
Пример #2
0
        //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);
        }