Detect *all* cycles during topological sort
Previously the cycle detection was limited to detecting when we hit
a currently-being-visited node during a traversal. So something like this would
be correctly found:
A --> B --> C
^ |
| |
+-----+
We start at the root (A), go to B, then to C, then to B, and detect that we're
still working on B and signal the error.
But this doesn't find all cycles, because we *start* at the root nodes, and if
a cycle doesn't have any outcropping branches we'll never reach it at all. For
example:
A --> B
^ |
| |
+-----+
This graph has no roots, so we incorrectly ignore the cycle.
This patch fixes the problem by keeping a count of visited nodes and and making
sure it matches the digraph's size at the end.
Fixes https://github.com/sjl/cl-digraph/issues/4
author |
Steve Losh <steve@stevelosh.com> |
date |
Mon, 14 Dec 2020 20:13:51 -0500 |
parents |
0434eb58dde3 |
children |
7e80eda84170 |
(defpackage :digraph
(:use :cl :digraph.quickutils)
(:export
:digraph
:make-digraph
:emptyp
:vertices
:edges
:arbitrary-vertex
:roots
:leafs
:rootp
:leafp
:predecessors
:successors
:neighbors
:contains-vertex-p
:contains-edge-p
:insert-vertex
:insert-edge
:remove-edge
:remove-vertex
:degree
:degree-in
:degree-out
:count-vertices
:count-edges
:mapc-vertices
:mapc-edges
:map-vertices
:map-edges
:map-depth-first
:map-breadth-first
:mapc-depth-first
:mapc-breadth-first
:topological-sort
:reachablep
:copy-digraph))