Guava не имеет этой встроенной функции, поэтому вам понадобится специальное решение, которое выполняет какой-то обход графика (например, обход в ширину), например, следующий фрагмент кода.
public static <N> ImmutableGraph<N> buildGraphWithBreadthFirstTraversal(
Iterable<N> startingNodes, SuccessorsFunction<N> successorsFunction) {
ImmutableGraph.Builder<N> builder = GraphBuilder.directed().immutable();
Queue<N> nodesRemaining = Queues.newArrayDeque(startingNodes);
Set<N> visited = Sets.newHashSet(startingNodes);
while (!nodesRemaining.isEmpty()) {
N next = nodesRemaining.remove();
for (N successor : successorsFunction.successors(next)) {
if (!visited.contains(successor)) {
nodesRemaining.add(successor);
visited.add(successor);
builder.putEdge(next, successor);
}
}
}
return builder.build();
}
Вот базовый модульный тест JUnit 5, который подтверждает, что код работает при задании начального узла и successorsFunction
, которые вместе образуют цикл 1 -> 2 -> 4 -> 1
.
@Test
void succeedsOnTraversalWithCycle() {
ImmutableGraph<Integer> graph =
buildGraphWithBreadthFirstTraversal(
ImmutableList.of(1),
node -> node <= 2 ? ImmutableList.of(node * 2) : ImmutableList.of(1));
assertThat(graph.nodes()).containsExactlyInAnyOrder(1, 2, 4);
assertThat(graph.edges())
.containsExactlyInAnyOrder(
EndpointPair.ordered(1, 2),
EndpointPair.ordered(2, 4));
}