Example usage for com.google.common.graph SuccessorsFunction successors

List of usage examples for com.google.common.graph SuccessorsFunction successors

Introduction

In this page you can find the example usage for com.google.common.graph SuccessorsFunction successors.

Prototype

Set<N> successors(N node);

Source Link

Document

Returns all nodes in this graph adjacent to node which can be reached by traversing node 's outgoing edges in the direction (if any) of the edge.

Usage

From source file:dagger.internal.codegen.DaggerGraphs.java

/**
 * Returns a shortest path from {@code nodeU} to {@code nodeV} in {@code graph} as a list of the
 * nodes visited in sequence, including both {@code nodeU} and {@code nodeV}. (Note that there may
 * be many possible shortest paths.)//from   w  w  w . ja v  a 2  s. c  om
 *
 * <p>If {@code nodeV} is not {@link
 * com.google.common.graph.Graphs#reachableNodes(com.google.common.graph.Graph, Object) reachable}
 * from {@code nodeU}, the list returned is empty.
 *
 * @throws IllegalArgumentException if {@code nodeU} or {@code nodeV} is not present in {@code
 *     graph}
 */
public static <N> ImmutableList<N> shortestPath(SuccessorsFunction<N> graph, N nodeU, N nodeV) {
    if (nodeU.equals(nodeV)) {
        return ImmutableList.of(nodeU);
    }
    Set<N> successors = ImmutableSet.copyOf(graph.successors(nodeU));
    if (successors.contains(nodeV)) {
        return ImmutableList.of(nodeU, nodeV);
    }

    Map<N, N> visitedNodeToPathPredecessor = new HashMap<>(); // encodes shortest path tree
    for (N node : successors) {
        visitedNodeToPathPredecessor.put(node, nodeU);
    }
    Queue<N> currentNodes = new ArrayDeque<N>(successors);
    Queue<N> nextNodes = new ArrayDeque<N>();

    // Perform a breadth-first traversal starting with the successors of nodeU.
    while (!currentNodes.isEmpty()) {
        while (!currentNodes.isEmpty()) {
            N currentNode = currentNodes.remove();
            for (N nextNode : graph.successors(currentNode)) {
                if (visitedNodeToPathPredecessor.containsKey(nextNode)) {
                    continue; // we already have a shortest path to nextNode
                }
                visitedNodeToPathPredecessor.put(nextNode, currentNode);
                if (nextNode.equals(nodeV)) {
                    ImmutableList.Builder<N> builder = ImmutableList.builder();
                    N node = nodeV;
                    builder.add(node);
                    while (!node.equals(nodeU)) {
                        node = visitedNodeToPathPredecessor.get(node);
                        builder.add(node);
                    }
                    return builder.build().reverse();
                }
                nextNodes.add(nextNode);
            }
        }
        Queue<N> emptyQueue = currentNodes;
        currentNodes = nextNodes;
        nextNodes = emptyQueue; // reusing empty queue faster than allocating new one
    }

    return ImmutableList.of();
}