private bool Attempt(double eps)
        {
            Initialize();
            int            numRoots      = 0;
            ICancelManager cancelManager = Services.CancelManager;

            foreach (TVertex vertex in VisitedGraph.Vertices)
            {
                if (cancelManager.IsCancelling)
                {
                    break;
                }

                // First pass: exploration
                if (!Explore(eps, vertex, ref numRoots))
                {
                    return(false);
                }

                // Second pass: coloration
                Colorize(vertex);
            }

            return(true);
        }
Esempio n. 2
0
        /// <inheritdoc />
        protected override void InternalCompute()
        {
            // If there is a starting vertex, start with him
            if (TryGetRootVertex(out TVertex root))
            {
                OnStartVertex(root);
                Visit(root, 0);
            }

            // Process each vertex
            ICancelManager cancelManager = Services.CancelManager;

            foreach (TVertex vertex in VisitedGraph.Vertices)
            {
                if (cancelManager.IsCancelling)
                {
                    return;
                }

                if (VerticesColors[vertex] == GraphColor.White)
                {
                    OnStartVertex(vertex);
                    Visit(vertex, 0);
                }
            }
        }
Esempio n. 3
0
        /// <inheritdoc />
        protected override void InternalCompute()
        {
            ICancelManager cancelManager = Services.CancelManager;

            while (_taskManager.HasTasks())
            {
                if (cancelManager.IsCancelling)
                {
                    return;
                }

                Task <TVertex, TEdge> task = _taskManager.GetTask();

                if (task.IsResultReady())
                {
                    BestCost   = task.MinCost;
                    ResultPath = task.Path;
                    return;
                }

                if (task.Split(
                        out Task <TVertex, TEdge> task1,
                        out Task <TVertex, TEdge> task2))
                {
                    _taskManager.AddTask(task1);
                    _taskManager.AddTask(task2);
                }
            }
        }
Esempio n. 4
0
        /// <inheritdoc />
        protected override void InternalCompute()
        {
            if (!TryGetRootVertex(out TVertex root))
            {
                throw new InvalidOperationException("Root vertex not set.");
            }

            // Start with root vertex
            OnStartVertex(root);

            ICancelManager cancelManager = Services.CancelManager;

            // Process each out edge of the root one
            foreach (TEdge edge in VisitedGraph.OutEdges(root))
            {
                if (cancelManager.IsCancelling)
                {
                    return;
                }

                if (!EdgesColors.ContainsKey(edge))
                {
                    OnStartEdge(edge);
                    Visit(edge, 0);
                }
            }
        }
Esempio n. 5
0
        /// <inheritdoc />
        protected override void InternalCompute()
        {
            ICancelManager cancelManager = Services.CancelManager;

            while (_heap.Count != 0)
            {
                if (cancelManager.IsCancelling)
                {
                    break;
                }

                TVertex vertex = _heap.Dequeue();
                if (InDegrees[vertex] != 0)
                {
                    throw new NonAcyclicGraphException();
                }

                _sortedVertices.Add(vertex);
                OnVertexAdded(vertex);

                // Update the count of its adjacent vertices
                foreach (TEdge edge in VisitedGraph.OutEdges(vertex))
                {
                    --InDegrees[edge.Target];

                    Debug.Assert(InDegrees[edge.Target] >= 0);

                    _heap.Update(edge.Target);
                }
            }

            SortedVertices = _sortedVertices.ToArray();
        }
Esempio n. 6
0
        /// <inheritdoc />
        protected override void InternalCompute()
        {
            ICancelManager cancelManager            = Services.CancelManager;
            IDictionary <TVertex, double> tempRanks = new Dictionary <TVertex, double>();

            // Create filtered graph
            var filterGraph = new FilteredBidirectionalGraph <TVertex, TEdge, IBidirectionalGraph <TVertex, TEdge> >(
                VisitedGraph,
                new InDictionaryVertexPredicate <TVertex, double>(Ranks).Test,
                edge => true);

            int    iteration = 0;
            double error;

            do
            {
                if (cancelManager.IsCancelling)
                {
                    return;
                }

                // Compute page ranks
                error = 0;
                foreach (KeyValuePair <TVertex, double> pair in Ranks)
                {
                    if (cancelManager.IsCancelling)
                    {
                        return;
                    }

                    TVertex vertex = pair.Key;
                    double  rank   = pair.Value;

                    // Compute ARi
                    double r = 0;
                    foreach (TEdge edge in filterGraph.InEdges(vertex))
                    {
                        r += Ranks[edge.Source] / filterGraph.OutDegree(edge.Source);
                    }

                    // Add sourceRank and store it
                    double newRank = (1 - Damping) + Damping * r;
                    tempRanks[vertex] = newRank;

                    // Compute deviation
                    error += Math.Abs(rank - newRank);
                }

                // Swap ranks
                IDictionary <TVertex, double> temp = Ranks;
                Ranks     = tempRanks;
                tempRanks = temp;

                ++iteration;
            } while (error > Tolerance && iteration < MaxIterations);
        }
Esempio n. 7
0
        /// <inheritdoc />
        protected override void InternalCompute()
        {
            ICancelManager cancelManager = Services.CancelManager;

            while (_heap.Count != 0)
            {
                if (cancelManager.IsCancelling)
                {
                    return;
                }

                TVertex vertex = _heap.Dequeue();
                int     degree = Degrees[vertex];
                // 0 => isolated vertex
                // 1 => single adjacent edge
                if (degree != 0 && degree != 1 && !AllowCyclicGraph)
                {
                    throw new NonAcyclicGraphException();
                }

                _sortedVertices.Add(vertex);
                OnVertexAdded(vertex);

                // Update the count of its adjacent vertices
                UpdateAdjacentDegree(vertex);
            }

            SortedVertices = _sortedVertices.ToArray();

            #region Local function

            void UpdateAdjacentDegree(TVertex vertex)
            {
                foreach (TEdge edge in VisitedGraph.AdjacentEdges(vertex).Where(e => !e.IsSelfEdge()))
                {
                    TVertex other = edge.GetOtherVertex(vertex);
                    --Degrees[other];

                    if (Degrees[other] < 0 && !AllowCyclicGraph)
                    {
                        throw new InvalidOperationException("Degree is negative, and cannot be.");
                    }

                    if (_heap.Contains(other))
                    {
                        _heap.Update(other);
                    }
                }
            }

            #endregion
        }
Esempio n. 8
0
        private void Visit([NotNull] TEdge startingEdge, int depth)
        {
            Debug.Assert(startingEdge != null);
            Debug.Assert(depth >= 0);

            if (depth > MaxDepth)
            {
                return;
            }

            // Mark edge as gray
            EdgesColors[startingEdge] = GraphColor.Gray;
            // Add edge to the search tree
            OnTreeEdge(startingEdge);

            ICancelManager cancelManager = Services.CancelManager;

            // Iterate over out-edges
            foreach (TEdge edge in VisitedGraph.OutEdges(startingEdge.Target))
            {
                if (cancelManager.IsCancelling)
                {
                    return;
                }

                // Check edge is not explored yet,
                // if not, explore it
                if (!EdgesColors.TryGetValue(edge, out GraphColor color))
                {
                    OnDiscoverTreeEdge(startingEdge, edge);
                    Visit(edge, depth + 1);
                }
                else
                {
                    if (color == GraphColor.Gray)
                    {
                        OnBackEdge(edge);
                    }
                    else
                    {
                        OnForwardOrCrossEdge(edge);
                    }
                }
            }

            // All out-edges have been explored
            EdgesColors[startingEdge] = GraphColor.Black;
            OnFinishEdge(startingEdge);
        }
        /// <inheritdoc />
        protected override void InternalCompute()
        {
            if (!TryGetRootVertex(out TVertex rootVertex))
            {
                throw new InvalidOperationException("Root vertex not set.");
            }

            ICancelManager cancelManager = Services.CancelManager;

            // Process root
            ClearTree(rootVertex);
            SetInTree(rootVertex);

            foreach (TVertex vertex in VisitedGraph.Vertices)
            {
                if (cancelManager.IsCancelling)
                {
                    break;
                }

                // First pass: exploration
                {
                    var     visitedEdges = new Dictionary <TEdge, int>();
                    TVertex current      = vertex;
                    while (NotInTree(current) && TryGetSuccessor(visitedEdges, current, out TEdge successor))
                    {
                        visitedEdges[successor] = 0;
                        Tree(current, successor);
                        if (!TryGetNextInTree(current, out current))
                        {
                            break;
                        }
                    }
                }

                // Second pass: coloration
                {
                    TVertex current = vertex;
                    while (NotInTree(current))
                    {
                        SetInTree(current);
                        if (!TryGetNextInTree(current, out current))
                        {
                            break;
                        }
                    }
                }
            }
        }
Esempio n. 10
0
        /// <inheritdoc />
        protected override void AugmentGraph()
        {
            ICancelManager cancelManager = Services.CancelManager;

            foreach (TVertex vertex in VisitedGraph.Vertices)
            {
                if (cancelManager.IsCancelling)
                {
                    break;
                }

                AddAugmentedEdge(SuperSource, vertex);
                AddAugmentedEdge(vertex, SuperSink);
            }
        }
        /// <inheritdoc />
        protected override void InternalCompute()
        {
            ICancelManager cancelManager = Services.CancelManager;

            InitializeInDegrees();

            while (_heap.Count != 0)
            {
                if (cancelManager.IsCancelling)
                {
                    return;
                }

                TVertex vertex = _heap.Dequeue();
                if (Degrees[vertex] != 0 && !AllowCyclicGraph)
                {
                    throw new NonAcyclicGraphException();
                }

                SortedVertices.Add(vertex);
                OnVertexAdded(vertex);

                // Update the count of its adjacent vertices
                UpdateAdjacentDegree(vertex);
            }

            #region Local function

            void UpdateAdjacentDegree(TVertex vertex)
            {
                foreach (TEdge edge in VisitedGraph.AdjacentEdges(vertex).Where(e => !e.IsSelfEdge()))
                {
                    --Degrees[edge.Target];

                    if (Degrees[edge.Target] < 0 && !AllowCyclicGraph)
                    {
                        throw new InvalidOperationException("Degree is negative, and cannot be.");
                    }

                    if (_heap.Contains(edge.Target))
                    {
                        _heap.Update(edge.Target);
                    }
                }
            }

            #endregion
        }
        /// <inheritdoc />
        protected override void Initialize()
        {
            // Put all edges to white
            ICancelManager cancelManager = Services.CancelManager;

            foreach (TEdge edge in VisitedGraph.Edges)
            {
                if (cancelManager.IsCancelling)
                {
                    return;
                }

                EdgesColors[edge] = GraphColor.White;
                OnEdgeInitialized(edge);
            }
        }
        /// <inheritdoc />
        protected override void InternalCompute()
        {
            ICancelManager cancelManager = Services.CancelManager;

            DirectedGraph = new DirectedGraph();

            var nodes = new List <DirectedGraphNode>(VisitedGraph.VertexCount);

            foreach (TVertex vertex in VisitedGraph.Vertices)
            {
                if (cancelManager.IsCancelling)
                {
                    return;
                }

                var node = new DirectedGraphNode {
                    Id = _vertexIdentities(vertex)
                };
                OnFormatNode(vertex, node);
                nodes.Add(node);
            }

            DirectedGraph.Nodes = nodes.ToArray();

            var links = new List <DirectedGraphLink>(VisitedGraph.EdgeCount);

            foreach (TEdge edge in VisitedGraph.Edges)
            {
                if (cancelManager.IsCancelling)
                {
                    return;
                }

                var link = new DirectedGraphLink
                {
                    Label  = _edgeIdentities(edge),
                    Source = _vertexIdentities(edge.Source),
                    Target = _vertexIdentities(edge.Target)
                };
                OnFormatEdge(edge, link);
                links.Add(link);
            }

            DirectedGraph.Links = links.ToArray();

            OnFormatGraph();
        }
        private void Visit([NotNull] TEdge rootEdge, int depth)
        {
            Debug.Assert(rootEdge != null);

            if (depth > MaxDepth)
            {
                return;
            }

            ICancelManager cancelManager = Services.CancelManager;

            // Mark edge as gray
            EdgesColors[rootEdge] = GraphColor.Gray;
            // Add edge to the search tree
            OnTreeEdge(rootEdge);

            // Iterate over out-edges
            foreach (TEdge edge in VisitedGraph.OutEdges(rootEdge.Target))
            {
                if (cancelManager.IsCancelling)
                {
                    return;
                }

                // Check edge is not explored yet,
                // If not, explore it
                if (EdgesColors[edge] == GraphColor.White)
                {
                    OnDiscoverTreeEdge(rootEdge, edge);
                    Visit(edge, depth + 1);
                }
                else if (EdgesColors[edge] == GraphColor.Gray)
                {
                    // Edge is being explored
                    OnBackEdge(edge);
                }
                else
                {
                    // Edge is black
                    OnForwardOrCrossEdge(edge);
                }
            }

            // All out-edges have been explored
            EdgesColors[rootEdge] = GraphColor.Black;
            OnFinishEdge(rootEdge);
        }
        /// <inheritdoc />
        protected override void InternalCompute()
        {
            ICancelManager cancelManager = Services.CancelManager;

            InitializeInDegrees();

            while (_heap.Count != 0)
            {
                if (cancelManager.IsCancelling)
                {
                    break;
                }

                TVertex vertex = _heap.Dequeue();
                if (InDegrees[vertex] != 0)
                {
                    throw new NonAcyclicGraphException();
                }

                SortedVertices.Add(vertex);
                OnVertexAdded(vertex);

                // Update the count of its successor vertices
                IEnumerable <TEdge> successorEdges = _direction == TopologicalSortDirection.Forward
                    ? VisitedGraph.OutEdges(vertex)
                    : VisitedGraph.InEdges(vertex);

                foreach (TEdge edge in successorEdges)
                {
                    if (edge.IsSelfEdge())
                    {
                        continue;
                    }

                    TVertex successor = _direction == TopologicalSortDirection.Forward
                        ? edge.Target
                        : edge.Source;

                    --InDegrees[successor];

                    Debug.Assert(InDegrees[successor] >= 0);

                    _heap.Update(successor);
                }
            }
        }
        /// <inheritdoc />
        protected override void InternalCompute()
        {
            ICancelManager cancelManager = Services.CancelManager;

            if (cancelManager.IsCancelling)
            {
                return;
            }

            // Start with root vertex
            if (TryGetRootVertex(out TVertex root))
            {
                OnStartVertex(root);

                // Process each out edge of the root one
                foreach (TEdge edge in VisitedGraph.OutEdges(root))
                {
                    if (cancelManager.IsCancelling)
                    {
                        return;
                    }

                    if (EdgesColors[edge] == GraphColor.White)
                    {
                        OnStartEdge(edge);
                        Visit(edge, 0);
                    }
                }
            }

            // Process the rest of the graph edges
            foreach (TEdge edge in VisitedGraph.Edges)
            {
                if (cancelManager.IsCancelling)
                {
                    return;
                }

                if (EdgesColors[edge] == GraphColor.White)
                {
                    OnStartEdge(edge);
                    Visit(edge, 0);
                }
            }
        }
        private void Visit([NotNull] TVertex u, int depth)
        {
            Debug.Assert(u != null);

            if (depth > MaxDepth)
            {
                return;
            }

            VertexColors[u] = GraphColor.Gray;
            OnDiscoverVertex(u);

            ICancelManager cancelManager = Services.CancelManager;

            foreach (TEdge edge in VisitedGraph.OutEdges(u))
            {
                if (cancelManager.IsCancelling)
                {
                    return;
                }

                OnExamineEdge(edge);
                TVertex v = edge.Target;

                if (!VertexColors.TryGetValue(v, out GraphColor vColor))
                {
                    OnTreeEdge(edge);
                    Visit(v, depth + 1);
                }
                else
                {
                    if (vColor == GraphColor.Gray)
                    {
                        OnBackEdge(edge);
                    }
                    else
                    {
                        OnForwardOrCrossEdge(edge);
                    }
                }
            }

            VertexColors[u] = GraphColor.Black;
            OnVertexFinished(u);
        }
        /// <summary>
        /// Runs a random tree generation.
        /// </summary>
        public void RandomTree()
        {
            ICancelManager cancelManager = Services.CancelManager;

            double eps = 1;
            bool   success;

            do
            {
                if (cancelManager.IsCancelling)
                {
                    break;
                }

                eps    /= 2;
                success = Attempt(eps);
            } while (!success);
        }
        /// <inheritdoc />
        protected override void Initialize()
        {
            base.Initialize();

            // Initialize vertices
            ICancelManager cancelManager = Services.CancelManager;

            if (cancelManager.IsCancelling)
            {
                return;
            }

            foreach (TVertex vertex in VisitedGraph.Vertices)
            {
                VerticesColors[vertex] = GraphColor.White;
                OnVertexInitialized(vertex);
            }
        }
Esempio n. 20
0
        private void FlushVisitQueue()
        {
            ICancelManager cancelManager = Services.CancelManager;

            while (_vertexQueue.Count > 0)
            {
                if (cancelManager.IsCancelling)
                {
                    return;
                }

                TVertex u = _vertexQueue.Dequeue();
                OnExamineVertex(u);
                foreach (TEdge edge in OutEdgesFilter(VisitedGraph.OutEdges(u)))
                {
                    TVertex v = edge.Target;
                    OnExamineEdge(edge);

                    GraphColor vColor = VerticesColors[v];
                    if (vColor == GraphColor.White)
                    {
                        OnTreeEdge(edge);
                        VerticesColors[v] = GraphColor.Gray;
                        OnDiscoverVertex(v);
                        _vertexQueue.Enqueue(v);
                    }
                    else
                    {
                        OnNonTreeEdge(edge);
                        if (vColor == GraphColor.Gray)
                        {
                            OnGrayTarget(edge);
                        }
                        else
                        {
                            OnBlackTarget(edge);
                        }
                    }
                }

                VerticesColors[u] = GraphColor.Black;
                OnVertexFinished(u);
            }
        }
Esempio n. 21
0
        private void Visit([NotNull] TVertex u, int depth)
        {
            Debug.Assert(u != null);

            if (depth > MaxDepth)
            {
                return;
            }

            VerticesColors[u] = GraphColor.Gray;
            OnDiscoverVertex(u);

            ICancelManager cancelManager = Services.CancelManager;

            foreach (TEdge edge in VisitedGraph.OutEdges(u))
            {
                if (cancelManager.IsCancelling)
                {
                    return;
                }

                OnExamineEdge(edge);
                TVertex v = edge.Target;
                ProcessEdge(depth, v, edge);
            }

            foreach (TEdge edge in VisitedGraph.InEdges(u))
            {
                if (cancelManager.IsCancelling)
                {
                    return;
                }

                OnExamineEdge(edge);
                TVertex v = edge.Source;
                ProcessEdge(depth, v, edge);
            }

            VerticesColors[u] = GraphColor.Black;
            OnVertexFinished(u);
        }
        private void FlushVisitQueue()
        {
            ICancelManager cancelManager = Services.CancelManager;

            while (_vertexQueue.Count > 0)
            {
                if (cancelManager.IsCancelling)
                {
                    return;
                }

                TVertex u = _vertexQueue.Dequeue();

                OnExamineVertex(u);

                ExploreAdjacentEdges(u);

                VerticesColors[u] = GraphColor.Black;
                OnVertexFinished(u);
            }
        }
        /// <inheritdoc />
        protected override void InternalCompute()
        {
            ICancelManager cancelManager = Services.CancelManager;

            var sets = new ForestDisjointSet <TVertex>(VisitedGraph.VertexCount);

            foreach (TVertex vertex in VisitedGraph.Vertices)
            {
                sets.MakeSet(vertex);
            }

            if (cancelManager.IsCancelling)
            {
                return;
            }

            var queue = new BinaryQueue <TEdge, double>(_edgeWeights);

            foreach (TEdge edge in VisitedGraph.Edges)
            {
                queue.Enqueue(edge);
            }

            if (cancelManager.IsCancelling)
            {
                return;
            }

            while (queue.Count > 0)
            {
                TEdge edge = queue.Dequeue();
                OnExamineEdge(edge);

                if (!sets.AreInSameSet(edge.Source, edge.Target))
                {
                    OnTreeEdge(edge);
                    sets.Union(edge.Source, edge.Target);
                }
            }
        }
        /// <inheritdoc />
        protected override void InternalCompute()
        {
            ICancelManager cancelManager = Services.CancelManager;

            if (cancelManager.IsCancelling)
            {
                return;
            }

            TVertex[] vertices = VisitedGraph.Vertices.ToArray();

            // Walk each vertices and make sure cost self-cost 0
            foreach (TVertex vertex in vertices)
            {
                _data[new SEquatableEdge <TVertex>(vertex, vertex)] = new VertexData(0, default(TEdge));
            }

            if (cancelManager.IsCancelling)
            {
                return;
            }

            // Iterate k, i, j
            foreach (TVertex vk in vertices)
            {
                if (cancelManager.IsCancelling)
                {
                    return;
                }

                FillIData(vertices, vk);
            }

            // Check negative cycles
            CheckNegativeCycles(vertices);
        }
        /// <inheritdoc />
        protected override void AugmentGraph()
        {
            ICancelManager cancelManager = Services.CancelManager;

            foreach (TVertex vertex in VisitedGraph.Vertices)
            {
                if (cancelManager.IsCancelling)
                {
                    break;
                }

                // Is source
                if (VisitedGraph.IsInEdgesEmpty(vertex))
                {
                    AddAugmentedEdge(SuperSource, vertex);
                }

                // Is sink
                if (VisitedGraph.IsOutEdgesEmpty(vertex))
                {
                    AddAugmentedEdge(vertex, SuperSink);
                }
            }
        }
        /// <inheritdoc />
        protected override void InternalCompute()
        {
            TVertex root = GetAndAssertRootInGraph();

            if (!TryGetTargetVertex(out TVertex target))
            {
                throw new InvalidOperationException("Target vertex not set.");
            }
            if (!VisitedGraph.ContainsVertex(target))
            {
                throw new VertexNotFoundException("Target vertex is not part of the graph.");
            }

            // Little shortcut
            if (root.Equals(target))
            {
                OnTargetReached();
                return; // Found it
            }

            ICancelManager cancelManager = Services.CancelManager;
            var            open          = new BinaryHeap <double, TVertex>(_distanceRelaxer.Compare);

            // (1) Place the initial node in Open, with all its operators marked unused
            open.Add(0, root);
            Dictionary <TEdge, GraphColor> operators = VisitedGraph.OutEdges(root).ToDictionary(edge => edge, edge => GraphColor.White);

            while (open.Count > 0)
            {
                if (cancelManager.IsCancelling)
                {
                    return;
                }

                // (3) Else, choose an Open node n of lowest cost for expansion
                KeyValuePair <double, TVertex> entry = open.RemoveMinimum();
                double  cost = entry.Key;
                TVertex n    = entry.Value;

                // (4) If node n is a target node, terminate with success
                if (n.Equals(target))
                {
                    OnTargetReached();
                    return;
                }

                // (5) Else, expand node n, generating all
                // successors n' reachable via unused legal operators,
                // compute their cost and delete node n
                ExpandNode(n, operators, cost, open);

#if DEBUG
                OperatorMaxCount = Math.Max(OperatorMaxCount, operators.Count);
#endif

                // (6) In a directed graph, generate each predecessor node n via an unused operator
                // and create dummy nodes for each with costs of infinity
                foreach (TEdge edge in VisitedGraph.InEdges(n))
                {
                    if (operators.TryGetValue(edge, out GraphColor edgeColor) &&
                        edgeColor == GraphColor.Gray)
                    {
                        // Delete node n
                        operators.Remove(edge);
                    }
                }
            }
        }
        /// <inheritdoc />
        protected override void InternalCompute()
        {
            ICancelManager cancelManager = Services.CancelManager;

            BipartiteToMaximumFlowGraphAugmentorAlgorithm <TVertex, TEdge> augmentor = null;
            ReversedEdgeAugmentorAlgorithm <TVertex, TEdge> reverser = null;

            try
            {
                if (cancelManager.IsCancelling)
                {
                    return;
                }

                // Augmenting the graph
                augmentor = new BipartiteToMaximumFlowGraphAugmentorAlgorithm <TVertex, TEdge>(
                    this,
                    VisitedGraph,
                    SourceToVertices,
                    VerticesToSink,
                    VertexFactory,
                    EdgeFactory);
                augmentor.Compute();

                if (cancelManager.IsCancelling)
                {
                    return;
                }

                // Adding reverse edges
                reverser = new ReversedEdgeAugmentorAlgorithm <TVertex, TEdge>(
                    VisitedGraph,
                    EdgeFactory);
                reverser.AddReversedEdges();

                if (cancelManager.IsCancelling)
                {
                    return;
                }

                // Compute maximum flow
                var flow = new EdmondsKarpMaximumFlowAlgorithm <TVertex, TEdge>(
                    this,
                    VisitedGraph,
                    edge => 1.0,
                    EdgeFactory,
                    reverser);

                flow.Compute(augmentor.SuperSource, augmentor.SuperSink);

                if (cancelManager.IsCancelling)
                {
                    return;
                }

                foreach (TEdge edge in VisitedGraph.Edges)
                {
                    if (Math.Abs(flow.ResidualCapacities[edge]) < float.Epsilon)
                    {
                        if (edge.Source.Equals(augmentor.SuperSource) ||
                            edge.Source.Equals(augmentor.SuperSink) ||
                            edge.Target.Equals(augmentor.SuperSource) ||
                            edge.Target.Equals(augmentor.SuperSink))
                        {
                            // Skip all edges that connect to SuperSource or SuperSink
                            continue;
                        }

                        _matchedEdges.Add(edge);
                    }
                }
            }
            finally
            {
                if (reverser != null && reverser.Augmented)
                {
                    reverser.RemoveReversedEdges();
                }
                if (augmentor != null && augmentor.Augmented)
                {
                    augmentor.Rollback();
                }
            }
        }
        /// <inheritdoc />
        protected override void InternalCompute()
        {
            // Create condensed graph
            CondensedGraph = new BidirectionalGraph <TGraph, CondensedEdge <TVertex, TEdge, TGraph> >(false);
            if (VisitedGraph.VertexCount == 0)
            {
                return;
            }

            // Compute strongly connected components
            var components     = new Dictionary <TVertex, int>(VisitedGraph.VertexCount);
            int componentCount = ComputeComponentCount(components);

            ICancelManager cancelManager = Services.CancelManager;

            if (cancelManager.IsCancelling)
            {
                return;
            }

            // Create vertices list
            var condensedVertices = new Dictionary <int, TGraph>(componentCount);

            for (int i = 0; i < componentCount; ++i)
            {
                var vertex = new TGraph();
                condensedVertices.Add(i, vertex);
                CondensedGraph.AddVertex(vertex);
            }

            // Adding vertices
            foreach (TVertex vertex in VisitedGraph.Vertices)
            {
                condensedVertices[components[vertex]].AddVertex(vertex);
            }

            if (cancelManager.IsCancelling)
            {
                return;
            }

            // Condensed edges
            var condensedEdges = new Dictionary <EdgeKey, CondensedEdge <TVertex, TEdge, TGraph> >(componentCount);

            // Iterate over edges and condensate graph
            foreach (TEdge edge in VisitedGraph.Edges)
            {
                // Get component ids
                int sourceID = components[edge.Source];
                int targetID = components[edge.Target];

                // Get vertices
                TGraph sources = condensedVertices[sourceID];
                if (sourceID == targetID)
                {
                    sources.AddEdge(edge);
                    continue;
                }

                // At last add edge
                var edgeKey = new EdgeKey(sourceID, targetID);
                if (!condensedEdges.TryGetValue(edgeKey, out CondensedEdge <TVertex, TEdge, TGraph> condensedEdge))
                {
                    TGraph targets = condensedVertices[targetID];

                    condensedEdge = new CondensedEdge <TVertex, TEdge, TGraph>(sources, targets);
                    condensedEdges.Add(edgeKey, condensedEdge);
                    CondensedGraph.AddEdge(condensedEdge);
                }

                condensedEdge.Edges.Add(edge);
            }
        }
        /// <inheritdoc />
        protected override void InternalCompute()
        {
            ICancelManager cancelManager = Services.CancelManager;

            TVertex root = GetAndAssertRootInGraph();

            if (!TryGetTargetVertex(out TVertex target))
            {
                throw new InvalidOperationException("Target vertex not set.");
            }
            if (!VisitedGraph.ContainsVertex(target))
            {
                throw new VertexNotFoundException("Target vertex is not part of the graph.");
            }

            // Start by building the minimum tree starting from the target vertex.
            ComputeMinimumTree(
                target,
                out IDictionary <TVertex, TEdge> successors,
                out IDictionary <TVertex, double> distances);

            if (cancelManager.IsCancelling)
            {
                return;
            }

            var queue       = new FibonacciQueue <DeviationPath, double>(deviationPath => deviationPath.Weight);
            int vertexCount = VisitedGraph.VertexCount;

            // First shortest path
            EnqueueFirstShortestPath(queue, successors, distances, root);

            while (queue.Count > 0 &&
                   ComputedShortestPathCount < ShortestPathCount)
            {
                if (cancelManager.IsCancelling)
                {
                    return;
                }

                DeviationPath deviation = queue.Dequeue();

                // Turn into path
                var path = new List <TEdge>();
                for (int i = 0; i < deviation.DeviationIndex; ++i)
                {
                    path.Add(deviation.ParentPath[i]);
                }
                path.Add(deviation.DeviationEdge);

                int startEdge = path.Count;
                AppendShortestPath(path, successors, deviation.DeviationEdge.Target);

                Debug.Assert(Math.Abs(deviation.Weight - path.Sum(e => _edgeWeights(e))) < float.Epsilon);
                Debug.Assert(path.Count > 0);

                // Add to list if has no cycle
                if (!path.HasCycles <TVertex, TEdge>())
                {
                    AddComputedShortestPath(path);
                }

                // Append new deviation paths
                if (path.Count < vertexCount)
                {
                    EnqueueDeviationPaths(
                        queue,
                        root,
                        distances,
                        path.ToArray(),
                        startEdge);
                }
            }
        }