Returns true if {@code graph} has at least one cycle. A cycle is defined as a non-empty subset of edges in a graph arranged to form a path (a sequence of adjacent outgoing edges) starting and ending with the same node. <p>This method will detect any non-empty cycle, including self-loops (a cycle of
(Graph<N> graph)
| 57 | * <p>This method will detect any non-empty cycle, including self-loops (a cycle of length 1). |
| 58 | */ |
| 59 | public static <N> boolean hasCycle(Graph<N> graph) { |
| 60 | int numEdges = graph.edges().size(); |
| 61 | if (numEdges == 0) { |
| 62 | return false; // An edge-free graph is acyclic by definition. |
| 63 | } |
| 64 | if (!graph.isDirected() && numEdges >= graph.nodes().size()) { |
| 65 | return true; // Optimization for the undirected case: at least one cycle must exist. |
| 66 | } |
| 67 | |
| 68 | Map<Object, NodeVisitState> visitedNodes = |
| 69 | Maps.newHashMapWithExpectedSize(graph.nodes().size()); |
| 70 | for (N node : graph.nodes()) { |
| 71 | if (subgraphHasCycle(graph, visitedNodes, node)) { |
| 72 | return true; |
| 73 | } |
| 74 | } |
| 75 | return false; |
| 76 | } |
| 77 | |
| 78 | /** |
| 79 | * Returns true if {@code network} has at least one cycle. A cycle is defined as a non-empty |