/// <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 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; 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 adjacent vertices foreach (TEdge edge in VisitedGraph.OutEdges(vertex)) { if (edge.IsSelfEdge()) { continue; } --InDegrees[edge.Target]; Debug.Assert(InDegrees[edge.Target] >= 0); _heap.Update(edge.Target); } } }
/// <summary> /// Runs the topological sort and puts the result in the provided list. /// </summary> /// <param name="vertices">Set of sorted vertices.</param> public void Compute([NotNull, ItemNotNull] IList <TVertex> vertices) { SortedVertices = vertices ?? throw new ArgumentNullException(nameof(vertices)); SortedVertices.Clear(); Compute(); }
private void OnVertexFinished([NotNull] TVertex vertex) { SortedVertices.Insert(0, vertex); }