Пример #1
0
        private void ENUM_PERFECT_MATCHINGS_ITER(BipartiteGraph G, EdgeList M, List <string> M_String)
        {
            /*-------------------------------
             * Step1: If G has no edge, stop.
             * ---------------------------------*/

            if (G.Edges.Count == 0)
            {
                return;
            }

            /*-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
             * Step2 & Step3: Choosing Edge-e and Finding Cycle. //Cycle is found using DFS algorithm and edge-e is chosen such that it is in cycle and in matching M ( and not in M'(which is found next)) of the directed graph(DG)
             * ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/

            BipartiteGraph d_G  = G.Clone().GetDirectedGraphAsPerMatching(M);
            var            CIDG = new CycleInDirectedGraph(d_G); //Class object containing Method to detect and get cycle in a grah

            if (!CIDG.HasCycle)
            {
                return;
            }
            List <GraphNode> cycleInDG = CIDG.Cycle;                         //returns here cycle in a directed graph DG
            //Cycle: Vertices can not repeate and Edges can not repeat
            EdgeList      cycleInDG_Edges          = d_G.ToEdges(cycleInDG); //cycleInDG is list of nodes in a Cycle . Here this list is converted into edges in the Cycle.
            List <string> cycleInDG_EdgesAsStrings = d_G.ToEdgesAsStrings(cycleInDG);
            EdgeList      M_corresp = CorrespondingListForTheGraph(d_G, M);
            Edge          e         = chooseEdge(M_corresp, cycleInDG_Edges); //Edge - e is chosen here.
            ////String e_string = chooseEdgeStringVersion(M_String, cycleInDG_EdgesAsStrings); //Edge - e is chosen here.

            /*---------------------------------------------------------------------------------
             * Step4: Find a perfect matching M' by exchanging edges along the cycle. Output M'.
             * ------------------------------------------------------------------------------------*/

            EdgeList      M_dash        = ExchangingEdgesAlongCycle(M_corresp, cycleInDG_Edges);                          /* Write code here to find M' here */
            List <string> M_dash_String = ExchangingEdgesAlongCycleStringVersion(M_String, cycleToStringList(cycleInDG)); //this.matchingToStringList(M)

            //list_PerfectMatchings.Add(M_dash);
            list_AllPerfectMatchings.Add(M_dash_String);



            /*-----------------------------------------------------------------------------------------
             * Step5: Find G+(e), trim unnecessary edges of G+(e) using SCC decomposition algorithm.
             * ------------------------------------------------------------------------------------------*/

            //Graph<T> G_plus = G_plus_e(DG.Clone(), e); //G+(e) is obtained here
            BipartiteGraph           G_plus      = G_plus_e(G.Clone(), e);
            List <List <GraphNode> > sCCs_G_plus = TarjanCycleDetect.DetectCycle(G_plus); // /SCCs in G+(e) to trim unnecessary edges

            /* Write code for trimming edges here*/

            /*-----------------------------------------------------------------------------------------------------------
             * Step6: Enumerate all perfect matchings including e by ENUM_PERFECT_MATCHING_ITER with obtained graph and M
             * ------------------------------------------------------------------------------------------------------------*/

            ENUM_PERFECT_MATCHINGS_ITER(G_plus, M, M_String); //recursive call with G+(e) and M  // !! here G+(e) graph will not have edge which is there in matching

            /*-----------------------------------------------------------------------------------------
            *  Step7: Find G-(e), trim unnecessary edges of G-(e) using SCC decomposition algorithm.
            *  -----------------------------------------------------------------------------------------*/

            BipartiteGraph G_minus = G_minus_e(G.Clone(), e);                               //G+(e) is obtained here
            ////G_minus.plotMethod(this.goView1);
            List <List <GraphNode> > sCCs_G_minus = TarjanCycleDetect.DetectCycle(G_minus); // SCCs in G-(e) to trim unnecessary edges

            /* Write code for trimming edges here*/


            /*---------------------------------------------------------------------------------------------------------------
            *  Step8: Enumerate all perfect matchings not including e by ENUM_PERFECT_MATCHING_ITER with obtained graph and M'
            *  ---------------------------------------------------------------------------------------------------------------*/

            ENUM_PERFECT_MATCHINGS_ITER(G_minus, matchingStringsToEdgeList(G_minus, M_dash_String), M_dash_String); //recursive call with G+(e) and M
        }
        private void ENUM_MAXIMUM_MATCHINGS_ITER(BipartiteGraph G, EdgeList M, List <String> M_String, int recursionLevel)
        {
            if (recursionLevel > MaximumRecursionLevel)
            {
                return;
            }

            //This code has been tested and works fine for test-case under consideration

            /*-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
             * Step1: If G has no edge, stop.
             * --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
            if (G.Edges.Count <= 1)
            {
                return;
            }



            /*-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
             * Step2: If D(G,M) contains no cylce, Go to Step8.
             * --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
            BipartiteGraph d_G  = G.Clone().GetDirectedGraphAsPerMatching(M);
            var            CIDG = new CycleInDirectedGraph(d_G); //Class object containing Method to detect and get cycle in a grah

            if (!CIDG.HasCycle)
            {
                goto Step8;
            }



            /*--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
             * Step3 & 4: Choose an edge e as the same manner in ENUM_PERFECT_MATCHINGS_ITER. Find a cycle containing e by a depth-first-search algorithm.
             * ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
            //Cycle is found using DFS algorithm and edge-e is chosen such that it is in cycle and in matching M ( and not in M'(which is found next)) of the directed graph(DG)
            List <GraphNode> cycleInDG                = CIDG.Cycle;             //returns here cycle in a directed graph DG //'Cycle': Vertices can not repeate and Edges can not repeat
            EdgeList         cycleInDG_Edges          = d_G.ToEdges(cycleInDG); //cycleInDG is list of nodes in a Cycle . Here this list is converted into edges in the Cycle.
            List <String>    cycleInDG_EdgesAsStrings = d_G.ToEdgesAsStrings(cycleInDG);
            EdgeList         M_corresp                = CorrespondingListForTheGraph(d_G, M);
            Edge             e = chooseEdge(M_corresp, cycleInDG_Edges); //Edge - e is chosen here.



            /*--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
             * Step5: Exchange edges along the cycle and output the obtained maximum matching M'.
             * ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
            List <String> M_dash_String = ExchangingEdgesAlongCycleOrPathStringVersion(M_String, cycleToStringList(cycleInDG));//this.matchingToStringList(M)

            M_dash_String.Sort();
            list_AllMaximumMatchings.Add(M_dash_String);



            /*-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
             * Step6: Enumerate all maximum matchings including e by ENUM_MAXIMUM_MATCHINGS_ITER with G+(e), M and trimmed D(G+(e), M\e).
             * --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
            BipartiteGraph G_plus = G_plus_e(G.Clone(), e);

            ENUM_MAXIMUM_MATCHINGS_ITER(G_plus, M, M_String, ++recursionLevel); //recursive call with G+(e) and M  // !! here G+(e) graph will not have edge which is there in matching



            /*-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
             * Step7: Enumerate all maximum matchings not including e by ENUM_MAXIMUM_MATCHINGS_ITER with G-(e), M' and trimmed D(G-(e), M'). Stop.
             * --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
            BipartiteGraph G_minus = G_minus_e(G.Clone(), e);                                                                         //G-(e) is obtained here

            ENUM_MAXIMUM_MATCHINGS_ITER(G_minus, matchingStringsToEdgeList(G_minus, M_dash_String), M_dash_String, ++recursionLevel); //recursive call with G-(e) and M
            return;



            /*-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
             * Step8: Find a feasible path with length 2 and generate a new maximum matching M'. Let e be the edge of the path not included in M.
             * ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
            //'Feasible Path':
            Step8 :;
            NodeList unmatchedVertices = d_G.GetUnmatchedVertices(M_String);
            var      path = new List <String>();

            foreach (GraphNode Gn in d_G)
            {
                if (Gn.NodeType == GraphNode.Type.Type1)
                {
                    var dfs = new DepthFirstSearch(d_G, Gn, unmatchedVertices);
                    path = dfs.length2Path;
                    if (path.Count == 3 && isFeasiblePath(d_G, path, unmatchedVertices))
                    {
                        break;
                    }
                }
                if ((Gn.NodeType == GraphNode.Type.Type2) && !(unmatchedVertices.Contains(Gn)))
                {
                    var dfs = new DepthFirstSearch(d_G, Gn, unmatchedVertices);
                    path = dfs.length2Path;
                    if (path.Count == 3 && isFeasiblePath(d_G, path, unmatchedVertices))
                    {
                        break;
                    }
                }
            }

            if (path.Count != 3)
            {
                return;
            }

            e = getEdgeInPathNotInM(G, M_String, pathToEdgesAsStrings(G, path));

            M_dash_String = ExchangingEdgesAlongCycleOrPathStringVersion(M_String, pathToEdgesAsStrings(G, path));
            M_dash_String.Sort();
            list_AllMaximumMatchings.Add(M_dash_String);


            /*--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
             * Step9: Call ENUM_MAXIMUM+MATCHINGS_ITER(G+(e), M', theta).
             * ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
            G_plus = G_plus_e(G.Clone(), e);
            ENUM_MAXIMUM_MATCHINGS_ITER(G_plus, matchingStringsToEdgeList(G_plus, M_dash_String), M_dash_String, ++recursionLevel);



            /*--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
            *  Step10: Call ENUM_MAXIMUM+MATCHINGS_ITER(G-(e), M, theta).
            *  --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/

            G_minus = G_minus_e(G.Clone(), e); //G-(e) is obtained here
            ENUM_MAXIMUM_MATCHINGS_ITER(G_minus, M, M_String, ++recursionLevel);
        }