| 188 | */ |
| 189 | // TODO(b/31438252): Consider optimizing for undirected graphs. |
| 190 | public static <N> ImmutableGraph<N> transitiveClosure( |
| 191 | Graph<N> graph, TransitiveClosureSelfLoopStrategy strategy) { |
| 192 | ImmutableGraph.Builder<N> transitiveClosure = |
| 193 | GraphBuilder.from(graph).allowsSelfLoops(true).<N>immutable(); |
| 194 | |
| 195 | for (N node : graph.nodes()) { |
| 196 | // add each node explicitly to include isolated nodes |
| 197 | transitiveClosure.addNode(node); |
| 198 | for (N reachableNode : getReachableNodes(graph, node, strategy)) { |
| 199 | transitiveClosure.putEdge(node, reachableNode); |
| 200 | } |
| 201 | } |
| 202 | return transitiveClosure.build(); |
| 203 | } |
| 204 | |
| 205 | /** |
| 206 | * Equivalent to {@code transitiveClosure(graph, ADD_SELF_LOOPS_ALWAYS)}. Callers should look at |