/// <summary> /// The Topological Sorting algorithm /// </summary> public static IEnumerable <T> Sort <T>(IGraph <T> Graph) where T : IComparable <T> { // If the graph is either null or is not a DAG, throw exception. if (Graph == null) { throw new ArgumentNullException(); } else if (!Graph.IsDirected || CyclesDetector.IsCyclic <T>(Graph)) { throw new Exception("The graph is not a DAG."); } var visited = new HashSet <T>(); var topoSortStack = new DataStructures.Lists.Stack <T>(); foreach (var vertex in Graph.Vertices) { if (!visited.Contains(vertex)) { _topoSortHelper <T>(Graph, vertex, ref topoSortStack, ref visited); } } return(topoSortStack); }
/// <summary> /// Returns an enumerable collection of nodes that specify the shortest path from the source vertex to the destination vertex. /// </summary> public IEnumerable <TVertex> ShortestPathTo(TVertex destination) { if (!_nodesToIndices.ContainsKey(destination)) { throw new Exception("Graph doesn't have the specified vertex."); } else if (!HasPathTo(destination)) { return(null); } int dstIndex = _nodesToIndices[destination]; var stack = new DataStructures.Lists.Stack <TVertex>(); int index; for (index = dstIndex; _distances[index] != 0; index = _predecessors[index]) { stack.Push(_indicesToNodes[index]); } // Push the source vertex stack.Push(_indicesToNodes[index]); return(stack); }
/// <summary> /// Private recursive helper. /// </summary> private static void _topoSortHelper <T>(IGraph <T> graph, T source, ref DataStructures.Lists.Stack <T> topoSortStack, ref HashSet <T> visited) where T : IComparable <T> { visited.Add(source); foreach (var adjacent in graph.Neighbours(source)) { if (!visited.Contains(adjacent)) { _topoSortHelper <T>(graph, adjacent, ref topoSortStack, ref visited); } } topoSortStack.Push(source); }