diff --git a/src/QuikGraph/Algorithms/TopologicalSort/SourceFirstBidirectionalTopologicalSortAlgorithm.cs b/src/QuikGraph/Algorithms/TopologicalSort/SourceFirstBidirectionalTopologicalSortAlgorithm.cs
index a021da400..adbdf3a1f 100644
--- a/src/QuikGraph/Algorithms/TopologicalSort/SourceFirstBidirectionalTopologicalSortAlgorithm.cs
+++ b/src/QuikGraph/Algorithms/TopologicalSort/SourceFirstBidirectionalTopologicalSortAlgorithm.cs
@@ -2,6 +2,8 @@
using System;
#endif
using System.Collections.Generic;
+using JetBrains.Annotations;
+using QuikGraph.Algorithms.Services;
#if SUPPORTS_CONTRACTS
using System.Diagnostics.Contracts;
#endif
@@ -9,12 +11,11 @@
namespace QuikGraph.Algorithms.TopologicalSort
{
- public enum TopologicalSortDirection
- {
- Forward,
- Backward
- }
-
+ ///
+ /// Topological sort algorithm (can be performed on an acyclic bidirectional graph).
+ ///
+ /// Vertex type.
+ /// Edge type.
#if SUPPORTS_SERIALIZATION
[Serializable]
#endif
@@ -22,124 +23,152 @@ public sealed class SourceFirstBidirectionalTopologicalSortAlgorithm>
where TEdge : IEdge
{
- private IDictionary predCounts = new Dictionary();
- private BinaryQueue heap;
- private IList sortedVertices = new List();
- private TopologicalSortDirection direction = TopologicalSortDirection.Forward;
+ [NotNull]
+ private readonly BinaryQueue _heap;
+ private readonly TopologicalSortDirection _direction;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// Graph to visit.
public SourceFirstBidirectionalTopologicalSortAlgorithm(
- IBidirectionalGraph visitedGraph
- )
+ [NotNull] IBidirectionalGraph visitedGraph)
: this(visitedGraph, TopologicalSortDirection.Forward)
{
}
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// Graph to visit.
+ /// Sort direction.
public SourceFirstBidirectionalTopologicalSortAlgorithm(
- IBidirectionalGraph visitedGraph,
- TopologicalSortDirection direction
- )
+ [NotNull] IBidirectionalGraph visitedGraph,
+ TopologicalSortDirection direction)
: base(visitedGraph)
{
- this.direction = direction;
- this.heap = new BinaryQueue(e => this.predCounts[e]);
+ _direction = direction;
+ _heap = new BinaryQueue(vertex => InDegrees[vertex]);
}
- public ICollection SortedVertices
+ ///
+ /// Sorted vertices.
+ ///
+#if SUPPORTS_CONTRACTS
+ [System.Diagnostics.Contracts.Pure]
+#endif
+ [NotNull, ItemNotNull]
+ public ICollection SortedVertices { get; private set; } = new List();
+
+ ///
+ /// Vertices in degrees.
+ ///
+#if SUPPORTS_CONTRACTS
+ [System.Diagnostics.Contracts.Pure]
+#endif
+ [NotNull]
+ public IDictionary InDegrees { get; } = new Dictionary();
+
+ ///
+ /// Fired when a vertex is added to the set of sorted vertices.
+ ///
+ public event VertexAction VertexAdded;
+
+ private void OnVertexAdded([NotNull] TVertex vertex)
{
- get
- {
- return this.sortedVertices;
- }
+#if SUPPORTS_CONTRACTS
+ Contract.Requires(vertex != null);
+#endif
+
+ VertexAdded?.Invoke(vertex);
}
- public BinaryQueue Heap
+ private void InitializeInDegrees()
{
- get
+ foreach (TVertex vertex in VisitedGraph.Vertices)
{
- return this.heap;
+ InDegrees.Add(vertex, 0);
}
- }
- public IDictionary InDegrees
- {
- get
+ foreach (TEdge edge in VisitedGraph.Edges)
{
- return this.predCounts;
+ if (edge.IsSelfEdge())
+ continue;
+
+ TVertex successor = _direction == TopologicalSortDirection.Forward
+ ? edge.Target
+ : edge.Source;
+
+ ++InDegrees[successor];
}
- }
- public event VertexAction AddVertex;
- private void OnAddVertex(TVertex v)
- {
- var eh = this.AddVertex;
- if (eh != null)
- eh(v);
+ foreach (TVertex vertex in VisitedGraph.Vertices)
+ {
+ _heap.Enqueue(vertex);
+ }
}
- public void Compute(IList vertices)
+ ///
+ /// Runs the topological sort and puts the result in the provided list.
+ ///
+ /// Set of sorted vertices.
+ public void Compute([NotNull, ItemNotNull] IList vertices)
{
#if SUPPORTS_CONTRACTS
Contract.Requires(vertices != null);
#endif
- this.sortedVertices = vertices;
+ SortedVertices = vertices;
+ SortedVertices.Clear();
Compute();
}
+ #region AlgorithmBase
+ ///
protected override void InternalCompute()
{
- var cancelManager = this.Services.CancelManager;
- this.InitializeInDegrees();
+ ICancelManager cancelManager = Services.CancelManager;
+ InitializeInDegrees();
- while (this.heap.Count != 0)
+ while (_heap.Count != 0)
{
- if (cancelManager.IsCancelling) break;
+ if (cancelManager.IsCancelling)
+ break;
- TVertex v = this.heap.Dequeue();
- if (this.predCounts[v] != 0)
+ TVertex vertex = _heap.Dequeue();
+ if (InDegrees[vertex] != 0)
throw new NonAcyclicGraphException();
- this.sortedVertices.Add(v);
- this.OnAddVertex(v);
+ SortedVertices.Add(vertex);
+ OnVertexAdded(vertex);
- // update the count of its successor vertices
- var succEdges = (this.direction == TopologicalSortDirection.Forward) ? this.VisitedGraph.OutEdges(v) : this.VisitedGraph.InEdges(v);
- foreach (var e in succEdges)
+ // Update the count of its successor vertices
+ IEnumerable successorEdges = _direction == TopologicalSortDirection.Forward
+ ? VisitedGraph.OutEdges(vertex)
+ : VisitedGraph.InEdges(vertex);
+
+ foreach (TEdge edge in successorEdges)
{
- if (e.Source.Equals(e.Target))
+ if (edge.IsSelfEdge())
continue;
- var succ = (direction == TopologicalSortDirection.Forward) ? e.Target : e.Source;
- this.predCounts[succ]--;
+
+ TVertex successor = _direction == TopologicalSortDirection.Forward
+ ? edge.Target
+ : edge.Source;
+
+ --InDegrees[successor];
#if SUPPORTS_CONTRACTS
- Contract.Assert(this.predCounts[succ] >= 0);
+ Contract.Assert(InDegrees[successor] >= 0);
#endif
- this.heap.Update(succ);
+ _heap.Update(successor);
}
}
}
- private void InitializeInDegrees()
- {
- foreach (var v in this.VisitedGraph.Vertices)
- {
- this.predCounts.Add(v, 0);
- }
-
- foreach (var e in this.VisitedGraph.Edges)
- {
- if (e.Source.Equals(e.Target))
- continue;
- var succ = (direction == TopologicalSortDirection.Forward) ? e.Target : e.Source;
- this.predCounts[succ]++;
- }
-
- foreach (var v in this.VisitedGraph.Vertices)
- {
- this.heap.Enqueue(v);
- }
- }
+ #endregion
}
}
diff --git a/src/QuikGraph/Algorithms/TopologicalSort/SourceFirstTopologicalSortAlgorithm.cs b/src/QuikGraph/Algorithms/TopologicalSort/SourceFirstTopologicalSortAlgorithm.cs
index 75af5bb5a..8fa12b79c 100644
--- a/src/QuikGraph/Algorithms/TopologicalSort/SourceFirstTopologicalSortAlgorithm.cs
+++ b/src/QuikGraph/Algorithms/TopologicalSort/SourceFirstTopologicalSortAlgorithm.cs
@@ -2,127 +2,145 @@
using System;
#endif
using System.Collections.Generic;
+using JetBrains.Annotations;
+using QuikGraph.Algorithms.Services;
+using QuikGraph.Collections;
#if SUPPORTS_CONTRACTS
using System.Diagnostics.Contracts;
#endif
-using QuikGraph.Collections;
namespace QuikGraph.Algorithms.TopologicalSort
{
+ ///
+ /// Topological sort algorithm (can be performed on an acyclic graph).
+ ///
+ /// Vertex type.
+ /// Edge type.
#if SUPPORTS_SERIALIZATION
[Serializable]
#endif
- public sealed class SourceFirstTopologicalSortAlgorithm :
- AlgorithmBase>
+ public sealed class SourceFirstTopologicalSortAlgorithm : AlgorithmBase>
where TEdge : IEdge
{
- private IDictionary inDegrees = new Dictionary();
- private BinaryQueue heap;
- private IList sortedVertices = new List();
+ [NotNull]
+ private readonly BinaryQueue _heap;
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// Graph to visit.
public SourceFirstTopologicalSortAlgorithm(
- IVertexAndEdgeListGraph visitedGraph
- )
- :base(visitedGraph)
+ [NotNull] IVertexAndEdgeListGraph visitedGraph)
+ : base(visitedGraph)
{
- this.heap = new BinaryQueue(e => this.inDegrees[e]);
+ _heap = new BinaryQueue(vertex => InDegrees[vertex]);
}
- public ICollection SortedVertices
+ ///
+ /// Sorted vertices.
+ ///
+#if SUPPORTS_CONTRACTS
+ [System.Diagnostics.Contracts.Pure]
+#endif
+ [NotNull, ItemNotNull]
+ public ICollection SortedVertices { get; private set; } = new List();
+
+ ///
+ /// Vertices in degrees.
+ ///
+#if SUPPORTS_CONTRACTS
+ [System.Diagnostics.Contracts.Pure]
+#endif
+ [NotNull]
+ public IDictionary InDegrees { get; } = new Dictionary();
+
+ ///
+ /// Fired when a vertex is added to the set of sorted vertices.
+ ///
+ public event VertexAction VertexAdded;
+
+ private void OnVertexAdded([NotNull] TVertex vertex)
{
- get
- {
- return this.sortedVertices;
- }
+#if SUPPORTS_CONTRACTS
+ Contract.Requires(vertex != null);
+#endif
+
+ VertexAdded?.Invoke(vertex);
}
- public BinaryQueue Heap
+ private void InitializeInDegrees()
{
- get
+ foreach (TVertex vertex in VisitedGraph.Vertices)
{
- return this.heap;
+ InDegrees.Add(vertex, 0);
}
- }
- public IDictionary InDegrees
- {
- get
+ foreach (TEdge edge in VisitedGraph.Edges)
{
- return this.inDegrees;
+ if (edge.IsSelfEdge())
+ continue;
+
+ ++InDegrees[edge.Target];
}
- }
- public event VertexAction AddVertex;
- private void OnAddVertex(TVertex v)
- {
- var eh = this.AddVertex;
- if (eh != null)
- eh(v);
+ foreach (TVertex vertex in VisitedGraph.Vertices)
+ {
+ _heap.Enqueue(vertex);
+ }
}
- public void Compute(IList vertices)
+ ///
+ /// Runs the topological sort and puts the result in the provided list.
+ ///
+ /// Set of sorted vertices.
+ public void Compute([NotNull, ItemNotNull] IList vertices)
{
#if SUPPORTS_CONTRACTS
Contract.Requires(vertices != null);
#endif
- this.sortedVertices = vertices;
+ SortedVertices = vertices;
+ SortedVertices.Clear();
Compute();
}
+ #region AlgorithmBase
+ ///
protected override void InternalCompute()
{
- var cancelManager = this.Services.CancelManager;
- this.InitializeInDegrees();
+ ICancelManager cancelManager = Services.CancelManager;
+ InitializeInDegrees();
- while (this.heap.Count != 0)
+ while (_heap.Count != 0)
{
- if (cancelManager.IsCancelling) break;
+ if (cancelManager.IsCancelling)
+ break;
- TVertex v = this.heap.Dequeue();
- if (this.inDegrees[v] != 0)
+ TVertex vertex = _heap.Dequeue();
+ if (InDegrees[vertex] != 0)
throw new NonAcyclicGraphException();
- this.sortedVertices.Add(v);
- this.OnAddVertex(v);
+ SortedVertices.Add(vertex);
+ OnVertexAdded(vertex);
- // update the count of it's adjacent vertices
- foreach (var e in this.VisitedGraph.OutEdges(v))
+ // Update the count of its adjacent vertices
+ foreach (TEdge edge in VisitedGraph.OutEdges(vertex))
{
- if (e.Source.Equals(e.Target))
+ if (edge.IsSelfEdge())
continue;
- this.inDegrees[e.Target]--;
+ --InDegrees[edge.Target];
#if SUPPORTS_CONTRACTS
- Contract.Assert(this.inDegrees[e.Target] >= 0);
+ Contract.Assert(InDegrees[edge.Target] >= 0);
#endif
- this.heap.Update(e.Target);
+ _heap.Update(edge.Target);
}
}
}
- private void InitializeInDegrees()
- {
- foreach (var v in this.VisitedGraph.Vertices)
- {
- this.inDegrees.Add(v, 0);
- }
-
- foreach (var e in this.VisitedGraph.Edges)
- {
- if (e.Source.Equals(e.Target))
- continue;
- this.inDegrees[e.Target]++;
- }
-
- foreach (var v in this.VisitedGraph.Vertices)
- {
- this.heap.Enqueue(v);
- }
-
- }
+ #endregion
}
}
diff --git a/src/QuikGraph/Algorithms/TopologicalSort/TopologicalSortAlgorithm.cs b/src/QuikGraph/Algorithms/TopologicalSort/TopologicalSortAlgorithm.cs
index 29509ced7..be201f2d6 100644
--- a/src/QuikGraph/Algorithms/TopologicalSort/TopologicalSortAlgorithm.cs
+++ b/src/QuikGraph/Algorithms/TopologicalSort/TopologicalSortAlgorithm.cs
@@ -2,6 +2,7 @@
using System;
#endif
using System.Collections.Generic;
+using JetBrains.Annotations;
#if SUPPORTS_CONTRACTS
using System.Diagnostics.Contracts;
#endif
@@ -9,60 +10,82 @@
namespace QuikGraph.Algorithms.TopologicalSort
{
+ ///
+ /// Topological sort algorithm (can be performed on an acyclic graph).
+ ///
+ /// Vertex type.
+ /// Edge type.
#if SUPPORTS_SERIALIZATION
[Serializable]
#endif
- public sealed class TopologicalSortAlgorithm :
- AlgorithmBase>
+ public sealed class TopologicalSortAlgorithm
+ : AlgorithmBase>
+ , IVertexTimeStamperAlgorithm
where TEdge : IEdge
{
- private IList vertices = new List();
- private bool allowCyclicGraph = false;
-
- public TopologicalSortAlgorithm(IVertexListGraph g)
- : this(g, new List())
- { }
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// Graph to visit.
+ public TopologicalSortAlgorithm([NotNull] IVertexListGraph visitedGraph)
+ : this(visitedGraph, new List())
+ {
+ }
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// Graph to visit.
+ /// Set of sorted vertices.
public TopologicalSortAlgorithm(
- IVertexListGraph g,
- IList vertices)
- : base(g)
+ [NotNull] IVertexListGraph visitedGraph,
+ [NotNull, ItemNotNull] IList vertices)
+ : base(visitedGraph)
{
#if SUPPORTS_CONTRACTS
Contract.Requires(vertices != null);
#endif
- this.vertices = vertices;
+ SortedVertices = vertices;
}
+ ///
+ /// Sorted vertices.
+ ///
+#if SUPPORTS_CONTRACTS
+ [System.Diagnostics.Contracts.Pure]
+#endif
+ [NotNull, ItemNotNull]
+ public IList SortedVertices { get; private set; }
- public IList SortedVertices
+ private static void OnBackEdge([NotNull] TEdge args)
{
- get
- {
- return vertices;
- }
+ throw new NonAcyclicGraphException();
}
- public bool AllowCyclicGraph
+ private void OnVertexFinished([NotNull] TVertex vertex)
{
- get { return this.allowCyclicGraph; }
+ SortedVertices.Insert(0, vertex);
}
- private void BackEdge(TEdge args)
+ ///
+ /// Runs the topological sort and puts the result in the provided list.
+ ///
+ /// Set of sorted vertices.
+ public void Compute([NotNull, ItemNotNull] IList vertices)
{
- if (!this.AllowCyclicGraph)
- throw new NonAcyclicGraphException();
- }
+#if SUPPORTS_CONTRACTS
+ Contract.Requires(vertices != null);
+#endif
- private void VertexFinished(TVertex v)
- {
- vertices.Insert(0, v);
+ SortedVertices = vertices;
+ SortedVertices.Clear();
+ Compute();
}
- public event VertexAction DiscoverVertex;
- public event VertexAction FinishVertex;
+ #region AlgorithmBase
+ ///
protected override void InternalCompute()
{
DepthFirstSearchAlgorithm dfs = null;
@@ -70,11 +93,10 @@ protected override void InternalCompute()
{
dfs = new DepthFirstSearchAlgorithm(
this,
- this.VisitedGraph,
- new Dictionary(this.VisitedGraph.VertexCount)
- );
- dfs.BackEdge += BackEdge;
- dfs.FinishVertex += VertexFinished;
+ VisitedGraph,
+ new Dictionary(VisitedGraph.VertexCount));
+ dfs.BackEdge += OnBackEdge;
+ dfs.FinishVertex += OnVertexFinished;
dfs.DiscoverVertex += DiscoverVertex;
dfs.FinishVertex += FinishVertex;
@@ -84,19 +106,24 @@ protected override void InternalCompute()
{
if (dfs != null)
{
- dfs.BackEdge -= BackEdge;
- dfs.FinishVertex -= VertexFinished;
+ dfs.BackEdge -= OnBackEdge;
+ dfs.FinishVertex -= OnVertexFinished;
dfs.DiscoverVertex -= DiscoverVertex;
dfs.FinishVertex -= FinishVertex;
}
}
}
- public void Compute(IList vertices)
- {
- this.vertices = vertices;
- this.vertices.Clear();
- this.Compute();
- }
+ #endregion
+
+ #region IVertexTimeStamperAlgorithm
+
+ ///
+ public event VertexAction DiscoverVertex;
+
+ ///
+ public event VertexAction FinishVertex;
+
+ #endregion
}
}
\ No newline at end of file
diff --git a/src/QuikGraph/Algorithms/TopologicalSort/TopologicalSortDirection.cs b/src/QuikGraph/Algorithms/TopologicalSort/TopologicalSortDirection.cs
new file mode 100644
index 000000000..0b3f51e46
--- /dev/null
+++ b/src/QuikGraph/Algorithms/TopologicalSort/TopologicalSortDirection.cs
@@ -0,0 +1,18 @@
+namespace QuikGraph.Algorithms.TopologicalSort
+{
+ ///
+ /// Enumeration of possible topological sort directions.
+ ///
+ public enum TopologicalSortDirection
+ {
+ ///
+ /// Forward sort.
+ ///
+ Forward,
+
+ ///
+ /// Backward sort.
+ ///
+ Backward
+ }
+}
diff --git a/src/QuikGraph/Algorithms/TopologicalSort/UndirectedFirstTopologicalSortAlgorithm.cs b/src/QuikGraph/Algorithms/TopologicalSort/UndirectedFirstTopologicalSortAlgorithm.cs
index 7df3e3889..9487150a2 100644
--- a/src/QuikGraph/Algorithms/TopologicalSort/UndirectedFirstTopologicalSortAlgorithm.cs
+++ b/src/QuikGraph/Algorithms/TopologicalSort/UndirectedFirstTopologicalSortAlgorithm.cs
@@ -3,118 +3,134 @@
#if SUPPORTS_CONTRACTS
using System.Diagnostics.Contracts;
#endif
+using JetBrains.Annotations;
+using QuikGraph.Algorithms.Services;
using QuikGraph.Collections;
namespace QuikGraph.Algorithms.TopologicalSort
{
+ ///
+ /// Undirected topological sort algorithm.
+ ///
+ /// Vertex type.
+ /// Edge type.
#if SUPPORTS_SERIALIZATION
[Serializable]
#endif
- public sealed class UndirectedFirstTopologicalSortAlgorithm :
- AlgorithmBase>
+ public sealed class UndirectedFirstTopologicalSortAlgorithm : AlgorithmBase>
where TEdge : IEdge
{
- private IDictionary degrees = new Dictionary();
- private BinaryQueue heap;
- private IList sortedVertices = new List();
- private bool allowCyclicGraph = false;
-
- public UndirectedFirstTopologicalSortAlgorithm(
- IUndirectedGraph visitedGraph
- )
+ [NotNull]
+ private readonly BinaryQueue _heap;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// Graph to visit.
+ public UndirectedFirstTopologicalSortAlgorithm([NotNull] IUndirectedGraph visitedGraph)
: base(visitedGraph)
{
- this.heap = new BinaryQueue(e => this.degrees[e]);
+ _heap = new BinaryQueue(vertex => Degrees[vertex]);
}
- public ICollection SortedVertices
- {
- get
- {
- return this.sortedVertices;
- }
- }
+ ///
+ /// Sorted vertices.
+ ///
+#if SUPPORTS_CONTRACTS
+ [System.Diagnostics.Contracts.Pure]
+#endif
+ [NotNull, ItemNotNull]
+ public ICollection SortedVertices { get; private set; } = new List();
- public BinaryQueue Heap
- {
- get
- {
- return this.heap;
- }
- }
+ ///
+ /// Vertices degrees.
+ ///
+#if SUPPORTS_CONTRACTS
+ [System.Diagnostics.Contracts.Pure]
+#endif
+ [NotNull]
+ public IDictionary Degrees { get; } = new Dictionary();
- public IDictionary Degrees
- {
- get
- {
- return this.degrees;
- }
- }
+ ///
+ /// Gets or sets the flag that indicates if cyclic graph are supported or not.
+ ///
+ public bool AllowCyclicGraph { get; set; }
+ ///
+ /// Fired when a vertex is added to the set of sorted vertices.
+ ///
+ public event VertexAction VertexAdded;
- public bool AllowCyclicGraph
+ private void OnVertexAdded([NotNull] TVertex vertex)
{
- get { return this.allowCyclicGraph; }
- set { this.allowCyclicGraph = value; }
+#if SUPPORTS_CONTRACTS
+ Contract.Requires(vertex != null);
+#endif
+
+ VertexAdded?.Invoke(vertex);
}
- public event VertexAction AddVertex;
- private void OnAddVertex(TVertex v)
+ private void InitializeInDegrees()
{
- var eh = AddVertex;
- if (eh != null)
- eh(v);
+ foreach (TVertex vertex in VisitedGraph.Vertices)
+ {
+ Degrees.Add(vertex, VisitedGraph.AdjacentDegree(vertex));
+ _heap.Enqueue(vertex);
+ }
}
- public void Compute(IList vertices)
+ ///
+ /// Runs the topological sort and puts the result in the provided list.
+ ///
+ /// Set of sorted vertices.
+ public void Compute([NotNull, ItemNotNull] IList vertices)
{
#if SUPPORTS_CONTRACTS
Contract.Requires(vertices != null);
#endif
- this.sortedVertices = vertices;
+ SortedVertices = vertices;
+ SortedVertices.Clear();
Compute();
}
+ #region AlgorithmBase
+ ///
protected override void InternalCompute()
{
- this.InitializeInDegrees();
- var cancelManager = this.Services.CancelManager;
+ ICancelManager cancelManager = Services.CancelManager;
+ InitializeInDegrees();
- while (this.heap.Count != 0)
+ while (_heap.Count != 0)
{
- if (cancelManager.IsCancelling) return;
+ if (cancelManager.IsCancelling)
+ return;
- TVertex v = this.heap.Dequeue();
- if (this.degrees[v] != 0 && !this.AllowCyclicGraph)
+ TVertex vertex = _heap.Dequeue();
+ if (Degrees[vertex] != 0 && !AllowCyclicGraph)
throw new NonAcyclicGraphException();
- this.sortedVertices.Add(v);
- this.OnAddVertex(v);
+ SortedVertices.Add(vertex);
+ OnVertexAdded(vertex);
- // update the count of it's adjacent vertices
- foreach (var e in this.VisitedGraph.AdjacentEdges(v))
+ // Update the count of its adjacent vertices
+ foreach (TEdge edge in VisitedGraph.AdjacentEdges(vertex))
{
- if (e.Source.Equals(e.Target))
+ if (edge.IsSelfEdge())
continue;
- this.degrees[e.Target]--;
- if (this.degrees[e.Target] < 0 && !this.AllowCyclicGraph)
- throw new InvalidOperationException("Degree is negative, and cannot be");
- if (this.heap.Contains(e.Target))
- this.heap.Update(e.Target);
+ --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);
}
}
}
- private void InitializeInDegrees()
- {
- foreach (var v in this.VisitedGraph.Vertices)
- {
- this.degrees.Add(v, this.VisitedGraph.AdjacentDegree(v));
- this.heap.Enqueue(v);
- }
- }
+ #endregion
}
}
diff --git a/src/QuikGraph/Algorithms/TopologicalSort/UndirectedTopologicalSortAlgorithm.cs b/src/QuikGraph/Algorithms/TopologicalSort/UndirectedTopologicalSortAlgorithm.cs
index c4bc79364..dc28878a8 100644
--- a/src/QuikGraph/Algorithms/TopologicalSort/UndirectedTopologicalSortAlgorithm.cs
+++ b/src/QuikGraph/Algorithms/TopologicalSort/UndirectedTopologicalSortAlgorithm.cs
@@ -3,61 +3,91 @@
#if SUPPORTS_CONTRACTS
using System.Diagnostics.Contracts;
#endif
+using JetBrains.Annotations;
using QuikGraph.Algorithms.Search;
namespace QuikGraph.Algorithms.TopologicalSort
{
+ ///
+ /// Undirected topological sort algorithm.
+ ///
+ /// Vertex type.
+ /// Edge type.
#if SUPPORTS_SERIALIZATION
[Serializable]
#endif
- public sealed class UndirectedTopologicalSortAlgorithm
- : AlgorithmBase>
+ public sealed class UndirectedTopologicalSortAlgorithm : AlgorithmBase>
where TEdge : IEdge
{
- private IList vertices;
- private bool allowCyclicGraph = false;
-
- public UndirectedTopologicalSortAlgorithm(IUndirectedGraph g)
- : this(g, new List())
- { }
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// Graph to visit.
+ public UndirectedTopologicalSortAlgorithm([NotNull] IUndirectedGraph visitedGraph)
+ : this(visitedGraph, new List())
+ {
+ }
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// Graph to visit.
+ /// Set of sorted vertices.
public UndirectedTopologicalSortAlgorithm(
- IUndirectedGraph g,
- IList vertices)
- : base(g)
+ [NotNull] IUndirectedGraph visitedGraph,
+ [NotNull, ItemNotNull] IList vertices)
+ : base(visitedGraph)
{
#if SUPPORTS_CONTRACTS
Contract.Requires(vertices != null);
#endif
- this.vertices = vertices;
+ SortedVertices = vertices;
}
- public IList SortedVertices
- {
- get
- {
- return vertices;
- }
- }
+ ///
+ /// Sorted vertices.
+ ///
+#if SUPPORTS_CONTRACTS
+ [System.Diagnostics.Contracts.Pure]
+#endif
+ [NotNull, ItemNotNull]
+ public IList SortedVertices { get; private set; }
+
+ ///
+ /// Gets or sets the flag that indicates if cyclic graph are supported or not.
+ ///
+ public bool AllowCyclicGraph { get; set; }
- public bool AllowCyclicGraph
+ private void BackEdge([NotNull] object sender, [NotNull] UndirectedEdgeEventArgs args)
{
- get { return this.allowCyclicGraph; }
- set { this.allowCyclicGraph = value; }
+ if (!AllowCyclicGraph)
+ throw new NonAcyclicGraphException();
}
- private void BackEdge(object sender, UndirectedEdgeEventArgs a)
+ private void OnVertexFinished([NotNull] TVertex vertex)
{
- if (!this.AllowCyclicGraph)
- throw new NonAcyclicGraphException();
+ SortedVertices.Insert(0, vertex);
}
- private void FinishVertex(TVertex v)
+ ///
+ /// Runs the topological sort and puts the result in the provided list.
+ ///
+ /// Set of sorted vertices.
+ public void Compute([NotNull, ItemNotNull] IList vertices)
{
- vertices.Insert(0, v);
+#if SUPPORTS_CONTRACTS
+ Contract.Requires(vertices != null);
+#endif
+
+ SortedVertices = vertices;
+ SortedVertices.Clear();
+ Compute();
}
+ #region AlgorithmBase
+
+ ///
protected override void InternalCompute()
{
UndirectedDepthFirstSearchAlgorithm dfs = null;
@@ -66,10 +96,9 @@ protected override void InternalCompute()
dfs = new UndirectedDepthFirstSearchAlgorithm(
this,
VisitedGraph,
- new Dictionary(this.VisitedGraph.VertexCount)
- );
+ new Dictionary(VisitedGraph.VertexCount));
dfs.BackEdge += BackEdge;
- dfs.FinishVertex += FinishVertex;
+ dfs.FinishVertex += OnVertexFinished;
dfs.Compute();
}
@@ -78,16 +107,11 @@ protected override void InternalCompute()
if (dfs != null)
{
dfs.BackEdge -= BackEdge;
- dfs.FinishVertex -= FinishVertex;
+ dfs.FinishVertex -= OnVertexFinished;
}
}
}
- public void Compute(IList vertices)
- {
- this.vertices = vertices;
- this.vertices.Clear();
- this.Compute();
- }
+ #endregion
}
}
diff --git a/tests/QuikGraph.Tests/Algorithms/TopologicalSortAlgorithmTest.cs b/tests/QuikGraph.Tests/Algorithms/TopologicalSortAlgorithmTest.cs
index 09c060dc7..481fe531d 100644
--- a/tests/QuikGraph.Tests/Algorithms/TopologicalSortAlgorithmTest.cs
+++ b/tests/QuikGraph.Tests/Algorithms/TopologicalSortAlgorithmTest.cs
@@ -28,10 +28,9 @@ public void SortCyclic(
[Test]
public void SortDCT8()
{
- var g = TestGraphFactory.LoadGraph(GetGraphFilePath("DCT8.graphml"));
- var topo = new TopologicalSortAlgorithm>(g);
- Assert.IsFalse(topo.AllowCyclicGraph);
- topo.Compute();
+ var graph = TestGraphFactory.LoadGraph(GetGraphFilePath("DCT8.graphml"));
+ var topologicalSort = new TopologicalSortAlgorithm>(graph);
+ topologicalSort.Compute();
}
[Test]