/** * Adds vertices, and a directed edge between them. * * @param from * Vertex value at the start of the edge * @param to * Vertex value at the end of the edge */ public void addDirectedEdge(final T from, final T to) { if (!from.equals(to)) { edges.add(new DirectedEdge(addVertex(from), addVertex(to))); } }
/** * Checks if the graph contains a cycle. * * @return true if the graph contains a cycle, false otherwise */ public boolean containsCycle() { final Collection<Vertex> vertices = clearTraversalStates(); for (final Vertex vertex: vertices) { if (vertex.getTraversalState() == TraversalState.notStarted) { if (visitForCyles(vertex)) { return true; } } } return false; }
public DirectedGraph<T> subGraph(final T value) { return subGraph(value, -1); }
public DirectedGraph<T> subGraph(final T value, final int depth) { final Collection<Vertex> vertices = clearTraversalStates(); visitForSubGraph(verticesMap.get(value), depth); final Set<Vertex> subGraphVertices = new HashSet<>(); for (final Vertex currentVertex: vertices) { if (currentVertex.getTraversalState() == TraversalState.complete) { subGraphVertices.add(currentVertex); } } final DirectedGraph<T> subGraph = new DirectedGraph<>(); for (final DirectedEdge edge: edges) { final Vertex from = edge.getFrom(); final Vertex to = edge.getTo(); if (subGraphVertices.contains(from) && subGraphVertices.contains(to)) { subGraph.addDirectedEdge(from.getValue(), to.getValue()); } } // In case this is an isolated node subGraph.addVertex(value); return subGraph; }
public List<T> topologicalSort() throws GraphException if (containsCycle()) if (isUnattachedNode(vertex, edges)) for (final Vertex vertex: vertices) if (isStartNode(vertex, edges)) dropOutEdges(vertex, edges);
private boolean visitForCyles(final Vertex vertex) { vertex.setTraversalState(TraversalState.inProgress); for (final DirectedEdge edge: edges) { if (edge.isFrom(vertex)) { final Vertex to = edge.getTo(); if (to.getTraversalState() == TraversalState.inProgress) { return true; } else if (to.getTraversalState() == TraversalState.notStarted) { if (visitForCyles(to)) { return true; } } } } vertex.setTraversalState(TraversalState.complete); return false; }