Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
package cdc.graphs.core;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
import cdc.graphs.EdgeDirection;
import cdc.graphs.EdgeTip;
import cdc.graphs.GraphAdapter;
import cdc.graphs.impl.ExplicitSubGraph;
import cdc.graphs.impl.ExtensionSubGraph;
import cdc.util.lang.Checks;
/**
* Utility used to compute transitive closure of a node or a set of nodes.
*
* @author Damien Carbonne
*
* @param Node type
* @param Edge type
*/
public class GraphTransitiveClosure extends GraphBase {
private static final String NODE = "node";
private static final String NODES = "nodes";
public GraphTransitiveClosure(GraphAdapter adapter) {
super(adapter);
}
public Set computeTransitiveClosureNodes(N node) {
Checks.isNotNull(node, NODE);
final Set result = new HashSet<>();
addClosure(node, result);
return result;
}
public Set computeTransitiveClosureNodes(Collection nodes) {
Checks.isNotNull(nodes, NODES);
final Set result = new HashSet<>();
for (final N node : nodes) {
addClosure(node, result);
}
return result;
}
public Set computeTransitiveClosureNodes(N node,
EdgeDirection direction) {
Checks.isNotNull(node, NODE);
final Set resultIn =
direction != EdgeDirection.OUTGOING ? new HashSet<>() : null;
final Set resultOut =
direction != EdgeDirection.INGOING ? new HashSet<>() : null;
if (resultOut != null) {
addOutgoingClosure(node, resultOut);
}
if (resultIn != null) {
addIngoingClosure(node, resultIn);
}
return merge(resultIn, resultOut);
}
public Set computeTransitiveClosureNodes(Collection nodes,
EdgeDirection direction) {
Checks.isNotNull(nodes, NODES);
final Set resultIn =
direction != EdgeDirection.OUTGOING ? new HashSet<>() : null;
final Set resultOut =
direction != EdgeDirection.INGOING ? new HashSet<>() : null;
for (final N node : nodes) {
if (resultOut != null) {
addOutgoingClosure(node, resultOut);
}
if (resultIn != null) {
addIngoingClosure(node, resultIn);
}
}
return merge(resultIn, resultOut);
}
public ExplicitSubGraph computeTransitiveClosure(N node) {
Checks.isNotNull(node, NODE);
final ExplicitSubGraph result = new ExtensionSubGraph<>(adapter);
addClosure(node, result);
return result;
}
public ExplicitSubGraph computeTransitiveClosure(Collection nodes) {
Checks.isNotNull(nodes, NODES);
final ExplicitSubGraph result = new ExtensionSubGraph<>(adapter);
for (final N node : nodes) {
addClosure(node, result);
}
return result;
}
/**
* Computes the transitive closure of a node.
*
* @param node The node.
* @param direction The transitive closure direction. {@code null} means both directions.
* @return The transitive closure of {@code node}.
*/
public ExplicitSubGraph computeTransitiveClosure(N node,
EdgeDirection direction) {
Checks.isNotNull(node, NODE);
final ExplicitSubGraph resultIn =
direction != EdgeDirection.OUTGOING ? new ExtensionSubGraph<>(adapter) : null;
final ExplicitSubGraph resultOut =
direction != EdgeDirection.INGOING ? new ExtensionSubGraph<>(adapter) : null;
if (resultOut != null) {
addOutgoingClosure(node, resultOut);
}
if (resultIn != null) {
addIngoingClosure(node, resultIn);
}
return merge(resultIn, resultOut);
}
/**
* Computes the transitive closure of a collection of nodes.
*
* @param nodes The collection of nodes.
* @param direction The transitive closure direction. {@code null} means both directions.
* @return The transitive closure of {@code nodes}.
*/
public ExplicitSubGraph computeTransitiveClosure(Collection nodes,
EdgeDirection direction) {
Checks.isNotNull(nodes, NODES);
final ExplicitSubGraph resultIn =
direction != EdgeDirection.OUTGOING ? new ExtensionSubGraph<>(adapter) : null;
final ExplicitSubGraph resultOut =
direction != EdgeDirection.INGOING ? new ExtensionSubGraph<>(adapter) : null;
for (final N node : nodes) {
if (resultOut != null) {
addOutgoingClosure(node, resultOut);
}
if (resultIn != null) {
addIngoingClosure(node, resultIn);
}
}
return merge(resultIn, resultOut);
}
private void addClosure(N node,
ExplicitSubGraph result) {
if (!result.containsNode(node)) {
result.addNode(node);
for (final E edge : adapter.getEdges(node, EdgeDirection.OUTGOING)) {
if (!result.containsEdge(edge)) {
final N target = adapter.getTip(edge, EdgeTip.TARGET);
addOutgoingClosure(target, result);
result.addEdge(edge);
}
}
for (final E edge : adapter.getEdges(node, EdgeDirection.INGOING)) {
if (!result.containsEdge(edge)) {
final N source = adapter.getTip(edge, EdgeTip.SOURCE);
addOutgoingClosure(source, result);
result.addEdge(edge);
}
}
}
}
private void addOutgoingClosure(N node,
ExplicitSubGraph result) {
if (!result.containsNode(node)) {
result.addNode(node);
for (final E edge : adapter.getEdges(node, EdgeDirection.OUTGOING)) {
if (!result.containsEdge(edge)) {
final N target = adapter.getTip(edge, EdgeTip.TARGET);
addOutgoingClosure(target, result);
result.addEdge(edge);
}
}
}
}
private void addIngoingClosure(N node,
ExplicitSubGraph result) {
if (!result.containsNode(node)) {
result.addNode(node);
for (final E edge : adapter.getEdges(node, EdgeDirection.INGOING)) {
if (!result.containsEdge(edge)) {
final N source = adapter.getTip(edge, EdgeTip.SOURCE);
addIngoingClosure(source, result);
result.addEdge(edge);
}
}
}
}
private ExplicitSubGraph merge(ExplicitSubGraph in,
ExplicitSubGraph out) {
if (in == null) {
return out;
} else if (out == null) {
return in;
} else {
for (final N n : in.getNodes()) {
out.addNode(n);
}
for (final E e : in.getEdges()) {
out.addEdge(e);
}
return out;
}
}
private void addClosure(N node,
Set result) {
if (!result.contains(node)) {
result.add(node);
for (final E edge : adapter.getEdges(node, EdgeDirection.OUTGOING)) {
final N target = adapter.getTip(edge, EdgeTip.TARGET);
addOutgoingClosure(target, result);
}
for (final E edge : adapter.getEdges(node, EdgeDirection.INGOING)) {
final N source = adapter.getTip(edge, EdgeTip.SOURCE);
addOutgoingClosure(source, result);
}
}
}
private void addOutgoingClosure(N node,
Set result) {
if (!result.contains(node)) {
result.add(node);
for (final E edge : adapter.getEdges(node, EdgeDirection.OUTGOING)) {
final N target = adapter.getTip(edge, EdgeTip.TARGET);
addOutgoingClosure(target, result);
}
}
}
private void addIngoingClosure(N node,
Set result) {
if (!result.contains(node)) {
result.add(node);
for (final E edge : adapter.getEdges(node, EdgeDirection.INGOING)) {
final N source = adapter.getTip(edge, EdgeTip.SOURCE);
addIngoingClosure(source, result);
}
}
}
private Set merge(Set in,
Set out) {
if (in == null) {
return out;
} else if (out == null) {
return in;
} else {
out.addAll(in);
return out;
}
}
}