All Downloads are FREE. Search and download functionalities are using the official Maven repository.

cdc.graphs.core.GraphPathsExplorer Maven / Gradle / Ivy

package cdc.graphs.core;

import java.util.HashSet;
import java.util.Set;
import java.util.function.Consumer;

import cdc.graphs.EdgeDirection;
import cdc.graphs.EdgeTip;
import cdc.graphs.GraphAdapter;

/**
 * Utility used to find paths starting or arriving to a node.
 * 

* Path that arrive to a sink or start on a source are produced. * * @author Damien Carbonne * * @param Node type. * @param Edge type. */ public class GraphPathsExplorer extends GraphBase { private class Visitor { /** * Set of currently visited nodes. * It has the same content as stack but is better for searches. */ private final Set visited = new HashSet<>(); /** * Current stack of edges, that produces a path when arriving on a sink or source. */ private final GraphPath.Builder stack = GraphPath.builder(); /** * The exploration direction. */ private final EdgeDirection direction; /** * Tip to use to find next node following direction. */ private final EdgeTip tip; public Visitor(EdgeDirection direction) { this.direction = direction; this.tip = direction == EdgeDirection.INGOING ? EdgeTip.SOURCE : EdgeTip.TARGET; } public void traverse(N node, Consumer> consumer) { visited.add(node); for (final E edge : adapter.getEdges(node, direction)) { final N succ = adapter.getTip(edge, tip); stack.push(edge); if (GraphPathsExplorer.this.adapter.hasEdges(succ, direction)) { if (visited.contains(succ)) { // Cycle detected throw new IllegalArgumentException("Cycle detected: " + stack); } else { traverse(succ, consumer); } } else { final GraphPath path = stack.build(); consumer.accept(path); } stack.pop(); visited.remove(node); } } } public GraphPathsExplorer(GraphAdapter adapter) { super(adapter); } /** * Explores all paths that start on a node and arrive to sinks or sources. * * @param from The starting node. * @param direction The exploration direction. * OUTGOING leads to sinks, INGOING to sources. * @param consumer The paths consumer. * @throws IllegalArgumentException When a cycle is detected. */ public void explore(N from, EdgeDirection direction, Consumer> consumer) { final Visitor visitor = new Visitor(direction); visitor.traverse(from, consumer); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy