Пример #1
0
        private List <Edge> FindAugmentingPath(UndirectedGraph graph, List <Edge> currentMatching)
        {
            Dictionary <int, UndirectedGraph> forest = new Dictionary <int, UndirectedGraph>();
            List <int>  unmarkedV = new List <int>(Enumerable.Range(0, graph.VerticeCount()));
            List <Edge> unmarkedE = graph.Edges.Except(currentMatching, new EdgeComparer()).ToList();
            List <int>  exposedV  = GetExposedV(graph, currentMatching);

            foreach (int v in exposedV)
            {
                forest[v] = new UndirectedGraph(graph.VerticeCount());
            }
            while (GetEvenDistanceV(forest, unmarkedV) != -1)
            {
                int targetV = GetEvenDistanceV(forest, unmarkedV);
                while (GetUnmarkedE(targetV, unmarkedE) != null)
                {
                    Edge targetE = GetUnmarkedE(targetV, unmarkedE);
                    int  secondV = targetE.V1 == targetV ? targetE.V2 : targetE.V1;
                    if (!InForest(forest, secondV))
                    {
                        //secondV is matched, so add its matched edge and targetE to forest[targetV]
                        int matchingV = GetMatchingV(currentMatching, secondV);
                        forest[GetVerticeRoot(forest, targetV)].AddEdge(targetE.V1, targetE.V2);
                        forest[GetVerticeRoot(forest, targetV)].AddEdge(secondV, matchingV);
                    }
                    else
                    {
                        if (!OddForestDistance(forest, secondV))
                        {
                            if (GetVerticeRoot(forest, targetV) != GetVerticeRoot(forest, secondV))
                            {
                                return(GetPathFromRoot(forest[GetVerticeRoot(forest, targetV)], GetVerticeRoot(forest, targetV), targetV).
                                       Concat(new List <Edge>()
                                {
                                    new Edge(targetV, secondV)
                                }).
                                       Concat(GetPathToRoot(forest[GetVerticeRoot(forest, secondV)], GetVerticeRoot(forest, secondV), secondV)).ToList());
                            }
                            else
                            {
                                //Contract a blossom in G
                                List <Edge>     blossom         = GetBlossom(targetV, secondV, forest);
                                UndirectedGraph contractedGraph = Contract(graph, blossom, targetV);
                                List <Edge>     newMatching     = Contract(currentMatching, blossom, targetV);
                                List <Edge>     path            = FindAugmentingPath(contractedGraph, newMatching);
                                return(Lift(path, blossom, targetV, graph, currentMatching));
                            }
                        }
                    }
                    unmarkedE.Remove(targetE);
                }
                unmarkedV.Remove(targetV);
            }
            return(new List <Edge>());
        }
Пример #2
0
        private List <int> GetExposedV(UndirectedGraph graph, List <Edge> currentMatching)
        {
            List <int> exposedV = new List <int>(Enumerable.Range(0, graph.VerticeCount()));

            foreach (Edge e in currentMatching)
            {
                exposedV.Remove(e.V1);
                exposedV.Remove(e.V2);
            }
            return(exposedV);
        }