sortedTopologicalOrdering property
Returns an ordered set of all vertices in topological order.
-
For every directed edge: (vertex1 -> vertex2), vertex1 is listed before vertex2.
-
If a vertex comparator is specified, the sorting will be applied in addition to the topological order.
-
Note: There is no topological ordering if the graph is cyclic. In that case the function returns
null
. -
Any self-loop renders a directed graph cyclic.
-
Based on Kahn's algorithm.
Implementation
Set<T>? get sortedTopologicalOrdering {
if (_comparator == null) return topologicalOrdering;
final result = <T>{};
// Get modifiable in-degree map.
final localInDegreeMap = HashMap<T, int>.of(inDegreeMap);
// Add all sources (vertices with inDegree == 0) to queue.
// Using a list instead of a queue to enable sorting of [sources].
//
// Note: In an acyclic directed graph there is at least
// one vertex with inDegree equal to zero.
final sources = PriorityQueue<T>(comparator);
for (final vertex in vertices) {
if (localInDegreeMap[vertex] == 0) {
sources.add(vertex);
}
}
// Initialize count of visited vertices.
var count = 0;
// Note: In an acyclic directed graph at least
// one vertex has outDegree zero.
while (sources.isNotEmpty) {
result.add(sources.removeFirst());
// Simulate removing the current vertex from the
// graph. => Connected vertices will have inDegree = inDegree - 1.
for (final vertex in edges(result.last)) {
var inDegree = localInDegreeMap[vertex]!;
inDegree--;
localInDegreeMap[vertex] = inDegree;
// Add new local source vertices of the remaining graph to the queue.
if (inDegree == 0) {
sources.add(vertex);
}
}
// Increment count of visited vertices.
count++;
}
return (count == length) ? result : null;
}