Exemple #1
0
        FindStronglyConnectedComponents(IDiGraph <T> graph)
        {
            var visited     = new HashSet <T>();
            var finishStack = new Stack <T>();

            //step one - create DFS finish visit stack
            foreach (var vertex in graph.VerticesAsEnumberable)
            {
                if (!visited.Contains(vertex.Key))
                {
                    kosarajuStep1(vertex, visited, finishStack);
                }
            }

            //reverse edges
            var reverseGraph = reverseEdges(graph);

            visited.Clear();

            var result = new List <List <T> >();

            //now pop finish stack and gather the components
            while (finishStack.Count > 0)
            {
                var currentVertex = reverseGraph.GetVertex(finishStack.Pop());

                if (!visited.Contains(currentVertex.Key))
                {
                    result.Add(kosarajuStep2(currentVertex, visited,
                                             finishStack, new List <T>()));
                }
            }

            return(result);
        }
Exemple #2
0
 private void Dfs(IDiGraph g, int v)
 {
     onStack[v] = true;
     marked[v]  = true;
     foreach (int w in g.Adj(v))
     {
         if (HasCycle())
         {
             return;
         }
         else if (!marked[w])
         {
             edgeTo[w] = v;
             Dfs(g, w);
         }
         else if (onStack[w])
         {
             cycle = new Chapter1.Stack <int>();
             for (int x = v; x != w; x = edgeTo[x])
             {
                 cycle.Push(x);
             }
             cycle.Push(w);
             cycle.Push(v);
         }
         onStack[v] = false;
     }
 }
        /// <summary>
        /// Clones this graph and creates a residual graph.
        /// </summary>
        private WeightedDiGraph <T, W> createResidualGraph(IDiGraph <T> graph)
        {
            var newGraph = new WeightedDiGraph <T, W>();

            //clone graph vertices
            foreach (var vertex in graph.VerticesAsEnumberable)
            {
                newGraph.AddVertex(vertex.Key);
            }

            //clone edges
            foreach (var vertex in graph.VerticesAsEnumberable)
            {
                //Use either OutEdges or InEdges for cloning
                //here we use OutEdges
                foreach (var edge in vertex.OutEdges)
                {
                    //original edge
                    newGraph.AddEdge(vertex.Key, edge.TargetVertexKey, edge.Weight <W>());
                    //add a backward edge for residual graph with edge value as default(W)
                    newGraph.AddEdge(edge.TargetVertexKey, vertex.Key, default(W));
                }
            }

            return(newGraph);
        }
Exemple #4
0
        /// <summary>
        /// Augment current Path to residual Graph.
        /// </summary>
        private W augmentResidualGraph(IDiGraph <T> graph,
                                       WeightedDiGraph <T, W> residualGraph, List <T> path)
        {
            var min = @operator.MaxWeight;

            for (int i = 0; i < path.Count - 1; i++)
            {
                var vertex1 = residualGraph.FindVertex(path[i]);
                var vertex2 = residualGraph.FindVertex(path[i + 1]);

                var edgeValue = vertex1.OutEdges[vertex2];

                if (@operator.Comparer(min, edgeValue) > 0)
                {
                    min = edgeValue;
                }
            }

            //augment path
            for (int i = 0; i < path.Count - 1; i++)
            {
                var vertex_1 = residualGraph.FindVertex(path[i]);
                var vertex_2 = residualGraph.FindVertex(path[i + 1]);

                //substract from forward paths
                vertex_1.OutEdges[vertex_2] = @operator.SubstractWeights(vertex_1.OutEdges[vertex_2], min);

                //add for backward paths
                vertex_2.OutEdges[vertex_1] = @operator.AddWeights(vertex_2.OutEdges[vertex_1], min);
            }

            return(min);
        }
        }                          //图
        public SymbolDiGraph(string filename, string delim, SearchTableOptions options = SearchTableOptions.SequantialST)
        {
            st = SearchTableExamples.CreateSearchTable <string, int?>(options);
            Scanner scanner = new Scanner(new StreamReader(File.OpenRead(filename)));

            while (scanner.HasNextLine())                     //构造索引
            {
                string[] a = scanner.ReadLine().Split(delim); //为每个不同的字符串关联一个索引
                for (int i = 0; i < a.Length; i++)
                {
                    if (!st.Contains(a[i]))
                    {
                        st.Put(a[i], st.Size);
                    }
                }
            }
            keys = new string[st.Size]; //用来获得顶点名反向索引

            foreach (string name in st.Keys())
            {
                keys[st.Get(name) ?? -1] = name;
            }
            G       = new DiGraph(st.Size);
            scanner = new Scanner(new StreamReader(File.OpenRead(filename))); //第二遍
            while (scanner.HasNextLine())
            {
                string[] a = scanner.ReadLine().Split(delim); //将每一行的第一个顶点和该行的其他顶点相连
                int      v = st.Get(a[0]) ?? -1;
                for (int i = 1; i < a.Length; i++)
                {
                    G.AddEdge(v, st.Get(a[i]) ?? -1);
                }
            }
        }
        /// <summary>
        /// Trace back path from destination to source using parent map.
        /// </summary>
        private ShortestPathResult <T, W> tracePath(IDiGraph <T> graph,
                                                    Dictionary <T, T> parentMap, T source, T destination)
        {
            //trace the path
            var pathStack = new Stack <T>();

            pathStack.Push(destination);

            var currentV = destination;

            while (!Equals(currentV, default(T)) && !Equals(parentMap[currentV], default(T)))
            {
                pathStack.Push(parentMap[currentV]);
                currentV = parentMap[currentV];
            }

            //return result
            var resultPath   = new List <T>();
            var resultLength = @operator.DefaultValue;

            while (pathStack.Count > 0)
            {
                resultPath.Add(pathStack.Pop());
            }

            for (var i = 0; i < resultPath.Count - 1; i++)
            {
                resultLength = @operator.Sum(resultLength,
                                             graph.GetVertex(resultPath[i]).GetOutEdge(graph.GetVertex(resultPath[i + 1])).Weight <W>());
            }

            return(new ShortestPathResult <T, W>(resultPath, resultLength));
        }
Exemple #7
0
 /// <summary>
 /// Creates a new <see cref="DiGraph{T,TWeight}"/> using an existing graph.
 /// </summary>
 /// <param name="graph">the existing graph</param>
 public DiGraph(IDiGraph <T, TWeight> graph) : this(graph.DefaultEdgeWeight)
 {
     _vertices = new HashSet <T>(graph.Vertices);
     foreach (var edge in graph.Edges)
     {
         AddEdge(edge.SourceVertex, edge.TargetVertex, edge.Weight);
     }
 }
 public TransitiveClosure(IDiGraph G)
 {
     all = new DirectedDFS[G.V];
     for (int v = 0; v < G.V; v++)
     {
         all[v] = new DirectedDFS(G, v);
     }
 }
Exemple #9
0
            public Algorithm(IDiGraph <T, TWeight> graph)
            {
                _graph          = graph;
                _metadataLookup = graph.Vertices.ToDictionary(n => n, n => new Metadata(-1, -1, false));

                _index = 0;
                _stack = new Stack <T>();
            }
        /// <summary>
        /// Returns the vertices in Topologically Sorted Order.
        /// </summary>
        public List <T> GetTopSort(IDiGraph <T> graph)
        {
            var inEdgeMap = new Dictionary <T, int>();

            var kahnQueue = new Queue <T>();

            foreach (var vertex in graph.VerticesAsEnumberable)
            {
                inEdgeMap.Add(vertex.Key, vertex.InEdgeCount);

                //init queue with vertices having not in edges
                if (vertex.InEdgeCount == 0)
                {
                    kahnQueue.Enqueue(vertex.Key);
                }
            }

            //no vertices with zero number of in edges
            if (kahnQueue.Count == 0)
            {
                throw new Exception("Graph has a cycle.");
            }

            var result = new List <T>();

            int visitCount = 0;

            //until queue is empty
            while (kahnQueue.Count > 0)
            {
                //cannot exceed vertex number of iterations
                if (visitCount > graph.VerticesCount)
                {
                    throw new Exception("Graph has a cycle.");
                }

                //pick a neighbour
                var nextPick = graph.GetVertex(kahnQueue.Dequeue());

                //if in edge count is 0 then ready for result
                if (inEdgeMap[nextPick.Key] == 0)
                {
                    result.Add(nextPick.Key);
                }

                //decrement in edge count for neighbours
                foreach (var edge in nextPick.OutEdges)
                {
                    inEdgeMap[edge.TargetVertexKey]--;
                    kahnQueue.Enqueue(edge.TargetVertexKey);
                }

                visitCount++;
            }

            return(result);
        }
        private Chapter1.Stack <int> Init(IDiGraph G)
        {
            DirectedCycle cyclefinder = new DirectedCycle(G);

            if (!cyclefinder.HasCycle())
            {
                DepthFirstOrder dfs = new DepthFirstOrder(G);
                return(dfs.ReversePost);
            }
            return(null);
        }
 private void Dfs(IDiGraph g, int s)
 {
     marked[s] = true;
     foreach (int w in g.Adj(s))
     {
         if (!marked[w])
         {
             Dfs(g, w);
         }
     }
 }
 //在G中找到从source中的所有顶点可达的所有顶点
 public DirectedDFS(IDiGraph G, IEnumerable <int> sources)
 {
     marked = new bool[G.V];
     foreach (int s in sources)
     {
         if (!marked[s])
         {
             Dfs(G, s);
         }
     }
 }
Exemple #14
0
        private bool[] onStack;             //递归调用的栈上的所有顶点

        public DirectedCycle(IDiGraph G)
        {
            onStack = new bool[G.V];
            edgeTo  = new int[G.V];
            marked  = new bool[G.V];
            for (int v = 0; v < G.V; v++)
            {
                if (!marked[v])
                {
                    Dfs(G, v);
                }
            }
        }
 private void Dfs(IDiGraph g, int v)
 {
     Pre.Enqueue(v);
     marked[v] = true;
     foreach (int w in g.Adj(v))
     {
         if (!marked[w])
         {
             Dfs(g, w);
         }
     }
     Post.Enqueue(v);
     ReversePost.Push(v);
 }
        }                                      //顶点的逆后续

        public DepthFirstOrder(IDiGraph G)
        {
            Pre         = new Queue <int>();
            Post        = new Queue <int>();
            ReversePost = new Stack <int>();
            marked      = new bool[G.V];
            for (int v = 0; v < G.V; v++)
            {
                if (!marked[v])
                {
                    Dfs(G, v);
                }
            }
        }
Exemple #17
0
        private void validateOperator(IDiGraph <T> graph)
        {
            if (this.@operator == null)
            {
                throw new ArgumentException("Provide an operator implementation for generic type W during initialization.");
            }

            if (!graph.IsWeightedGraph)
            {
                if ([email protected]() != typeof(int))
                {
                    throw new ArgumentException("Edges of unweighted graphs are assigned an imaginary weight of one (1)." +
                                                "Provide an appropriate IFlowOperators<int> operator implementation during initialization.");
                }
            }
        }
        public KosarajuSCC(IDiGraph G)
        {
            this.G = G;
            marked = new bool[G.V];
            id     = new int[G.V];
            DepthFirstOrder order = new DepthFirstOrder(G.Reverse());

            foreach (int s in order.ReversePost)
            {
                if (!marked[s])
                {
                    Dfs(G, s);
                    Count++;
                }
            }
        }
        /// <summary>
        /// Returns true if a cycle exists
        /// </summary>
        public bool HasCycle(IDiGraph <T> graph)
        {
            var visiting = new HashSet <T>();
            var visited  = new HashSet <T>();

            foreach (var vertex in graph.VerticesAsEnumberable)
            {
                if (!visited.Contains(vertex.Key))
                {
                    if (dfs(vertex, visited, visiting))
                    {
                        return(true);
                    }
                }
            }

            return(false);
        }
Exemple #20
0
        public List <MinCutEdge <T> > ComputeMinCut(IDiGraph <T> graph,
                                                    T source, T sink)
        {
            if (this.@operator == null)
            {
                throw new ArgumentException("Provide an operator implementation for generic type W during initialization.");
            }

            if (!graph.IsWeightedGraph)
            {
                if ([email protected]() != typeof(int))
                {
                    throw new ArgumentException("Edges of unweighted graphs are assigned an imaginary weight of one (1)." +
                                                "Provide an appropriate IFlowOperators<int> operator implementation during initialization.");
                }
            }

            var edmondsKarpMaxFlow = new EdmondKarpMaxFlow <T, W>(@operator);

            var maxFlowResidualGraph = edmondsKarpMaxFlow
                                       .computeMaxFlowAndReturnResidualGraph(graph, source, sink);

            //according to Min Max theory
            //the Min Cut can be obtained by Finding edges
            //from Reachable Vertices from Source
            //to unreachable vertices in residual graph
            var reachableVertices = getReachable(maxFlowResidualGraph, source);

            var result = new List <MinCutEdge <T> >();

            foreach (var vertex in reachableVertices)
            {
                foreach (var edge in graph.GetVertex(vertex).OutEdges)
                {
                    //if unreachable
                    if (!reachableVertices.Contains(edge.TargetVertexKey))
                    {
                        result.Add(new MinCutEdge <T>(vertex, edge.TargetVertexKey));
                    }
                }
            }

            return(result);
        }
Exemple #21
0
        private WeightedDiGraph <T, W> clone(IDiGraph <T> graph)
        {
            var newGraph = new WeightedDiGraph <T, W>();

            foreach (var vertex in graph.VerticesAsEnumberable)
            {
                newGraph.AddVertex(vertex.Key);
            }

            foreach (var vertex in graph.VerticesAsEnumberable)
            {
                foreach (var edge in vertex.OutEdges)
                {
                    newGraph.AddEdge(vertex.Key, edge.TargetVertexKey, edge.Weight <W>());
                }
            }

            return(newGraph);
        }
Exemple #22
0
        /// <summary>
        /// Compute max flow by searching a path
        /// and then augmenting the residual graph until
        /// no more path exists in residual graph with possible flow.
        /// </summary>

        public W ComputeMaxFlow(IDiGraph <T> graph,
                                T source, T sink)
        {
            validateOperator(graph);

            var residualGraph = createResidualGraph(graph);

            var path = DFS(residualGraph, source, sink);

            var result = @operator.defaultWeight;

            while (path != null)
            {
                result = @operator.AddWeights(result, augmentResidualGraph(residualGraph, path));
                path   = DFS(residualGraph, source, sink);
            }

            return(result);
        }
Exemple #23
0
        /// <summary>
        /// Create a clone graph with reverse edge directions.
        /// </summary>
        private IDiGraph <T> reverseEdges(IDiGraph <T> graph)
        {
            var newGraph = new DiGraph <T>();

            foreach (var vertex in graph.VerticesAsEnumberable)
            {
                newGraph.AddVertex(vertex.Key);
            }

            foreach (var vertex in graph.VerticesAsEnumberable)
            {
                foreach (var edge in vertex.OutEdges)
                {
                    //reverse edge
                    newGraph.AddEdge(edge.TargetVertexKey, vertex.Key);
                }
            }

            return(newGraph);
        }
Exemple #24
0
        /// <summary>
        /// Return all flow Paths.
        /// </summary>
        public List <List <T> > ComputeMaxFlowAndReturnFlowPath(IDiGraph <T> graph,
                                                                T source, T sink)
        {
            validateOperator(graph);

            var residualGraph = createResidualGraph(graph);

            List <T> path = DFS(residualGraph, source, sink);

            var flow = @operator.defaultWeight;

            var result = new List <List <T> >();

            while (path != null)
            {
                result.Add(path);
                flow = @operator.AddWeights(flow, augmentResidualGraph(residualGraph, path));
                path = DFS(residualGraph, source, sink);
            }

            return(result);
        }
Exemple #25
0
        /// <summary>
        /// Rreturns a list of Strongly Connected components in this graph.
        /// </summary>
        public List <List <T> > FindStronglyConnectedComponents(IDiGraph <T> graph)
        {
            var result = new List <List <T> >();

            var discoveryTimeMap = new Dictionary <T, int>();
            var lowTimeMap       = new Dictionary <T, int>();
            var pathStack        = new Stack <T>();
            var pathStackMap     = new HashSet <T>();
            var discoveryTime    = 0;

            foreach (var vertex in graph.VerticesAsEnumberable)
            {
                if (!discoveryTimeMap.ContainsKey(vertex.Key))
                {
                    DFS(vertex,
                        result,
                        discoveryTimeMap, lowTimeMap,
                        pathStack, pathStackMap, ref discoveryTime);
                }
            }

            return(result);
        }
Exemple #26
0
        /// <summary>
        /// Returns the vertices in Topologically Sorted Order.
        /// </summary>
        public List <T> GetTopSort(IDiGraph <T> graph)
        {
            var pathStack = new Stack <T>();
            var visited   = new HashSet <T>();

            //we need a loop so that we can reach all vertices
            foreach (var vertex in graph.VerticesAsEnumberable)
            {
                if (!visited.Contains(vertex.Key))
                {
                    dfs(vertex, visited, pathStack);
                }
            }

            //now just pop the stack to result
            var result = new List <T>();

            while (pathStack.Count > 0)
            {
                result.Add(pathStack.Pop());
            }

            return(result);
        }
Exemple #27
0
        FindAllPairShortestPaths(IDiGraph <T> graph)
        {
            if (this.@operator == null)
            {
                throw new ArgumentException("Provide an operator implementation for generic type W during initialization.");
            }

            if (!graph.IsWeightedGraph)
            {
                if ([email protected]() != typeof(int))
                {
                    throw new ArgumentException("Edges of unweighted graphs are assigned an imaginary weight of one (1)." +
                                                "Provide an appropriate IJohnsonsShortestPathOperators<T, int> operator implementation during initialization.");
                }
            }

            var workGraph = clone(graph);

            //add an extra vertex with zero weight edge to all nodes
            var randomVetex = @operator.RandomVertex();

            if (workGraph.Vertices.ContainsKey(randomVetex))
            {
                throw new Exception("Random Vertex is not unique for given graph.");
            }
            workGraph.AddVertex(randomVetex);

            foreach (var vertex in workGraph.Vertices)
            {
                workGraph.AddEdge(randomVetex, vertex.Key, @operator.DefaultValue);
            }

            //now compute shortest path from random vertex to all other vertices
            var bellmanFordSp  = new BellmanFordShortestPath <T, W>(@operator);
            var bellFordResult = new Dictionary <T, W>();

            foreach (var vertex in workGraph.Vertices)
            {
                var result = bellmanFordSp.FindShortestPath(workGraph, randomVetex, vertex.Key);
                bellFordResult.Add(vertex.Key, result.Length);
            }

            //adjust edges so that all edge values are now +ive
            foreach (var vertex in workGraph.Vertices)
            {
                foreach (var edge in vertex.Value.OutEdges.ToList())
                {
                    vertex.Value.OutEdges[edge.Key] = @operator.Substract(
                        @operator.Sum(bellFordResult[vertex.Key], edge.Value),
                        bellFordResult[edge.Key.Key]);
                }
            }

            workGraph.RemoveVertex(randomVetex);
            //now run dijikstra for all pairs of vertices
            //trace path
            var dijikstras  = new DijikstraShortestPath <T, W>(@operator);
            var finalResult = new List <AllPairShortestPathResult <T, W> >();

            foreach (var vertexA in workGraph.Vertices)
            {
                foreach (var vertexB in workGraph.Vertices)
                {
                    var source = vertexA.Key;
                    var dest   = vertexB.Key;
                    var sp     = dijikstras.FindShortestPath(workGraph, source, dest);

                    //no path exists
                    if (sp.Length.Equals(@operator.MaxValue))
                    {
                        continue;
                    }

                    var distance = sp.Length;
                    var path     = sp.Path;

                    finalResult.Add(new AllPairShortestPathResult <T, W>(source, dest, distance, path));
                }
            }

            return(finalResult);
        }
Exemple #28
0
 /// <inheritdoc />
 public IEnumerable <IDiGraph <T, TWeight> > GetCyclicalComponents <T, TWeight>(IDiGraph <T, TWeight> graph)
     where TWeight : IComparable <TWeight> =>
 GetStronglyConnectedComponents(graph).Where(IsCyclicSubGraph);
Exemple #29
0
 /// <inheritdoc />
 public bool IsAcyclic <T, TWeight>(IDiGraph <T, TWeight> graph) where TWeight : IComparable <TWeight> =>
 !GetCyclicalComponents(graph).Any();
Exemple #30
0
 private static bool IsCyclicSubGraph <T, TWeight>(IDiGraph <T, TWeight> graph) where TWeight : IComparable <TWeight>
 => 1 < graph.Vertices.Count() || graph.Vertices.Count() == 1 && graph.Edges.Any();