cdc.graphs.core.GraphSimplePaths Maven / Gradle / Ivy
package cdc.graphs.core;
import java.util.HashSet;
import java.util.Set;
import cdc.graphs.EdgeDirection;
import cdc.graphs.GraphAdapter;
/**
* Utility used to find simple (node) paths in a graph.
*
* A simple paths passes once by a node, except for the first and last node that can be the same.
*
* WARNING: Node paths may be ambiguous when several edges are allowed between 2 nodes.
*
* @author Damien Carbonne
*
* @param Node class.
* @param Edge class.
*/
public class GraphSimplePaths extends GraphBase {
public GraphSimplePaths(GraphAdapter adapter) {
super(adapter);
}
private void findSimpleNodePathsBetween(N source,
N target,
GraphPath.Builder path,
Set> paths) {
for (final N next : adapter.getConnectedNodes(source, EdgeDirection.OUTGOING)) {
if (next == target) {
final GraphPath.Builder tmp = GraphPath.builder();
tmp.push(path.getItems());
tmp.push(next);
paths.add(tmp.build());
} else if (!path.contains(next)) {
path.push(next);
findSimpleNodePathsBetween(next, target, path, paths);
path.pop();
}
}
}
/**
* Finds all simple node paths between a source and a target.
*
* @param source The source node.
* @param target The target node.
* @return A set of all simple paths between source and target.
*/
public Set> findSimpleNodePathsBetween(N source,
N target) {
final Set> paths = new HashSet<>();
final GraphPath.Builder path = GraphPath.builder();
path.push(source);
findSimpleNodePathsBetween(source, target, path, paths);
return paths;
}
/**
* Finds all simple node paths starting from a source node.
*
* @param source The source node.
* @return A set of all simple paths starting from source.
*/
public Set> findSimpleNodePathsFrom(N source) {
final Set> result = new HashSet<>();
for (final N target : getAdapter().getNodes()) {
final Set> paths = findSimpleNodePathsBetween(source, target);
result.addAll(paths);
}
return result;
}
/**
* Find all simple node paths arriving to a target node.
*
* @param target The target node.
* @return All simple paths arriving to target.
*/
public Set> findAllSimpleNodePathsTo(N target) {
final Set> result = new HashSet<>();
for (final N source : getAdapter().getNodes()) {
final Set> paths = findSimpleNodePathsBetween(source, target);
result.addAll(paths);
}
return result;
}
/**
* Find all simple node paths in the underlying graph.
*
* @return A set of all simple paths in the graph.
*/
public Set> findAllSimpleNodePaths() {
final Set> result = new HashSet<>();
for (final N source : getAdapter().getNodes()) {
for (final N target : getAdapter().getNodes()) {
final Set> paths = findSimpleNodePathsBetween(source, target);
result.addAll(paths);
}
}
return result;
}
}