Пример #1
0
        /// <summary>
        /// We can get the min cut using the max-flow min-cut theorm, which states that the max flow in a n/w = min-cut of the network.
        /// Steps:
        /// 1. Run FordFulkerson algo to get the residual graph.
        /// 2. Find the set of vertices that can be reached from the source vertex.
        /// 3. Get all the edges from vertices in this set to the vertices which are not present in this set.
        /// this will give all the edges of the min cut.
        ///
        /// The running time of this algo is same as the ford fulkerson's max flow algo with edward karp optimization
        /// O(V(E^2))
        /// </summary>
        /// <param name="graph">graph object</param>
        /// <param name="startId">id of the source vertex</param>
        /// <param name="endId">id of the sink vertex</param>
        /// <returns></returns>
        public List <string> GetMinCut(GraphWithFwdEdges graph, string startId, string endId)
        {
            List <string> setOfEdges = new List <string>();

            // 1. Run FordFulkerson algo to get the residual graph.
            FordFulkersonEdmondKarp ffkp = new FordFulkersonEdmondKarp();

            ffkp.GetTheMaxFlow(graph, startId, endId);

            // 2. Find the set of vertices that can be reached from the source vertex.
            Dictionary <GraphVertex, bool> setOfVerticesFromSource = GetAllVerticesThatCanBeReachedFromSrc(graph, startId);

            // 3.Get all the forward edges from vertices in this set to the vertices which are not present in this set.
            foreach (GraphVertex vertex in setOfVerticesFromSource.Keys)
            {
                foreach (GraphVertex neighbour in vertex.Neighbours)
                {
                    string edgeId = vertex.Id + "#" + neighbour.Id;
                    if (graph.IsEdgeFwd[edgeId] && !setOfVerticesFromSource.ContainsKey(neighbour))
                    {
                        // the graph edge should not have 0 flow and also should not be present in the current set(found after the cut)
                        setOfEdges.Add(edgeId);
                    }
                }
            }

            return(setOfEdges);
        }
        /// <summary>
        /// Create a source vertex which has edge with unit weight to all the employees.
        /// Note we are using unit edge weight cause each employee can take up only one job.
        /// Also create a sink vertex, all the jobs will have a directed edge towards the sink and the edge weight is 1.
        /// The unit edge weight is used cause each job must be done by one employee.
        /// </summary>
        /// <param name="employeeJobPreference">dictionary having key as the employeeid and value as the list of job ids which are prefered</param>
        public MaximumBipartiteMatching(Dictionary <string, List <string> > employeeJobPreference)
        {
            // initialize the graph
            Graph = new GraphWithFwdEdges();
            foreach (string employeeId in employeeJobPreference.Keys)
            {
                Graph.AddEdge(StartId, employeeId, 1);        // Add fwd edge
                Graph.AddEdge(employeeId, StartId, 0, false); // Add backedge
                foreach (string jobId in employeeJobPreference[employeeId])
                {
                    Graph.AddEdge(employeeId, jobId, 1);        // Add fwdEdge
                    Graph.AddEdge(jobId, employeeId, 0, false); // Add back edge

                    // Add the directed edge towards sink from the job id
                    Graph.AddEdge(jobId, SinkId, 1);        // Add fwdEdge
                    Graph.AddEdge(SinkId, jobId, 0, false); // Add back edge
                }
            }
        }
Пример #3
0
        public static void TestMinCut()
        {
            MinCut mc = new MinCut();

            /*
             * (A)<------3--------(B)
             | X               /x
             |  \             / |
             |    3         4   |
             |      \      /    |
             | 3        \  x      |
             |         (C)      1
             |       /   \      |
             |     /       \    |
             |    1          2  |
             |  x             x |
             | (D)-------2------>(E)
             |                  |
             |                  |
             |                  |
             | 6                  1
             |                  |
             | x                  X
             | (F)-------9------->(G)
             */
            GraphWithFwdEdges graph = new GraphWithFwdEdges();

            graph.AddEdge("A", "B", 3);
            graph.AddEdge("B", "A", 0, false);
            graph.AddEdge("A", "D", 3);
            graph.AddEdge("D", "A", 0, false);
            graph.AddEdge("D", "E", 2);
            graph.AddEdge("E", "D", 0, false);
            graph.AddEdge("E", "B", 1);
            graph.AddEdge("B", "E", 0, false);
            graph.AddEdge("C", "A", 3);
            graph.AddEdge("A", "C", 0, false);
            graph.AddEdge("B", "C", 4);
            graph.AddEdge("C", "B", 0, false);
            graph.AddEdge("C", "D", 1);
            graph.AddEdge("D", "C", 0, false);
            graph.AddEdge("C", "E", 2);
            graph.AddEdge("E", "C", 0, false);
            graph.AddEdge("D", "F", 6);
            graph.AddEdge("F", "D", 0, false);
            graph.AddEdge("F", "G", 9);
            graph.AddEdge("G", "F", 0, false);
            graph.AddEdge("E", "G", 1);
            graph.AddEdge("G", "E", 0, false);

            List <string> setOfEdges = mc.GetMinCut(graph, "A", "G");

            PrintEdges(setOfEdges);


            graph = new GraphWithFwdEdges();
            graph.AddEdge("0", "1", 16);
            graph.AddEdge("1", "2", 10);
            graph.AddEdge("0", "2", 13);
            graph.AddEdge("2", "1", 4);
            graph.AddEdge("1", "3", 12);
            graph.AddEdge("3", "2", 9);
            graph.AddEdge("2", "4", 14);
            graph.AddEdge("4", "3", 7);
            graph.AddEdge("4", "5", 4);
            graph.AddEdge("3", "5", 20);

            graph.AddEdge("1", "0", 0, false);
            graph.AddEdge("2", "0", 0, false);
            graph.AddEdge("3", "1", 0, false);
            graph.AddEdge("2", "3", 0, false);
            graph.AddEdge("4", "2", 0, false);
            graph.AddEdge("3", "4", 0, false);
            graph.AddEdge("5", "4", 0, false);
            graph.AddEdge("5", "3", 0, false);
            setOfEdges = mc.GetMinCut(graph, "0", "5");
            PrintEdges(setOfEdges);
        }