/** * Returns the node that is selected as the representative of the SCC containing the argument. * @since 1.6 */ public V getRepresentative(V node) { return sccs.find(node); }
public List<V> getReachabilityPath(V source, V target) { if (!isReachable(source, target)) { return null; } else { Set<V> sccsInSubGraph = CollectionHelper.intersectionMutable(counting.getAllReachableTargets(source), counting.getAllReachableSources(target)); sccsInSubGraph.add(sccs.find(source)); sccsInSubGraph.add(sccs.find(target)); Set<V> nodesInSubGraph = CollectionsFactory.createSet(); for (V sccRoot : sccsInSubGraph) { nodesInSubGraph.addAll(sccs.getPartition(sccRoot)); } return GraphHelper.constructPath(source, target, nodesInSubGraph, gds); } }
/** * Return the SCCs from which the SCC represented by the root node is reachable. Note that an SCC can be present * multiple times in the returned list (multiple edges between the two SCCs). * * @param root * @return the list of reachable target SCCs */ private List<V> getSourceSCCsOfSCC(V root) { List<V> sourceSCCs = new ArrayList<V>(); for (V containedNode : this.sccs.getPartition(root)) { IMemoryView<V> sourceNodes = this.gds.getSourceNodes(containedNode); for (V source : sourceNodes.distinctValues()) { sourceSCCs.add(this.sccs.find(source)); } } return sourceSCCs; }
/** * Return the SCCs which are reachable from the SCC represented by the root node. Note that an SCC can be present * multiple times in the returned list (multiple edges between the two SCCs). * * @param root * @return the list of reachable target SCCs */ private List<V> getTargetSCCsOfSCC(V root) { List<V> targetSCCs = new ArrayList<V>(); for (V containedNode : this.sccs.getPartition(root)) { IMemoryView<V> targetNodes = this.gds.getTargetNodes(containedNode); for (V target : targetNodes.distinctValues()) { targetSCCs.add(this.sccs.find(target)); } } return targetSCCs; }
@Override public Set<V> getAllReachableSources(V target) { V targetRoot = sccs.find(target); Set<V> containedNodes = sccs.getPartition(targetRoot); Set<V> sources = CollectionsFactory.createSet(); if (containedNodes.size() > 1 || GraphHelper.getEdgeCount(target, gds) == 1) { sources.addAll(containedNodes); } Set<V> rootSet = counting.getAllReachableSources(targetRoot); if (rootSet != null) { for (V _root : rootSet) { sources.addAll(sccs.getPartition(_root)); } } return sources; }
@Override public Set<V> getAllReachableTargets(V source) { V sourceRoot = sccs.find(source); Set<V> containedNodes = sccs.getPartition(sourceRoot); Set<V> targets = CollectionsFactory.createSet(); if (containedNodes.size() > 1 || GraphHelper.getEdgeCount(source, gds) == 1) { targets.addAll(containedNodes); } Set<V> rootSet = counting.getAllReachableTargets(sourceRoot); if (rootSet != null) { for (V _root : rootSet) { targets.addAll(sccs.getPartition(_root)); } } return targets; }
/** * Returns true if the SCC represented by the given root node has outgoing edges in the reduced graph, * false otherwise (if this SCC is a sink in the reduced graph). * * @param root the root node of an SCC * @return true if it has outgoing edges, false otherwise * @since 1.6 */ public boolean hasOutgoingEdges(V root) { for (final V containedNode : this.sccs.getPartition(root)) { final IMemoryView<V> targetNodes = this.gds.getTargetNodes(containedNode); for (final V target : targetNodes.distinctValues()) { final V otherRoot = this.sccs.find(target); if (!Objects.equals(root, otherRoot)) { return true; } } } return false; }
/** * Returns true if the SCC represented by the given root node has incoming edges in the reduced graph, * false otherwise (if this SCC is a source in the reduced graph). * * @param root the root node of an SCC * @return true if it has incoming edges, false otherwise * @since 1.6 */ public boolean hasIncomingEdges(final V root) { for (final V containedNode : this.sccs.getPartition(root)) { final IMemoryView<V> sourceNodes = this.gds.getSourceNodes(containedNode); for (final V source : sourceNodes.distinctValues()) { final V otherRoot = this.sccs.find(source); if (!Objects.equals(root, otherRoot)) { return true; } } } return false; }
private void initalizeInternalDataStructures() { SCCResult<V> _sccres = SCC.computeSCC(gds); Set<Set<V>> _sccs = _sccres.getSccs(); for (Set<V> _set : _sccs) { sccs.makeSet(_set); } // Initalization of the reduced graph for (V n : sccs.getPartitionHeads()) { reducedGraph.insertNode(n); } for (V source : gds.getAllNodes()) { final IMemoryView<V> targetNodes = gds.getTargetNodes(source); for (Entry<V, Integer> entry : targetNodes.entriesWithMultiplicities()) { for (int i = 0; i < entry.getValue(); i++) { V target = entry.getKey(); V sourceRoot = sccs.find(source); V targetRoot = sccs.find(target); if (!sourceRoot.equals(targetRoot)) { reducedGraph.insertEdge(sourceRoot, targetRoot); } } } } counting = new CountingAlg<V>(reducedGraph); }