/// <summary>
        /// Recursive DFS subroutine used by Ford fulkerson's algorithm
        /// </summary>
        /// <param name="vertexId"></param>
        /// <param name="endId"></param>
        /// <param name="backtrack"></param>
        /// <returns></returns>
        private bool DFS(string vertexId, string endId, Dictionary <string, string> backtrack)
        {
            if (!string.IsNullOrEmpty(vertexId))
            {
                // Check Error condition

                if (vertexId == endId)
                {
                    //We have found a path
                    return(true);
                }
                else
                {
                    GraphVertex currentVertex = Graph.AllVertices[vertexId];
                    foreach (GraphVertex neighbour in currentVertex.Neighbours)
                    {
                        string edgeId = currentVertex.Id + "#" + neighbour.Id;
                        if (!backtrack.ContainsKey(neighbour.Id) && Graph.EdgeWeights[edgeId] > 0)
                        {
                            backtrack[neighbour.Id] = currentVertex.Id;

                            if (DFS(neighbour.Id, endId, backtrack))
                            {
                                return(true);
                            }
                        }
                    }
                }
            }
            return(false);
        }
예제 #2
0
        /// <summary>
        /// Gets all the vertices that can be reached from the source
        /// We can do BFS to get this.
        /// </summary>
        /// <param name="graph">graph object</param>
        /// <param name="startId">id of the source vertex</param>
        /// <returns></returns>
        private Dictionary <GraphVertex, bool> GetAllVerticesThatCanBeReachedFromSrc(Graph graph, string startId)
        {
            Dictionary <GraphVertex, bool> setOfVerticesFromSource = new Dictionary <GraphVertex, bool>();

            //Do a BFS to get all the vertices that can be reached from the source
            Queue <GraphVertex> queue  = new Queue <GraphVertex>();
            GraphVertex         source = graph.AllVertices[startId];

            queue.Enqueue(source);
            setOfVerticesFromSource[source] = true;

            while (queue.Count > 0)
            {
                GraphVertex vertex = queue.Dequeue();
                foreach (GraphVertex neighbour in vertex.Neighbours)
                {
                    if (graph.EdgeWeights[vertex.Id + "#" + neighbour.Id] != 0 && !setOfVerticesFromSource.ContainsKey(neighbour))
                    {
                        // Edges with flow 0 should not be considered
                        // vertices in setOfVerticesFromSource keeps track of the visited vertices
                        setOfVerticesFromSource[neighbour] = true;
                        queue.Enqueue(neighbour);
                    }
                }
            }

            return(setOfVerticesFromSource);
        }
        /// <summary>
        /// Do the BFS and get the augmented path and return the current flow in that path
        /// </summary>
        /// <param name="graph">graph object</param>
        /// <param name="startId">source in the graph</param>
        /// <param name="endId">sink in the graph</param>
        /// <returns>current flow in that path</returns>
        public int BFS(Graph graph, string startId, string endId)
        {
            Dictionary <string, string> parentDict = new Dictionary <string, string>();
            Queue <GraphVertex>         queue      = new Queue <GraphVertex>();

            queue.Enqueue(graph.AllVertices[startId]);
            parentDict[startId] = string.Empty;

            while (queue.Count > 0)
            {
                GraphVertex vertex = queue.Dequeue();
                if (vertex.Id == endId)
                {
                    // found the augmented path and get the current flow
                    return(GetTheFlowInCurrentPath(graph, parentDict, startId, endId));
                }
                foreach (GraphVertex neighbour in vertex.Neighbours)
                {
                    if (!parentDict.ContainsKey(neighbour.Id) && graph.EdgeWeights[vertex.Id + "#" + neighbour.Id] != 0)
                    {
                        // the neighbour should not have been visited and the weight of the edge should not be 0
                        queue.Enqueue(neighbour);
                        parentDict[neighbour.Id] = vertex.Id;
                    }
                }
            }
            return(-1);
        }
예제 #4
0
 /// <summary>
 /// Add a weighted directed edge
 /// </summary>
 /// <param name="startId"></param>
 /// <param name="endId"></param>
 /// <param name="weight"></param>
 public void AddEdge(string startId, string endId, int weight)
 {
     if (!AllVertices.ContainsKey(startId))
     {
         AllVertices[startId] = new GraphVertex(startId);
     }
     if (!AllVertices.ContainsKey(endId))
     {
         AllVertices[endId] = new GraphVertex(endId);
     }
     AllVertices[startId].Neighbours.Add(AllVertices[endId]);
     EdgeWeights[startId + "#" + endId] = weight;
 }