示例#1
0
        public static bool RemoveEdgeFromGraph(UndirectedGraph <int, Edge <int> > originalGraph, Edge <int> edgeToRemove, out UndirectedGraph <int, Edge <int> > resultGraph)
        {
            var  edgeComparer = new EdgeComparer();
            var  edges        = new HashSet <Edge <int> >(originalGraph.Edges, edgeComparer);
            bool isRemoved    = edges.Remove(edgeToRemove);

            if (!isRemoved)
            {
                resultGraph = originalGraph;
                return(false);
            }
            else
            {
                resultGraph = GetGraphFromEdges(edges);
                return(true);
            }
        }
示例#2
0
        private static List <Edge <int> > LiftingV3(List <Edge <int> > augmentingPath, List <Edge <int> > blossom, UndirectedGraph <int, Edge <int> > g, Edge <int> edgeBetweenTrees, int superVertex, List <Edge <int> > currentMatching)
        {
            var edgeComparer    = new EdgeComparer();
            var matchedVertices = GetAllVerticesForPath(currentMatching);
            var matchedEdges    = new HashSet <Edge <int> >(currentMatching, new EdgeComparer());

            GetPathEnds(augmentingPath, out int firstVertex, out int lastVertex);
            var superVertexEdges = new List <Edge <int> >();

            foreach (var edge in augmentingPath)
            {
                if (edge.Source == superVertex || edge.Target == superVertex)
                {
                    superVertexEdges.Add(edge);
                }
            }
            if (superVertexEdges.Count > 2)
            {
                throw new ArgumentException("There can be max 2 edges adjacent to superVertex in augmenting path");
            }
            var superVertexUnmatchedEdge = superVertexEdges.FirstOrDefault(edge => !matchedEdges.Contains(edge));
            var superVertexMatchedEdge   = superVertexEdges.FirstOrDefault(edge => matchedEdges.Contains(edge));

            if (superVertexEdges.Count == 2 && (superVertexMatchedEdge == null || superVertexUnmatchedEdge == null))
            {
                throw new ArgumentException("Super vertex edges found incorrectly");
            }
            if (superVertexEdges.Count == 1 && (superVertexMatchedEdge == null && superVertexUnmatchedEdge == null))
            {
                throw new ArgumentException("Super vertex edges found incorrectly");
            }

            var pathForMatchedEdge   = new List <Edge <int> >();
            var pathForUnmatchedEdge = new List <Edge <int> >();
            var pathForBlossom       = new List <Edge <int> >();

            if (superVertexMatchedEdge != null)
            {
                int oppositeToSuperVertex1 = GetTargetVertex(superVertexMatchedEdge, superVertex);
                if (oppositeToSuperVertex1 != firstVertex && oppositeToSuperVertex1 != lastVertex)
                {
                    var augmentingPathGraph1 = GetGraphFromEdges(augmentingPath);
                    var edges = new HashSet <Edge <int> >(g.Edges, edgeComparer);
                    if (!edges.Contains(superVertexMatchedEdge))
                    {
                        throw new ArgumentException("Graph should contain matched Edge");
                    }
                    bool wasRemoved = RemoveEdgeFromGraph(augmentingPathGraph1, superVertexMatchedEdge, out augmentingPathGraph1);
                    //bool remove1 = augmentingPathGraph1.RemoveEdge(superVertexMatchedEdge);
                    //bool remove2 = augmentingPathGraph1.RemoveEdge(new Edge<int>(superVertexMatchedEdge.Target, superVertexMatchedEdge.Source));
                    if (!wasRemoved)
                    {
                        throw new ArgumentException("Edge was not removed");
                    }
                    bool pathFound = DFSSearch(firstVertex, oppositeToSuperVertex1, augmentingPathGraph1, out List <Edge <int> > path1);
                    if (pathFound)
                    {
                        pathForMatchedEdge = path1;
                    }
                    else
                    {
                        pathFound = DFSSearch(oppositeToSuperVertex1, lastVertex, augmentingPathGraph1, out List <Edge <int> > path2);
                        if (!pathFound)
                        {
                            throw new ArgumentException("Path should exist");
                        }
                        pathForMatchedEdge = path2;
                    }
                }
                pathForMatchedEdge.Add(superVertexMatchedEdge);
            }

            if (superVertexUnmatchedEdge != null)
            {
                int oppositeToSuperVertex2 = GetTargetVertex(superVertexUnmatchedEdge, superVertex);
                if (oppositeToSuperVertex2 != firstVertex && oppositeToSuperVertex2 != lastVertex)
                {
                    var augmentingPathGraph2 = GetGraphFromEdges(augmentingPath);
                    var edges = new HashSet <Edge <int> >(g.Edges, edgeComparer);
                    //if (!edges.Contains(superVertexUnmatchedEdge))
                    //    throw new ArgumentException("Graph should contain matched Edge");
                    bool wasRemoved = RemoveEdgeFromGraph(augmentingPathGraph2, superVertexUnmatchedEdge, out augmentingPathGraph2);
                    //bool remove1 = augmentingPathGraph2.RemoveEdge(superVertexUnmatchedEdge);
                    //bool remove2 = augmentingPathGraph2.RemoveEdge(new Edge<int>(superVertexUnmatchedEdge.Target, superVertexUnmatchedEdge.Source));
                    if (!wasRemoved)
                    {
                        throw new ArgumentException("Edge was not removed");
                    }
                    bool pathFound = DFSSearch(firstVertex, oppositeToSuperVertex2, augmentingPathGraph2, out List <Edge <int> > path1);
                    if (pathFound)
                    {
                        pathForUnmatchedEdge = path1;
                    }
                    else
                    {
                        pathFound = DFSSearch(oppositeToSuperVertex2, lastVertex, augmentingPathGraph2, out List <Edge <int> > path2);
                        if (!pathFound)
                        {
                            throw new ArgumentException("Path should exist");
                        }
                        pathForUnmatchedEdge = path2;
                    }
                }
                //pathForUnmatchedEdge.Add(superVertexUnmatchedEdge);
            }

            Edge <int> firstEdgeInPath       = null;
            var        blossomVertices       = GetAllVerticesForPath(blossom);
            int        oppositeToSuperVertex = GetTargetVertex(superVertexUnmatchedEdge, superVertex);
            int        firstVertexOnBlossom  = -1;

            foreach (var edge in g.AdjacentEdges(oppositeToSuperVertex))
            {
                int target = GetTargetVertex(edge, oppositeToSuperVertex);
                if (blossomVertices.Contains(target))
                {
                    firstEdgeInPath      = edge;
                    firstVertexOnBlossom = target;
                    break;
                }
            }
            if (firstEdgeInPath == null || firstVertexOnBlossom < 0)
            {
                throw new ArgumentException("This path should be found");
            }
            if (!matchedVertices.Contains(firstVertexOnBlossom))
            {
                return(augmentingPath);
            }
            if (firstVertexOnBlossom == superVertex)
            {
                pathForBlossom = new List <Edge <int> > {
                    firstEdgeInPath
                };
            }
            else
            {
                var blossomGraph = GetGraphFromEdges(blossom);
                foreach (var edge in blossomGraph.AdjacentEdges(firstVertexOnBlossom))
                {
                    int target = GetTargetVertex(edge, firstVertexOnBlossom);
                    if (!matchedVertices.Contains(target))
                    {
                        bool edgeRemoved = blossomGraph.RemoveEdge(edge);
                        if (!edgeRemoved)
                        {
                            throw new ArgumentException("Edge should be removed");
                        }
                        break;
                    }
                }

                bool pathFound = DFSSearch(firstVertexOnBlossom, superVertex, blossomGraph, out pathForBlossom);
                pathForBlossom.Add(firstEdgeInPath);
            }

            // Merge results for all the 3 paths
            var augmentingPathGraph = GetGraphFromEdges(pathForBlossom);

            if (superVertexMatchedEdge != null)
            {
                augmentingPathGraph.AddVerticesAndEdgeRange(pathForMatchedEdge);
            }
            if (superVertexUnmatchedEdge != null)
            {
                augmentingPathGraph.AddVerticesAndEdgeRange(pathForUnmatchedEdge);
            }

            if (!augmentingPathGraph.Vertices.Contains(firstVertex) || !augmentingPathGraph.Vertices.Contains(lastVertex))
            {
                throw new ArgumentException("First and last vertex must be a part of the graph");
            }
            var liftedAugmentingPathFound = DFSSearch(firstVertex, lastVertex, augmentingPathGraph, out List <Edge <int> > liftedAugmentingPath);

            if (!liftedAugmentingPathFound)
            {
                throw new ArgumentException("Lifted augmenting path not found");
            }
            return(liftedAugmentingPath);
        }