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

org.chocosolver.graphsolver.util.ConnectivityFinder Maven / Gradle / Ivy

There is a newer version: 4.2.2
Show newest version
/**
 * Copyright (c) 1999-2011, Ecole des Mines de Nantes
 * All rights reserved.
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 * 

* * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the name of the Ecole des Mines de Nantes nor the * names of its contributors may be used to endorse or promote products * derived from this software without specific prior written permission. *

* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *

* Created by IntelliJ IDEA. * User: Jean-Guillaume Fages * Date: 17/04/2016 * Time: 13:11 */ /** * Created by IntelliJ IDEA. * User: Jean-Guillaume Fages * Date: 17/04/2016 * Time: 13:11 */ package org.chocosolver.graphsolver.util; import gnu.trove.list.array.TIntArrayList; import org.chocosolver.util.objects.graphs.IGraph; import org.chocosolver.util.objects.setDataStructures.ISet; import java.util.Iterator; /** * Class containing algorithms to find all connected components and articulation points of graph by performing one dfs * it uses Tarjan algorithm in a non recursive way and can be performed in O(M+N) time c.f. Gondrand Minoux * * @author Jean-Guillaume Fages */ public class ConnectivityFinder { //*********************************************************************************** // CONNECTED COMPONENTS ONLY //*********************************************************************************** private int n; private IGraph graph; private int[] CC_firstNode, CC_nextNode, node_CC, p, fifo; private int nbCC; //bonus biconnection private int[] numOfNode, nodeOfNum, inf; private Iterator[] iterators; /** * Create an object that can compute Connected Components (CC) of a graph g * Can also quickly tell whether g is biconnected or not (only for undirected graph) * * @param g graph */ public ConnectivityFinder(IGraph g) { graph = g; n = g.getNbMaxNodes(); p = new int[n]; fifo = new int[n]; iterators = new Iterator[n]; } /** * get the number of CC in g * Beware you should call method findAllCC() first * * @return nbCC the number of CC in g */ public int getNBCC() { return nbCC; } public int[] getCC_firstNode() { return CC_firstNode; } public int[] getCC_nextNode() { return CC_nextNode; } public int[] getNode_CC() { return node_CC; } /** * Find all connected components of graph by performing one dfs * Complexity : O(M+N) light and fast in practice */ public void findAllCC() { if (node_CC == null) { CC_firstNode = new int[n]; CC_nextNode = new int[n]; node_CC = new int[n]; } ISet act = graph.getNodes(); for (int i : act) { p[i] = -1; } for(int i=0;i 1) { return false;// ARTICULATION POINT DETECTED } } i = j; k++; numOfNode[i] = k; nodeOfNum[k] = i; inf[i] = numOfNode[i]; } else if (p[i] != j) { inf[i] = Math.min(inf[i], numOfNode[j]); } }else { if (i == start) { return k >= act.size() - 1; } q = inf[i]; i = p[i]; inf[i] = Math.min(q, inf[i]); if (q >= numOfNode[i] && i != start) { return false; } // ARTICULATION POINT DETECTED } } } public TIntArrayList isthmusFrom, isthmusTo; private int[] ND, L, H; /** * Only for undirected graphs * @return true iff g is connected */ public boolean isConnectedAndFindIsthma() { assert (!graph.isDirected()); if (numOfNode == null || CC_firstNode == null) { CC_firstNode = new int[n]; CC_nextNode = new int[n]; node_CC = new int[n]; nodeOfNum = new int[n]; numOfNode = new int[n]; isthmusFrom = new TIntArrayList(); isthmusTo = new TIntArrayList(); ND = new int[n]; L = new int[n]; H = new int[n]; } ISet act = graph.getNodes(); for (int i : act) { p[i] = -1; iterators[i] = graph.getSuccOrNeighOf(i).iterator(); } for(int i=0;i= 0; i--) { currentNode = nodeOfNum[i]; ND[currentNode] = 1; L[currentNode] = i; H[currentNode] = i; for (int s : graph.getSuccOrNeighOf(currentNode)) { if (p[s] == currentNode) { ND[currentNode] += ND[s]; L[currentNode] = Math.min(L[currentNode], L[s]); H[currentNode] = Math.max(H[currentNode], H[s]); } else if (s != p[currentNode]) { L[currentNode] = Math.min(L[currentNode], numOfNode[s]); H[currentNode] = Math.max(H[currentNode], numOfNode[s]); } if (s != currentNode && p[s] == currentNode && L[s] >= numOfNode[s] && H[s] < numOfNode[s] + ND[s]) { isthmusFrom.add(currentNode); isthmusTo.add(s); } } } return true; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy