//This code has been tested and works fine for test-case under consideration private void ENUM_MAXIMUM_MATCHINGS_ITER(BipartiteGraph G, EdgeList M, MatchingList matching, int recursionLevel) { //System.Console.WriteLine(recursionLevel); //System.Console.WriteLine(recursionLevel); if (recursionLevel >= MaximumRecursionLevel) { return; } /*------------------------------------------------------------------------------------------------------------------- * 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 directedGraph = G.Clone().GetDirectedGraphAsPerMatching(M); var CIDG = new CycleInDirectedGraph(directedGraph); //Class object containing Method to detect and get cycle in a grah Edge e; MatchingList Mdash; BipartiteGraph Gplus, Gminus; if (CIDG.HasCycle) { /*------------------------------------------------------------------------------------------------------------------- * 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> cycle = CIDG.Cycle; //returns here cycle in a directed graph DG //'Cycle': Vertices can not repeate and Edges can not repeat EdgeList cycleEdges = directedGraph.ToEdges(cycle); //cycleInDG is list of nodes in a Cycle . Here this list is converted into edges in the Cycle. EdgeList MEdgeList = CorrespondingEdgeList(directedGraph, M); e = ChooseEdge(MEdgeList, cycleEdges); //Edge - e is chosen here. /*------------------------------------------------------------------------------------------------------------------- * Step5: Exchange edges along the cycle and output the obtained maximum matching M'. * ------------------------------------------------------------------------------------------------------------------*/ Mdash = ExchangeEdgesAlongCycleOrPath(matching, CycleToMatching(cycle)); //this.matchingToStringList(M) Mdash.Sort(); AddMatching(Mdash); if (MinimumCost > minimumAchievableCost) { /*------------------------------------------------------------------------------------------------------------------- * Step6: Enumerate all maximum matchings including e by ENUM_MAXIMUM_MATCHINGS_ITER with G+(e), M and trimmed D(G+(e), M\e). * ------------------------------------------------------------------------------------------------------------------*/ Gplus = BuildGplus(G, e); //G+(e) is obtained here //!! here G+(e) graph will not have edge which is there in matching ENUM_MAXIMUM_MATCHINGS_ITER(Gplus, M, matching, recursionLevel + 1); //recursive call with G+(e) and M /*------------------------------------------------------------------------------------------------------------------- * Step7: Enumerate all maximum matchings not including e by ENUM_MAXIMUM_MATCHINGS_ITER with G-(e), M' and trimmed D(G-(e), M'). Stop. * ------------------------------------------------------------------------------------------------------------------*/ Gminus = BuildGminus(G, e); //G-(e) is obtained here ENUM_MAXIMUM_MATCHINGS_ITER(Gminus, MatchingToEdgeList(Gminus, Mdash), Mdash, recursionLevel + 1); //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': NodeList unmatchedVertices = directedGraph.GetUnmatchedVertices(matching); var path = new MatchingList(); foreach (GraphNode node in directedGraph) { if (node.NodeType == GraphNode.Type.Type1 || node.NodeType == GraphNode.Type.Type2 && !unmatchedVertices.Contains(node)) { var dfs = new DepthFirstSearch(directedGraph, node, unmatchedVertices); path = dfs.length2Path; if (path.Count == 3 && IsFeasiblePath(directedGraph, path, unmatchedVertices)) { break; } } } if (path.Count != 3) { return; } e = GetEdgeInPathNotInM(G, matching, PathToMatching(G, path)); Mdash = ExchangeEdgesAlongCycleOrPath(matching, PathToMatching(G, path)); Mdash.Sort(); AddMatching(Mdash); if (MinimumCost > minimumAchievableCost) { /*------------------------------------------------------------------------------------------------------------------- * Step9: Call ENUM_MAXIMUM+MATCHINGS_ITER(G+(e), M', theta). * -* ------------------------------------------------------------------------------------------------------------------*/ Gplus = BuildGplus(G, e); //G+(e) is obtained here ENUM_MAXIMUM_MATCHINGS_ITER(Gplus, MatchingToEdgeList(Gplus, Mdash), Mdash, recursionLevel + 1); /*------------------------------------------------------------------------------------------------------------------- * Step10: Call ENUM_MAXIMUM+MATCHINGS_ITER(G-(e), M, theta). * ------------------------------------------------------------------------------------------------------------------*/ Gminus = BuildGminus(G, e); //G-(e) is obtained here ENUM_MAXIMUM_MATCHINGS_ITER(Gminus, M, matching, recursionLevel + 1); } }
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); }