All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.jgrapht.alg.ConnectivityInspector Maven / Gradle / Ivy

/* ==========================================
 * JGraphT : a free Java graph-theory library
 * ==========================================
 *
 * Project Info:  http://jgrapht.sourceforge.net/
 * Project Creator:  Barak Naveh (http://sourceforge.net/users/barak_naveh)
 *
 * (C) Copyright 2003-2008, by Barak Naveh and Contributors.
 *
 * This program and the accompanying materials are dual-licensed under
 * either
 *
 * (a) the terms of the GNU Lesser General Public License version 2.1
 * as published by the Free Software Foundation, or (at your option) any
 * later version.
 *
 * or (per the licensee's choosing)
 *
 * (b) the terms of the Eclipse Public License v1.0 as published by
 * the Eclipse Foundation.
 */
/* --------------------------
 * ConnectivityInspector.java
 * --------------------------
 * (C) Copyright 2003-2008, by Barak Naveh and Contributors.
 *
 * Original Author:  Barak Naveh
 * Contributor(s):   John V. Sichi
 *                   Christian Hammer
 *
 * $Id$
 *
 * Changes
 * -------
 * 06-Aug-2003 : Initial revision (BN);
 * 10-Aug-2003 : Adaptation to new event model (BN);
 * 07-Jun-2005 : Made generic (CH);
 *
 */
package org.jgrapht.alg;

import java.util.*;

import org.jgrapht.*;
import org.jgrapht.event.*;
import org.jgrapht.graph.*;
import org.jgrapht.traverse.*;


/**
 * Allows obtaining various connectivity aspects of a graph. The inspected
 * graph is specified at construction time and cannot be modified.
 * Currently, the inspector supports connected components for an undirected
 * graph and weakly connected components for a directed graph. To find strongly
 * connected components, use {@link StrongConnectivityInspector} instead.
 *
 * 

The inspector methods work in a lazy fashion: no computation is performed * unless immediately necessary. Computation are done once and results and * cached within this class for future need.

* *

The inspector is also a {@link org.jgrapht.event.GraphListener}. If added * as a listener to the inspected graph, the inspector will amend internal * cached results instead of recomputing them. It is efficient when a few * modifications are applied to a large graph. If many modifications are * expected it will not be efficient due to added overhead on graph update * operations. If inspector is added as listener to a graph other than the one * it inspects, results are undefined.

* * @author Barak Naveh * @author John V. Sichi * @since Aug 6, 2003 */ public class ConnectivityInspector implements GraphListener { List> connectedSets; Map> vertexToConnectedSet; private Graph graph; /** * Creates a connectivity inspector for the specified undirected graph. * * @param g the graph for which a connectivity inspector to be created. */ public ConnectivityInspector(UndirectedGraph g) { init(); this.graph = g; } /** * Creates a connectivity inspector for the specified directed graph. * * @param g the graph for which a connectivity inspector to be created. */ public ConnectivityInspector(DirectedGraph g) { init(); this.graph = new AsUndirectedGraph(g); } /** * Test if the inspected graph is connected. An empty graph is not * considered connected. * * @return true if and only if inspected graph is connected. */ public boolean isGraphConnected() { return lazyFindConnectedSets().size() == 1; } /** * Returns a set of all vertices that are in the maximally connected * component together with the specified vertex. For more on maximally * connected component, see * http://www.nist.gov/dads/HTML/maximallyConnectedComponent.html. * * @param vertex the vertex for which the connected set to be returned. * * @return a set of all vertices that are in the maximally connected * component together with the specified vertex. */ public Set connectedSetOf(V vertex) { Set connectedSet = vertexToConnectedSet.get(vertex); if (connectedSet == null) { connectedSet = new HashSet(); BreadthFirstIterator i = new BreadthFirstIterator(graph, vertex); while (i.hasNext()) { connectedSet.add(i.next()); } vertexToConnectedSet.put(vertex, connectedSet); } return connectedSet; } /** * Returns a list of Set s, where each set contains all * vertices that are in the same maximally connected component. All graph * vertices occur in exactly one set. For more on maximally connected * component, see * http://www.nist.gov/dads/HTML/maximallyConnectedComponent.html. * * @return Returns a list of Set s, where each set contains all * vertices that are in the same maximally connected component. */ public List> connectedSets() { return lazyFindConnectedSets(); } /** * @see GraphListener#edgeAdded(GraphEdgeChangeEvent) */ public void edgeAdded(GraphEdgeChangeEvent e) { init(); // for now invalidate cached results, in the future need to // amend them. } /** * @see GraphListener#edgeRemoved(GraphEdgeChangeEvent) */ public void edgeRemoved(GraphEdgeChangeEvent e) { init(); // for now invalidate cached results, in the future need to // amend them. } /** * Tests if there is a path from the specified source vertex to the * specified target vertices. For a directed graph, direction is ignored for * this interpretation of path. * *

Note: Future versions of this method might not ignore edge directions * for directed graphs.

* * @param sourceVertex one end of the path. * @param targetVertex another end of the path. * * @return true if and only if there is a path from the source * vertex to the target vertex. */ public boolean pathExists(V sourceVertex, V targetVertex) { /* * TODO: Ignoring edge direction for directed graph may be * confusing. For directed graphs, consider Dijkstra's algorithm. */ Set sourceSet = connectedSetOf(sourceVertex); return sourceSet.contains(targetVertex); } /** * @see VertexSetListener#vertexAdded(GraphVertexChangeEvent) */ public void vertexAdded(GraphVertexChangeEvent e) { init(); // for now invalidate cached results, in the future need to // amend them. } /** * @see VertexSetListener#vertexRemoved(GraphVertexChangeEvent) */ public void vertexRemoved(GraphVertexChangeEvent e) { init(); // for now invalidate cached results, in the future need to // amend them. } private void init() { connectedSets = null; vertexToConnectedSet = new HashMap>(); } private List> lazyFindConnectedSets() { if (connectedSets == null) { connectedSets = new ArrayList>(); Set vertexSet = graph.vertexSet(); if (vertexSet.size() > 0) { BreadthFirstIterator i = new BreadthFirstIterator(graph, null); i.addTraversalListener(new MyTraversalListener()); while (i.hasNext()) { i.next(); } } } return connectedSets; } /** * A traversal listener that groups all vertices according to to their * containing connected set. * * @author Barak Naveh * @since Aug 6, 2003 */ private class MyTraversalListener extends TraversalListenerAdapter { private Set currentConnectedSet; /** * @see TraversalListenerAdapter#connectedComponentFinished(ConnectedComponentTraversalEvent) */ public void connectedComponentFinished( ConnectedComponentTraversalEvent e) { connectedSets.add(currentConnectedSet); } /** * @see TraversalListenerAdapter#connectedComponentStarted(ConnectedComponentTraversalEvent) */ public void connectedComponentStarted( ConnectedComponentTraversalEvent e) { currentConnectedSet = new HashSet(); } /** * @see TraversalListenerAdapter#vertexTraversed(VertexTraversalEvent) */ public void vertexTraversed(VertexTraversalEvent e) { V v = e.getVertex(); currentConnectedSet.add(v); vertexToConnectedSet.put(v, currentConnectedSet); } } } // End ConnectivityInspector.java




© 2015 - 2024 Weber Informatics LLC | Privacy Policy