/** Tests Subgraph. */ public void testSubgraph() { UndirectedGraph<String, DefaultEdge> g = init(false); UndirectedSubgraph<String, DefaultEdge> sub = new UndirectedSubgraph<String, DefaultEdge>(g, null, null); assertEquals(g.vertexSet(), sub.vertexSet()); assertEquals(g.edgeSet(), sub.edgeSet()); Set<String> vset = new HashSet<String>(g.vertexSet()); g.removeVertex(v1); assertEquals(vset, sub.vertexSet()); // losing track g = init(false); vset = new HashSet<String>(); vset.add(v1); sub = new UndirectedSubgraph<String, DefaultEdge>(g, vset, null); assertEquals(vset, sub.vertexSet()); assertEquals(0, sub.degreeOf(v1)); assertEquals(Collections.EMPTY_SET, sub.edgeSet()); vset.add(v2); vset.add(v3); sub = new UndirectedSubgraph<String, DefaultEdge>( g, vset, new HashSet<DefaultEdge>(g.getAllEdges(v1, v2))); assertEquals(vset, sub.vertexSet()); assertEquals(1, sub.edgeSet().size()); }
/** {@inheritDoc} */ protected void encounterVertexAgain(V vertex, E edge) { super.encounterVertexAgain(vertex, edge); int i; if (root != null) { // For rooted detection, the path must either // double back to the root, or to a node of a cycle // which has already been detected. if (vertex.equals(root)) { i = 0; } else if ((cycleSet != null) && cycleSet.contains(vertex)) { i = 0; } else { return; } } else { i = path.indexOf(vertex); } if (i > -1) { if (cycleSet == null) { // we're doing yes/no cycle detection throw new CycleDetectedException(); } else { for (; i < path.size(); ++i) { cycleSet.add(path.get(i)); } } } }
/** * @param vertexNumber the number which identifies the vertex v in this order. * @return the identifying numbers of all vertices which are connected to v by an edge incoming to * v. */ public int[] getInEdges(int vertexNumber) { if (cacheEdges && (incomingEdges[vertexNumber] != null)) { return incomingEdges[vertexNumber]; } V v = getVertex(vertexNumber); Set<E> edgeSet; if (graph instanceof DirectedGraph<?, ?>) { edgeSet = ((DirectedGraph<V, E>) graph).incomingEdgesOf(v); } else { edgeSet = graph.edgesOf(v); } int[] vertexArray = new int[edgeSet.size()]; int i = 0; for (E edge : edgeSet) { V source = graph.getEdgeSource(edge), target = graph.getEdgeTarget(edge); vertexArray[i++] = mapVertexToOrder.get(source.equals(v) ? target : source); } if (cacheEdges) { incomingEdges[vertexNumber] = vertexArray; } return vertexArray; }
/** @see Graph#getAllEdges(Object, Object) */ public Set<E> getAllEdges(V sourceVertex, V targetVertex) { Set<E> edges = null; if (containsVertex(sourceVertex) && containsVertex(targetVertex)) { edges = new ArrayUnenforcedSet<E>(); Iterator<E> iter = getEdgeContainer(sourceVertex).vertexEdges.iterator(); while (iter.hasNext()) { E e = iter.next(); boolean equalStraight = sourceVertex.equals(getEdgeSource(e)) && targetVertex.equals(getEdgeTarget(e)); boolean equalInverted = sourceVertex.equals(getEdgeTarget(e)) && targetVertex.equals(getEdgeSource(e)); if (equalStraight || equalInverted) { edges.add(e); } } } return edges; }
private void init(Graph<V, E> g, Set<V> vertexSet, Set<E> edgeSet) { // create a map between vertex value to its order(1st,2nd,etc) // "CAT"=1 "DOG"=2 "RHINO"=3 this.mapVertexToOrder = new HashMap<V, Integer>(vertexSet.size()); int counter = 0; for (V vertex : vertexSet) { mapVertexToOrder.put(vertex, new Integer(counter)); counter++; } // create a friendlier representation of an edge // by order, like 2nd->3rd instead of B->A // use the map to convert vertex to order // on directed graph, edge A->B must be (A,B) // on undirected graph, edge A-B can be (A,B) or (B,A) this.labelsEdgesSet = new HashSet<LabelsEdge>(edgeSet.size()); for (E edge : edgeSet) { V sourceVertex = g.getEdgeSource(edge); Integer sourceOrder = mapVertexToOrder.get(sourceVertex); int sourceLabel = sourceOrder.intValue(); int targetLabel = (mapVertexToOrder.get(g.getEdgeTarget(edge))).intValue(); LabelsEdge lablesEdge = new LabelsEdge(sourceLabel, targetLabel); this.labelsEdgesSet.add(lablesEdge); if (g instanceof UndirectedGraph<?, ?>) { LabelsEdge oppositeEdge = new LabelsEdge(targetLabel, sourceLabel); this.labelsEdgesSet.add(oppositeEdge); } } }
public Set<String> getIndexedClasses() { Set<String> classes = newHashSet(); Set<JavaClass> vertexSet = graph.vertexSet(); for (JavaClass each : vertexSet) { classes.add(each.getName()); } return classes; }
private void markPath(V v, V child, V stem, Set<V> blossom) { while (!contracted.get(v).equals(stem)) { blossom.add(contracted.get(v)); blossom.add(contracted.get(match.get(v))); path.put(v, child); child = match.get(v); v = path.get(match.get(v)); } }
public Set<E> getAllEdges(V sourceVertex, V targetVertex) { Set<E> res = new HashSet<E>(); if (g1.containsVertex(sourceVertex) && g1.containsVertex(targetVertex)) { res.addAll(g1.getAllEdges(sourceVertex, targetVertex)); } if (g2.containsVertex(sourceVertex) && g2.containsVertex(targetVertex)) { res.addAll(g2.getAllEdges(sourceVertex, targetVertex)); } return Collections.unmodifiableSet(res); }
public Set<E> edgesOf(V vertex) { Set<E> res = new HashSet<E>(); if (g1.containsVertex(vertex)) { res.addAll(g1.edgesOf(vertex)); } if (g2.containsVertex(vertex)) { res.addAll(g2.edgesOf(vertex)); } return Collections.unmodifiableSet(res); }
public Set<E> outgoingEdgesOf(V vertex) { Set<E> res = new HashSet<E>(); if (getG1().containsVertex(vertex)) { res.addAll(getG1().outgoingEdgesOf(vertex)); } if (getG2().containsVertex(vertex)) { res.addAll(getG2().outgoingEdgesOf(vertex)); } return Collections.unmodifiableSet(res); }
/** . */ public void testStronglyConnected3() { DirectedGraph<String, DefaultEdge> g = new DefaultDirectedGraph<String, DefaultEdge>(DefaultEdge.class); g.addVertex(V1); g.addVertex(V2); g.addVertex(V3); g.addVertex(V4); g.addEdge(V1, V2); g.addEdge(V2, V3); g.addEdge(V3, V1); // strongly connected g.addEdge(V1, V4); g.addEdge(V2, V4); g.addEdge(V3, V4); // weakly connected StrongConnectivityInspector<String, DefaultEdge> inspector = new StrongConnectivityInspector<String, DefaultEdge>(g); // convert from List to Set because we need to ignore order // during comparison Set<Set<String>> actualSets = new HashSet<Set<String>>(inspector.stronglyConnectedSets()); // construct the expected answer Set<Set<String>> expectedSets = new HashSet<Set<String>>(); Set<String> set = new HashSet<String>(); set.add(V1); set.add(V2); set.add(V3); expectedSets.add(set); set = new HashSet<String>(); set.add(V4); expectedSets.add(set); assertEquals(expectedSets, actualSets); actualSets.clear(); List<DirectedSubgraph<String, DefaultEdge>> subgraphs = inspector.stronglyConnectedSubgraphs(); for (DirectedSubgraph<String, DefaultEdge> sg : subgraphs) { actualSets.add(sg.vertexSet()); StrongConnectivityInspector<String, DefaultEdge> ci = new StrongConnectivityInspector<String, DefaultEdge>(sg); assertTrue(ci.isStronglyConnected()); } assertEquals(expectedSets, actualSets); }
/** . */ public void testSubgraphListener() { UndirectedGraph<String, DefaultEdge> g = init(true); UndirectedSubgraph<String, DefaultEdge> sub = new UndirectedSubgraph<String, DefaultEdge>(g, null, null); assertEquals(g.vertexSet(), sub.vertexSet()); assertEquals(g.edgeSet(), sub.edgeSet()); Set<String> vset = new HashSet<String>(g.vertexSet()); g.removeVertex(v1); vset.remove(v1); assertEquals(vset, sub.vertexSet()); // not losing track assertEquals(g.edgeSet(), sub.edgeSet()); }
private void findParents(JavaClass jclass, Set<JavaClass> changedParents) { for (JavaClass parent : getParents(jclass)) { if (changedParents.add(parent)) { findParents(parent, changedParents); } } }
/* * The subroutine of DFS. NOTE: the set is used to distinguish between 1st * and 2nd round of DFS. set == null: finished vertices are stored (1st * round). set != null: all vertices found will be saved in the set (2nd * round) */ private void dfsVisit( DirectedGraph<V, E> visitedGraph, VertexData<V> vertexData, Set<V> vertices) { Deque<VertexData<V>> stack = new ArrayDeque<VertexData<V>>(); stack.add(vertexData); while (!stack.isEmpty()) { VertexData<V> data = stack.removeLast(); if (!data.isDiscovered()) { data.setDiscovered(true); if (vertices != null) { vertices.add(data.getVertex()); } stack.add(new VertexData1<V>(data, true, true)); // follow all edges for (E edge : visitedGraph.outgoingEdgesOf(data.getVertex())) { VertexData<V> targetData = vertexToVertexData.get(visitedGraph.getEdgeTarget(edge)); if (!targetData.isDiscovered()) { // the "recursion" stack.add(targetData); } } } else if (data.isFinished()) { if (vertices == null) { orderedVertices.addFirst(data.getFinishedData()); } } } }
private V lowestCommonAncestor(V a, V b) { Set<V> seen = new HashSet<>(); for (; ; ) { a = contracted.get(a); seen.add(a); if (!match.containsKey(a)) { break; } a = path.get(match.get(a)); } for (; ; ) { b = contracted.get(b); if (seen.contains(b)) { return b; } b = path.get(match.get(b)); } }
/** @see Graph#getAllEdges(Object, Object) */ public Set<E> getAllEdges(V sourceVertex, V targetVertex) { Set<E> edges = null; if (containsVertex(sourceVertex) && containsVertex(targetVertex)) { edges = new ArrayUnenforcedSet<E>(); DirectedEdgeContainer<V, E> ec = getEdgeContainer(sourceVertex); Iterator<E> iter = ec.outgoing.iterator(); while (iter.hasNext()) { E e = iter.next(); if (getEdgeTarget(e).equals(targetVertex)) { edges.add(e); } } } return edges; }
/** * Finds the vertex set for the subgraph of all cycles. * * @return set of all vertices which participate in at least one cycle in this graph */ public Set<V> findCycles() { // ProbeIterator can't be used to handle this case, // so use StrongConnectivityInspector instead. StrongConnectivityInspector<V, E> inspector = new StrongConnectivityInspector<V, E>(graph); List<Set<V>> components = inspector.stronglyConnectedSets(); // A vertex participates in a cycle if either of the following is // true: (a) it is in a component whose size is greater than 1 // or (b) it is a self-loop Set<V> set = new HashSet<V>(); for (Set<V> component : components) { if (component.size() > 1) { // cycle set.addAll(component); } else { V v = component.iterator().next(); if (graph.containsEdge(v, v)) { // self-loop set.add(v); } } } return set; }
/** @see Graph#edgesOf(Object) */ public Set<E> edgesOf(V vertex) { ArrayUnenforcedSet<E> inAndOut = new ArrayUnenforcedSet<E>(getEdgeContainer(vertex).incoming); inAndOut.addAll(getEdgeContainer(vertex).outgoing); // we have two copies for each self-loop - remove one of them. if (allowingLoops) { Set<E> loops = getAllEdges(vertex, vertex); for (int i = 0; i < inAndOut.size(); ) { Object e = inAndOut.get(i); if (loops.contains(e)) { inAndOut.remove(i); loops.remove(e); // so we remove it only once } else { i++; } } } return Collections.unmodifiableSet(inAndOut); }
public Set<JavaClass> findClasses(Collection<File> changedFiles) { // First update class index List<String> changedClassesNames = new ArrayList<String>(); for (File changedFile : changedFiles) { String changedClassname = builder.classFileChanged(changedFile); if (changedClassname != null) { changedClassesNames.add(changedClassname); } } // Then find dependencies Set<JavaClass> changedClasses = newHashSet(); for (String changedClassesName : changedClassesNames) { JavaClass javaClass = builder.getClass(changedClassesName); if (javaClass != null) { addToIndex(javaClass); changedClasses.add(javaClass); } } builder.clear(); return changedClasses; }
/** * Updates outgoing vertices of the vertex. For each outgoing vertex, the new paths are obtained * by concatenating the specified edge to the calculated paths of the specified vertex. If the * weight of a new path is greater than the weight of any path stored so far at the outgoing * vertex then the path is not added, otherwise it is added to the list of paths in increasing * order of weight. Complexity = * * <ul> * <li>O(<code>d(v)*k*(m+n)</code>) where <code>d(v)</code> is the outgoing degree of the * specified vertex, <code>k</code> is the maximum number of shortest paths to compute, * <code>m</code> is the number of edges of the graph and <code>n</code> is the number of * vertices of the graph * </ul> * * @param vertex * @param improvedVertices */ private void updateOutgoingVertices(V vertex, Set<V> improvedVertices) { // try to add new paths for the target vertices of the outgoing edges // of the vertex in argument. for (Iterator<E> iter = edgesOfIterator(vertex); iter.hasNext(); ) { E edge = iter.next(); V vertexReachedByEdge = Graphs.getOppositeVertex(this.graph, edge, vertex); // check if the path does not loop over the start vertex. if (!vertexReachedByEdge.equals(this.startVertex)) { if (this.seenDataContainer.containsKey(vertexReachedByEdge)) { boolean relaxed = tryToAddNewPaths(vertexReachedByEdge, edge); if (relaxed) { improvedVertices.add(vertexReachedByEdge); } } else { boolean relaxed = tryToAddFirstPaths(vertexReachedByEdge, edge); if (relaxed) { improvedVertices.add(vertexReachedByEdge); } } } } }
/** * Compute the unique decomposition of the input graph G (atoms of G). Implementation of algorithm * Atoms as described in Berry et al. (2010), DOI:10.3390/a3020197, <a * href="http://www.mdpi.com/1999-4893/3/2/197">http://www.mdpi.com/1999-4893/3/2/197</a> */ private void computeAtoms() { if (chordalGraph == null) { computeMinimalTriangulation(); } separators = new HashSet<>(); // initialize g' as subgraph of graph (same vertices and edges) UndirectedGraph<V, E> gprime = copyAsSimpleGraph(graph); // initialize h' as subgraph of chordalGraph (same vertices and edges) UndirectedGraph<V, E> hprime = copyAsSimpleGraph(chordalGraph); atoms = new HashSet<>(); Iterator<V> iterator = meo.descendingIterator(); while (iterator.hasNext()) { V v = iterator.next(); if (generators.contains(v)) { Set<V> separator = new HashSet<>(Graphs.neighborListOf(hprime, v)); if (isClique(graph, separator)) { if (separator.size() > 0) { if (separators.contains(separator)) { fullComponentCount.put(separator, fullComponentCount.get(separator) + 1); } else { fullComponentCount.put(separator, 2); separators.add(separator); } } UndirectedGraph<V, E> tmpGraph = copyAsSimpleGraph(gprime); tmpGraph.removeAllVertices(separator); ConnectivityInspector<V, E> con = new ConnectivityInspector<>(tmpGraph); if (con.isGraphConnected()) { throw new RuntimeException("separator did not separate the graph"); } for (Set<V> component : con.connectedSets()) { if (component.contains(v)) { gprime.removeAllVertices(component); component.addAll(separator); atoms.add(new HashSet<>(component)); assert (component.size() > 0); break; } } } } hprime.removeVertex(v); } if (gprime.vertexSet().size() > 0) { atoms.add(new HashSet<>(gprime.vertexSet())); } }
/** * Runs the algorithm on the input graph and returns the match edge set. * * @return set of Edges */ private Set<E> findMatch() { Set<E> result = new ArrayUnenforcedSet<>(); match = new HashMap<>(); path = new HashMap<>(); contracted = new HashMap<>(); for (V i : graph.vertexSet()) { // Any augmenting path should start with _exposed_ vertex // (vertex may not escape match-set being added once) if (!match.containsKey(i)) { // Match is maximal iff graph G contains no more augmenting paths V v = findPath(i); while (v != null) { V pv = path.get(v); V ppv = match.get(pv); match.put(v, pv); match.put(pv, v); v = ppv; } } } Set<V> seen = new HashSet<>(); graph .vertexSet() .stream() .filter(v -> !seen.contains(v) && match.containsKey(v)) .forEach( v -> { seen.add(v); seen.add(match.get(v)); result.add(graph.getEdge(v, match.get(v))); }); return result; }
public int outDegreeOf(V vertex) { Set<E> res = outgoingEdgesOf(vertex); return res.size(); }
/** * . * * @param e */ public void addIncomingEdge(EE e) { incoming.add(e); }
/** * . * * @param e */ public void removeEdge(EE e) { vertexEdges.remove(e); }
/** * . * * @return */ public int edgeCount() { return vertexEdges.size(); }
/** * . * * @param e */ public void addEdge(EE e) { vertexEdges.add(e); }
/** * . * * @param e */ public void addOutgoingEdge(EE e) { outgoing.add(e); }
/** * . * * @param e */ public void removeOutgoingEdge(EE e) { outgoing.remove(e); }
/** * . * * @param e */ public void removeIncomingEdge(EE e) { incoming.remove(e); }