示例#1
0
        public EdgeList matchingStringsToEdgeList(BipartiteGraph G, List <string> M_String)
        {
            var       M_to_EdgeListM = new EdgeList();
            GraphNode nd1, nd2;

            foreach (string edg in M_String)
            {
                nd1 = G.GetNode(edg.Split('-')[0]);
                nd2 = G.GetNode(edg.Split('-')[1]);
                if (G.Contains(nd1, nd2))
                {
                    M_to_EdgeListM.Add(G.Edges.FindByNodes(nd1, nd2));
                }
                else if (G.Contains(nd2, nd1))
                {
                    M_to_EdgeListM.Add(G.Edges.FindByNodes(nd2, nd1));
                }
                //else
                //{
                //    M_to_EdgeListM.Add(new Edge(nd1,nd2,0));
                //}
            }

            return(M_to_EdgeListM);
        }
示例#2
0
        private void ENUM_PERFECT_MATCHINGS(BipartiteGraph G)
        {
            /*-------------------------------------------------------------------------------
             * Step1: Find a perfect matching M of G and output M. If M is not found, stop.
             * ---------------------------------------------------------------------------------*/

            //////G.GetAdjListInTheFormOfIntegers(); //Graph is converted to AdjList containing integers which are assigned to each model type node in a graph
            //////IList<int> match = HopcroftKarp.GetMatching(G.AdjList, G.ModSet.Count); //Max. matching algorithm is called here with above AdjList of graph and number of model type nodes in a graph as input
            //This returns matching as IList of integers associated with models

            throw new NotImplementedException();
            EdgeList M = null;             //G.MatchingToEdgeList(); //Edges of Matching

            //// List<List<T>> M_String = G.MatchingToEdgeListAsValues();//Matching Edges as Strings( "Node - Node")

            list_AllPerfectMatchings.Add(matchingToStringList(M));

            /*-----------------------------------------------------------------------------------------------------------
             * Step2: Trim unnecessary edges from G by a strongly connected component decomposition algorithm with D(G,M)
             * -------------------------------------------------------------------------------------------------------------*/

            ////Graph D_GM = Get_D_GM(G.Clone(), M); //Directed graph is obtained here with reversing edges of matchingEdges.
            ////List<List<GraphNode>> sCCs = TarjanCycleDetect.DetectCycle(D_GM); //Need further action on this to trim edges after finding SCCs in a D(G,M). Here only SCCs are found. Edges are not trimmed yet.


            /*----------------------------------------
             * Step3: Call ENUM_PERFECT_MATCHINGS_ITER
             * ------------------------------------------*/
            ENUM_PERFECT_MATCHINGS_ITER(G.Clone(), M, matchingToStringList(M));
            //list_AllPerfectMatchings.Add(M_String);
        }
        //YHB: this method find the graph G_plus by deleting given edge-e, its end vertices and edges associated with the end vertices
        private static BipartiteGraph BuildGplus(BipartiteGraph G, Edge e)
        {
            BipartiteGraph Gplus = G.Clone();

            Gplus.Remove(e.FromNode.Value);
            Gplus.Remove(e.ToNode.Value);
            return(Gplus);
        }
 public MaximumMatchings(BipartiteGraph G, bool getAllMatchings = false)
 {
     list_AllMaximumMatchings.Clear();
     this.G = G;
     this.G.UpdateAddingDuplicateNodes();
     edgePrims = this.G.edgeNodesCost;
     ENUM_MAXIMUM_MATCHINGS(this.G.Clone(), getAllMatchings);
 }
        private bool IsFeasiblePath(BipartiteGraph G, MatchingList path, NodeList unmatchedNodes)
        {
            if (unmatchedNodes.Contains(G.GetNode(path[0])) || unmatchedNodes.Contains(G.GetNode(path[2])))
            {
                return(true);
            }

            return(false);
        }
        public MaximumMatchings2(BipartiteGraph G, bool getAllMatchings = false)
        {
            this.G = G;
            this.G.UpdateAddingDuplicateNodes();
            edgePrims = this.G.edgeNodesCost;

            minimumAchievableCost = 0;

            ENUM_MAXIMUM_MATCHINGS(this.G.Clone(), getAllMatchings);
        }
        private bool isFeasiblePath(BipartiteGraph G, List <String> path, NodeList unmatchedNodes)
        {
            bool isFeasiblePath = false;

            if (unmatchedNodes.Contains(G.GetNode(path[0])) || unmatchedNodes.Contains(G.GetNode(path[2])))
            {
                isFeasiblePath = true;
            }

            return(isFeasiblePath);
        }
        private readonly GraphNode _s;                  //source vertex

        public DepthFirstDirectedPaths(BipartiteGraph G, GraphNode s)
        {
            _marked = new Dictionary <string, bool>();//create dictionary containing vertex, statur(true/false) wehter marked or not for all vertices
            foreach (GraphNode item in G)
            {
                _marked.Add(item.Value.ToString(), false);
            }
            _edgeTo = new Dictionary <String, GraphNode>(); //create a boolean array for all vertices
            _s      = s;                                    //mark the source vertex
            DFS(G, s);
        }
        public static EdgeList Get(BipartiteGraph bipartiteGraph)
        {
            NodeList models = bipartiteGraph.ModelsSet;

            if (models is null)
            {
                throw new ArgumentException("Graph has no models", nameof(bipartiteGraph));
            }

            NodeList variables = bipartiteGraph.VariablesSet;

            if (variables is null)
            {
                throw new ArgumentException("Graph has no variables", nameof(bipartiteGraph));
            }

            //Assigning int values to each node in the graph starting from 0.
            var modNodeIntMap = models.Select((m, i) => new KeyValuePair <string, int>(m.Value, i)).ToDictionary(kvp => kvp.Key, kvp => kvp.Value);

            //Creating Adjacency List
            var adjacencyList = new List <int[]>(variables.Count);

            foreach (GraphNode variable in variables)
            {
                adjacencyList.Add(variable.Neighbors.Select(n => modNodeIntMap[n.Value]).ToArray());
            }

            // Get Match
            IList <int> match = new HopcroftKarpClass(adjacencyList, models.Count).GetMatching();

            // Format the match
            var MatchingEdgeList = new EdgeList();
            int idx = 0;

            foreach (Node variable in variables)
            {
                int matchedModelIndex = match[idx];
                if (matchedModelIndex != -1)
                {
                    string modelValue = modNodeIntMap.FirstOrDefault(x => x.Value == matchedModelIndex).Key;
                    //matching edge list contains edges having direction from
                    MatchingEdgeList.Add(bipartiteGraph.Edges.FindByNodes(variable, bipartiteGraph.GetNode(modelValue)));
                    // 'variables set' to 'model set'
                    idx++;
                }
                else
                {
                    idx++; /*variable associated at that location is unmatched*/                   //Implement to store unmatched variable information if required
                }
            }

            return(MatchingEdgeList);
        }
        /*
         * A recursive function to do depth first search.
         * We start with the source vertex s, find all vertices connected to it and recursively call
         * DFS as move out from s to connected vertices.  We avoid "going backwards" or needlessly looking
         * at all paths by keeping track of which vertices we've already visited using the _marked[] array.
         * We keep track of how we're moving through the graph (from s to v) using _edgeTo[].
         */
        private void DFS(BipartiteGraph G, GraphNode v)
        {
            _marked[v.Value.ToString()] = true;

            foreach (GraphNode w in v.Neighbors)
            {
                if (!_marked[w.Value.ToString()])
                {
                    _edgeTo[w.Value.ToString()] = v;
                    DFS(G, w);
                }
            }
        }
示例#11
0
        private static BipartiteGraph G_plus_e(BipartiteGraph G, Edge e)
        {//YHB: this method find the graph G_plus by deleting given edge-e, its end vertices and edges associated with the end vertices
            BipartiteGraph G_plus = G;

            foreach (GraphNode item in G.Nodes)
            {
            }

            G_plus.Remove(e.FromNode.Value);
            G_plus.Remove(e.ToNode.Value);

            return(G_plus);
        }
        public DFSDirectedCycle(BipartiteGraph g, GraphNode s)
        {
            this.g = g;
            this.s = s;

            marked  = new Dictionary <string, bool>();
            onStack = new Dictionary <string, bool>();

            foreach (GraphNode item in g.Nodes)
            {
                marked.Add(item.Value.ToString(), false);
                onStack.Add(item.Value.ToString(), false);
            }
            findCycle(g, s);
        }
 private static BipartiteGraph dg; //graph directed graph(dg)
 public static List <List <GraphNode> > DetectCycle(BipartiteGraph g)
 {
     StronglyConnectedComponents = new List <List <GraphNode> >();
     index = 0;
     S     = new Stack <GraphNode>();
     dg    = g;
     foreach (GraphNode v in g.Nodes)
     {
         if (v.index < 0)
         {
             strongconnect(v);
         }
     }
     return(StronglyConnectedComponents);
 }
示例#14
0
        private static BipartiteGraph G_minus_e(BipartiteGraph G, Edge e)
        {//YHB: this method find the graph G_minus by deleting given edge-e from the G i.e. given graph
            BipartiteGraph G_minus = G;

            if (G.Contains(G.GetNode(e.FromNode.Value), G.GetNode(e.ToNode.Value)))
            {
                G_minus.RemoveDirectedEdge(G.GetNode(e.FromNode.Value), G.GetNode(e.ToNode.Value));
            }
            else
            {
                G_minus.RemoveDirectedEdge(G.GetNode(e.ToNode.Value), G.GetNode(e.FromNode.Value));
            }


            return(G_minus);
        }
        // A recursive function to find which vertices are connected.
        private void DFS(BipartiteGraph G, GraphNode v)
        {
            length2Path.Add(v.Value);
            if (_path2Count++ == 2)
            {
                return;
            }
            _count++;
            //mark this vertex as being visited
            _marked.Add(v.Value.ToString(), true);

            /*
             * for each vertex w in the linked list for vertex v
             * there exists an edge between v and w
             * if it is not in _marked it hasn't been visited
             * yet so mark it then check all the vertices
             * in it's linked list (it has edges to).
             * */
            foreach (GraphNode w in v.Neighbors)
            {
                if (!_marked.ContainsKey(w.Value.ToString()))
                {
                    if (_path2Count < 2)
                    {
                        DFS(G, w);
                    }
                    else if (_path2Count == 2)
                    {
                        if (unmatchedVertices.Contains(w) || unmatchedVertices.Contains(G.GetNode(length2Path[0])))
                        {
                            DFS(G, w);
                        }
                        else
                        {
                            goto nextNeighbour;
                        }
                    }
                }
                else
                {
                    goto nextNeighbour;
                }

                nextNeighbour :;
            }
            return;
        }
 private bool AllSetMappedCheck(Combination combination)
 {
     if (Type == ReversalType.Inputs)
     {
         BipartiteGraph <Data, Data> G = GraphBuilder.BipartiteFromTwoSets(RequestedInputsToReverse, combination,
                                                                           i => GetDependenciesFromInput(i), i => GetDependenciesFromInput(i));
         List <(Data, Data)> Matching = MaximumMatching.Get(G);
         return(Matching.Count == NinRequest);
     }
     else
     {
         BipartiteGraph <Data, Data> G = GraphBuilder.BipartiteFromTwoSets(RequestedOutputsToReverse, combination,
                                                                           o => GetDependenciesFromOutput(o), o => GetDependenciesFromOutput(o));
         List <(Data, Data)> Matching = MaximumMatching.Get(G);
         return(Matching.Count == NoutRequest);
     }
 }
        //YHB: this method find the graph G_minus by deleting given edge-e from the G i.e. given graph
        private static BipartiteGraph BuildGminus(BipartiteGraph G, Edge e)
        {
            BipartiteGraph Gminus = G.Clone();
            GraphNode      from   = G.GetNode(e.FromNode.Value);
            GraphNode      to     = G.GetNode(e.ToNode.Value);

            if (G.Contains(from, to))
            {
                Gminus.RemoveDirectedEdge(from, to);
            }
            else
            {
                Gminus.RemoveDirectedEdge(to, from);
            }


            return(Gminus);
        }
        private Edge getEdgeInPathNotInM(BipartiteGraph G, List <String> M, List <String> path)
        {
            Edge   e       = null;
            String eString = path.Except(M).ToList()[0];

            String[]  eNodes = eString.Split('-');
            GraphNode nd1    = G.GetNode(eNodes[0]);
            GraphNode nd2    = G.GetNode(eNodes[1]);

            if (G.Contains(nd1, nd2))
            {
                e = G.Edges.FindByNodes(nd1, nd2);
            }
            else if (G.Contains(nd2, nd1))
            {
                e = G.Edges.FindByNodes(nd2, nd1);
            }
            return(e);
        }
        private Edge GetEdgeInPathNotInM(BipartiteGraph G, MatchingList M, MatchingList path)
        {
            Edge   e    = null;
            string edge = path.Except(M).ToList()[0];

            string[]  nodes = edge.Split('-');
            GraphNode node1 = G.GetNode(nodes[0]);
            GraphNode node2 = G.GetNode(nodes[1]);

            if (G.Contains(node1, node2))
            {
                e = G.Edges.FindByNodes(node1, node2);
            }
            else if (G.Contains(node2, node1))
            {
                e = G.Edges.FindByNodes(node2, node1);
            }
            return(e);
        }
示例#20
0
        private static BipartiteGraph Get_D_GM(BipartiteGraph G, EdgeList M)
        {//Get directed graph from given Graph G and matchings(list of matched edges) M
            BipartiteGraph D_GM = G;


            //D_GM.GetAdjListInTheFormOfIntegers(); //Graph is converted to AdjList containing integers which are assigned to each model type node in a graph
            //IList<int> match = HopcroftKarp.GetMatching(D_GM.AdjList, D_GM.ModSet.Count); //Max. matching algorithm is called here with above AdjList of graph and number of model type nodes in a graph as input

            //EdgeList<T> M = D_GM.MatchingToEdgeList(match); //Edges of Matching



            foreach (var edge in M)
            {
                D_GM.ReverseEdgeDirection(edge); //getting directed graph with matched edges with direction from v1 -> v2 and other edges from v2 -> v1
            }

            return(D_GM);
        }
        private MatchingList PathToMatching(BipartiteGraph G, MatchingList path)
        {
            var    matching = new MatchingList();
            string edge;

            for (int i = 0; i < path.Count() - 1; i++)
            {
                if (G.GetNode(path[i]).NodeType == GraphNode.Type.Type2)
                {
                    edge = EdgeString(path[i], path[i + 1]);
                }
                else
                {
                    edge = EdgeString(path[i + 1], path[i]);
                }

                matching.Add(edge);
            }
            return(matching);
        }
        private List <String> pathToEdgesAsStrings(BipartiteGraph G, List <String> path) //04-01-2017 Added for MaximumMatchings
        {
            var    pathAsStrings = new List <String>();
            String str;

            for (int i = 0; i < path.Count() - 1; i++)
            {
                if (G.GetNode(path[i]).NodeType == GraphNode.Type.Type2)
                {
                    str = path[i] + '-' + path[i + 1];
                }
                else
                {
                    str = path[i + 1] + '-' + path[i];
                }

                pathAsStrings.Add(str);
            }
            return(pathAsStrings);
        }
        //public bool hasCycle()
        //{
        //    return hasCycle;
        //}

        public void findCycle(BipartiteGraph g, GraphNode v)
        {
            marked[v.Value.ToString()]  = true;
            onStack[v.Value.ToString()] = true;

            foreach (GraphNode w in v.Neighbors)
            {
                if (!marked[w.Value.ToString()])
                {
                    findCycle(g, w);
                }
                else if (onStack[w.Value.ToString()])
                {
                    hasCycle = true;
                    return;
                }
            }

            onStack[v.Value.ToString()] = false;
        }
        private void ENUM_MAXIMUM_MATCHINGS(BipartiteGraph G, bool getAllMatchings)
        {
            /*--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
            *  Step1: Find a maximum matching M of G and output M.
            *  --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/

            // The maximum mathing
            EdgeList      M        = MaximumMatching.Get(G);
            List <string> M_String = matchingToStringList(M);

            M_String.Sort();

            findOverconstrainedModelsReversalCost(M_String, out OverConstrainedModels, out unmappedVariables, out revCost);
            if (OverConstrainedModels.Count > 0)
            {
                returnTrue = true;
                return;
            }

            list_AllMaximumMatchings.Add(M_String);

            /*--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
            *  Step2: Trim unnecessary arcs from D(G,M) by a strongly connected component decomposition algorithm.
            *  --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
            //Need further action on this to trim edges after finding SCCs in a D(G,M). Here only SCCs are found. Edges are not trimmed yet.

            //Graph D_GM = Get_D_GM(G.Clone(), M); //Directed graph is obtained here with reversing edges of matchingEdges.
            //List<List<GraphNode>> sCCs = TarjanCycleDetect.DetectCycle(D_GM);


            /*-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
             * Step3: Call ENUM_MAXIMUM_MATCHINGS_ITER(G, M, D(G,M))
             * --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
            if (getAllMatchings)
            {
                ENUM_MAXIMUM_MATCHINGS_ITER(G.Clone(), M, matchingToStringList(M), 0);
            }
            //list_AllPerfectMatchings.Add(M_String);

            filterDuplicateMatchings();
        }
示例#25
0
        } = new List <GraphNode>();                                   //YHB stores cycle in sequence

        public CycleInDirectedGraph(BipartiteGraph graph)
        {
            var whiteSet = new HashSet <GraphNode>(graph.Nodes.Select(n => n as GraphNode)); //unvisited
            var graySet  = new HashSet <GraphNode>();                                        //visiting
            var blackSet = new HashSet <GraphNode>();                                        //visite4

            HasCycle = false;
            while (whiteSet.Count > 0)
            {
                stack.Clear();
                GraphNode current = whiteSet.First();                 //ElementAt(random.Next(whiteSet.Count));

                if (DepthFirstSearch(current, whiteSet, graySet, blackSet))
                {
                    Cycle.Add(stack.Pop());
                    Cycle.AddRange(stack.TakeWhile(n => n != Cycle[0]));
                    Cycle.Add(Cycle[0]);
                    HasCycle = true;
                    break;
                }
            }
        }
        private void ENUM_MAXIMUM_MATCHINGS(BipartiteGraph G, bool getAllMatchings)
        {
            /*-------------------------------------------------------------------------------------------------------------------
             * Step1: Find a maximum matching M of G and output M.
             * ------------------------------------------------------------------------------------------------------------------*/
            EdgeList     M        = MaximumMatching.Get(G);  //Edges of Matching
            MatchingList matching = EdgeListToMatching(M);

            matching.Sort();

            FindOverconstrainedModelsReversalCost(matching);
            if (OverConstrainedModels.Count > 0)
            {
                OverConstrained = true;
                return;
            }

            AddMatching(matching);
            if (MinimumCost > minimumAchievableCost)
            {
                /*-------------------------------------------------------------------------------------------------------------------
                 * Step2: Trim unnecessary arcs from D(G,M) by a strongly connected component decomposition algorithm.
                 * ------------------------------------------------------------------------------------------------------------------*/
                //Need further action on this to trim edges after finding SCCs in a D(G,M). Here only SCCs are found. Edges are not trimmed yet.
                //Graph D_GM = Get_D_GM(G.Clone(), M); //Directed graph is obtained here with reversing edges of matchingEdges.
                //List<List<GraphNode>> sCCs = TarjanCycleDetect.DetectCycle(D_GM);


                /*-------------------------------------------------------------------------------------------------------------------
                 * Step3: Call ENUM_MAXIMUM_MATCHINGS_ITER(G, M, D(G,M))
                 * ------------------------------------------------------------------------------------------------------------------*/
                if (getAllMatchings)
                {
                    ENUM_MAXIMUM_MATCHINGS_ITER(G.Clone(), M, matching, 0);
                }
            }

            FilterDuplicateMatchings();
        }
        //This method find the corresponding edges of matching M(which contains edges from other Graph) for the given Graph G
        private static EdgeList CorrespondingEdgeList(BipartiteGraph G, EdgeList M)
        {
            var corresponding = new EdgeList();

            foreach (Edge edge in M)
            {
                GraphNode from = G.GetNode(edge.FromNode.Value);
                GraphNode to   = G.GetNode(edge.ToNode.Value);
                if (from == null && to == null)
                {
                    continue;
                }

                if (G.Edges.FindByNodes(from, to) != null)
                {
                    corresponding.Add(G.Edges.FindByNodes(from, to));
                }
                else
                {
                    corresponding.Add(G.Edges.FindByNodes(to, from));
                }
            }
            return(corresponding);
        }
        private EdgeList MatchingToEdgeList(BipartiteGraph G, MatchingList M_String)
        {
            var edgeList = new EdgeList();

            foreach (string edg in M_String)
            {
                GraphNode node1 = G.GetNode(edg.Split('-')[0]);
                GraphNode node2 = G.GetNode(edg.Split('-')[1]);
                if (G.Contains(node1, node2))
                {
                    edgeList.Add(G.Edges.FindByNodes(node1, node2));
                }
                else if (G.Contains(node2, node1))
                {
                    edgeList.Add(G.Edges.FindByNodes(node2, node1));
                }
                //else
                //{
                //    M_to_EdgeListM.Add(new Edge(nd1,nd2,0));
                //}
            }

            return(edgeList);
        }
示例#29
0
        private static EdgeList CorrespondingListForTheGraph(BipartiteGraph G, EdgeList M) //This method find the corresponding edges of matching M(which contains edges from other Graph) for the given Graph G
        {
            var M_corresp = new EdgeList();

            foreach (Edge edg in M)
            {
                GraphNode frm = G.GetNode(edg.FromNode.Value);
                GraphNode to  = G.GetNode(edg.ToNode.Value);
                if (frm == null && to == null)
                {
                    goto xyz;
                }
                if (G.Edges.FindByNodes(frm, to) != null)
                {
                    M_corresp.Add(G.Edges.FindByNodes(frm, to));
                }
                else
                {
                    M_corresp.Add(G.Edges.FindByNodes(to, frm));
                }
                xyz :;
            }
            return(M_corresp);
        }
        //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);
            }
        }