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

org.jgrapht.alg.BlockCutpointGraph 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.
 */
/* -------------------------
 * BlockCutpointGraph.java
 * -------------------------
 * (C) Copyright 2007-2008, by France Telecom
 *
 * Original Author:  Guillaume Boulmier and Contributors.
 * Contributor(s):   John V. Sichi
 *
 * $Id$
 *
 * Changes
 * -------
 * 05-Jun-2007 : Initial revision (GB);
 * 05-Jul-2007 : Added support for generics (JVS);
 *
 */
package org.jgrapht.alg;

import java.util.*;

import org.jgrapht.*;
import org.jgrapht.graph.*;


/**
 * Definition of a block of a
 * graph in MathWorld.
* Definition and lemma taken from the article * Structure-Based Resilience Metrics for Service-Oriented Networks: * *
    *
  • Definition 4.5 Let G(V; E) be a connected undirected graph. The * block-cut point graph (BC graph) of G, denoted by GB(VB; EB), is the * bipartite graph defined as follows. (a) VB has one node corresponding to each * block and one node corresponding to each cut point of G. (b) Each edge fx; yg * in EB joins a block node x to a cut point y if the block corresponding to x * contains the cut point node corresponding to y.
  • *
  • Lemma 4.4 Let G(V; E) be a connected undirected graph. (a) Each * pair of blocks of G share at most one node, and that node is a cutpoint. (b) * The BC graph of G is a tree in which each leaf node corresponds to a block of * G.
  • *
* * @author Guillaume Boulmier * @since July 5, 2007 */ public class BlockCutpointGraph extends SimpleGraph, DefaultEdge> { /** */ private static final long serialVersionUID = -9101341117013163934L; private Set cutpoints = new HashSet(); /** * DFS (Depth-First-Search) tree. */ private DirectedGraph dfsTree; private UndirectedGraph graph; private int numOrder; private Deque stack = new ArrayDeque(); private Map>> vertex2biconnectedSubgraphs = new HashMap>>(); private Map> vertex2block = new HashMap>(); private Map vertex2numOrder = new HashMap(); /** * Running time = O(m) where m is the number of edges. */ public BlockCutpointGraph(UndirectedGraph graph) { super(DefaultEdge.class); this.graph = graph; this.dfsTree = new SimpleDirectedGraph( DefaultEdge.class); V s = graph.vertexSet().iterator().next(); this.dfsTree.addVertex(s); dfsVisit(s, s); if (this.dfsTree.edgesOf(s).size() > 1) { this.cutpoints.add(s); } else { this.cutpoints.remove(s); } for (Iterator iter = this.cutpoints.iterator(); iter.hasNext();) { V cutpoint = iter.next(); UndirectedGraph subgraph = new SimpleGraph(this.graph.getEdgeFactory()); subgraph.addVertex(cutpoint); this.vertex2block.put(cutpoint, subgraph); addVertex(subgraph); Set> biconnectedSubgraphs = getBiconnectedSubgraphs(cutpoint); for ( Iterator> iterator = biconnectedSubgraphs.iterator(); iterator.hasNext();) { UndirectedGraph biconnectedSubgraph = iterator.next(); assert (vertexSet().contains(biconnectedSubgraph)); addEdge(subgraph, biconnectedSubgraph); } } } /** * Returns the vertex if vertex is a cutpoint, and otherwise returns the * block (biconnected component) containing the vertex. * * @param vertex vertex in the initial graph. */ public UndirectedGraph getBlock(V vertex) { if (!this.graph.vertexSet().contains(vertex)) { throw new IllegalArgumentException("No such vertex in the graph!"); } return this.vertex2block.get(vertex); } /** * Returns the cutpoints of the initial graph. */ public Set getCutpoints() { return this.cutpoints; } /** * Returns true if the vertex is a cutpoint, false * otherwise. * * @param vertex vertex in the initial graph. */ public boolean isCutpoint(V vertex) { if (!this.graph.vertexSet().contains(vertex)) { throw new IllegalArgumentException("No such vertex in the graph!"); } return this.cutpoints.contains(vertex); } private void biconnectedComponentFinished(V s, V n) { this.cutpoints.add(s); Set vertexComponent = new HashSet(); Set edgeComponent = new HashSet(); BCGEdge edge = this.stack.removeLast(); while ( (getNumOrder(edge.getSource()) >= getNumOrder(n)) && !this.stack.isEmpty()) { edgeComponent.add(edge); vertexComponent.add(edge.getSource()); vertexComponent.add(edge.getTarget()); edge = this.stack.removeLast(); } edgeComponent.add(edge); // edgeComponent is an equivalence class. vertexComponent.add(edge.getSource()); vertexComponent.add(edge.getTarget()); VertexComponentForbiddenFunction mask = new VertexComponentForbiddenFunction( vertexComponent); UndirectedGraph biconnectedSubgraph = new UndirectedMaskSubgraph( this.graph, mask); for (Iterator iter = vertexComponent.iterator(); iter.hasNext();) { V vertex = iter.next(); this.vertex2block.put(vertex, biconnectedSubgraph); getBiconnectedSubgraphs(vertex).add(biconnectedSubgraph); } addVertex(biconnectedSubgraph); } private int dfsVisit(V s, V father) { this.numOrder++; int minS = this.numOrder; setNumOrder(s, this.numOrder); for ( Iterator iter = this.graph.edgesOf(s).iterator(); iter.hasNext();) { E edge = iter.next(); V n = Graphs.getOppositeVertex(this.graph, edge, s); if (getNumOrder(n) == 0) { this.dfsTree.addVertex(n); BCGEdge dfsEdge = new BCGEdge(s, n); this.dfsTree.addEdge(s, n, dfsEdge); this.stack.add(dfsEdge); // minimum of the traverse orders of the "attach points" of // the vertex n. int minN = dfsVisit(n, s); minS = Math.min(minN, minS); if (minN >= getNumOrder(s)) { // s is a cutpoint. // it has a son whose "attach depth" is greater or equal. biconnectedComponentFinished(s, n); } } else if ((getNumOrder(n) < getNumOrder(s)) && !n.equals(father)) { BCGEdge backwardEdge = new BCGEdge(s, n); this.stack.add(backwardEdge); // n is an "attach point" of s. {s->n} is a backward edge. minS = Math.min(getNumOrder(n), minS); } } // minimum of the traverse orders of the "attach points" of // the vertex s. return minS; } /** * Returns the biconnected components containing the vertex. A vertex which * is not a cutpoint is contained in exactly one component. A cutpoint is * contained is at least 2 components. * * @param vertex vertex in the initial graph. */ private Set> getBiconnectedSubgraphs(V vertex) { Set> biconnectedSubgraphs = this.vertex2biconnectedSubgraphs.get(vertex); if (biconnectedSubgraphs == null) { biconnectedSubgraphs = new HashSet>(); this.vertex2biconnectedSubgraphs.put(vertex, biconnectedSubgraphs); } return biconnectedSubgraphs; } /** * Returns the traverse order of the vertex in the DFS. */ private int getNumOrder(V vertex) { assert (vertex != null); Integer numOrder = this.vertex2numOrder.get(vertex); if (numOrder == null) { return 0; } else { return numOrder.intValue(); } } private void setNumOrder(V vertex, int numOrder) { this.vertex2numOrder.put(vertex, Integer.valueOf(numOrder)); } private class BCGEdge extends DefaultEdge { /** */ private static final long serialVersionUID = -5115006161815760059L; private V source; private V target; public BCGEdge(V source, V target) { super(); this.source = source; this.target = target; } @Override public V getSource() { return this.source; } @Override public V getTarget() { return this.target; } } private class VertexComponentForbiddenFunction implements MaskFunctor { private Set vertexComponent; public VertexComponentForbiddenFunction(Set vertexComponent) { this.vertexComponent = vertexComponent; } @Override public boolean isEdgeMasked(E edge) { return false; } @Override public boolean isVertexMasked(V vertex) { if (this.vertexComponent.contains(vertex)) { // vertex belongs to component then we do not mask it. return false; } else { return true; } } } } // End BlockCutpointGraph.java




© 2015 - 2024 Weber Informatics LLC | Privacy Policy