//================================================================================================== // G r a p h _ p r o b l e m Interface // C o n n e c t i v i t y // By Bruno Bachelet //================================================================================================== // Copyright (c) 1999-2016 // Bruno Bachelet - bruno@nawouak.net - http://www.nawouak.net // // This file is part of the B++ Library. This library is free software; you can redistribute it // and/or modify it under the terms of the GNU Library General Public License as published by the // Free Software Foundation; either version 2 of the License, or (at your option) any later // version. // // This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; // without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See // the GNU Library General Public License for more details (http://www.gnu.org).
/*DESCRIPTION*/ /* This module provides facilities to solve connectivity problems in graphs. */
// File Name //------------------------------------------------------------------------------------- #line __LINE__ "graph_problem/connectivity.hpp"
// Guardian //-------------------------------------------------------------------------------------- #ifndef guGraphProblemConnectivity #define guGraphProblemConnectivity
// Headers //--------------------------------------------------------------------------------------- #include <bpp/graph.hpp> /*INCLUDE*/
namespace bpp {
// Importation/Exportation //----------------------------------------------------------------------- #ifdef GRAPH_PROBLEM_DLL #define dll_export DLL_EXPORT #else #define dll_export DLL_IMPORT #endif
// Namespaces //------------------------------------------------------------------------------------ #define public_area graphProblemConnectivity #define private_area graphProblemConnectivity_private
namespace public_area { /*NAMESPACE*/ using namespace graph; } namespace private_area { using namespace public_area; }
extern_module_name;
// Initialization //-------------------------------------------------------------------------------- #define iniGraphProblemConnectivity has_initializer;
// Macrocommands //--------------------------------------------------------------------------------- /*ALIAS*/ #define tdGraph class prArcData,class prNodeData //
/*ALIAS*/ #define tuGraph prArcData,prNodeData //
// Types & Classes //------------------------------------------------------------------------------- namespace public_area {} namespace private_area {}
// Functions Interface //--------------------------------------------------------------------------- namespace public_area { template <tdGraph> void findConnectedComponent(clGraph<tuGraph> &,tyNodeKey,std_vector(clNode<tuGraph> *) &);
template <tdGraph> void findConnectedComponents(clGraph<tuGraph> &,std_vector(std_vector(clNode<tuGraph> *)) &);
template <tdGraph> void findStronglyConnectedComponent(clGraph<tuGraph> &,tyNodeKey,std_vector(clNode<tuGraph> *) &);
template <tdGraph> void findStronglyConnectedComponents(clGraph<tuGraph> &, std_vector(std_vector(clNode<tuGraph> *)) &); }
namespace private_area { template <tdGraph> void findStronglyConnectedComponent(clGraph<tuGraph> &,clNode<tuGraph> &, std_vector(clNode<tuGraph> *) &,tyMark agMark);
testing_mode ( function void test(void); ) }
// Errors //---------------------------------------------------------------------------------------- namespace public_area {}
// Constants & Variables //------------------------------------------------------------------------- extern_dynamic_constant(private,clString,goDataLocation,?);
// X X X Interface //------------------------------------------------------------------------------ namespace {}
// Functions Inline //------------------------------------------------------------------------------ namespace public_area {} namespace private_area {}
// X X X Inline //--------------------------------------------------------------------------------- namespace {}
// Functions Implementation //---------------------------------------------------------------------- namespace public_area { //---------------------------------------------------------------------------FindConnectedComponent /*FUNCTION*/ /* Finds the connected graph component that contains a given node. */ template <tdGraph> void findConnectedComponent(clGraph<tuGraph> & agGraph,tyNodeKey agNodeKey, std_vector(clNode<tuGraph> *) & agComponent) { typedef typename clNode<tuGraph>::cpArcX::const_iterator cpArcIterator; typedef std_vector(clNode<tuGraph> *) cpNodeS;
tyMark lcMark = ++(agGraph.mark()); clNode<tuGraph> & lcNode = agGraph.node(agNodeKey);
clArc<tuGraph> * lcArc; cpArcIterator lcCurrentArc; cpArcIterator lcLastArc; clNode<tuGraph> * lcNode1; clNode<tuGraph> * lcNode2; cpNodeS lcNodeS; cpNodeS lcSet;
agComponent.erase(agComponent.begin(),agComponent.end()); lcNode.mark()=lcMark; lcNodeS.push_back(&lcNode);
while (lcNodeS.size()>0) { lcNode1=lcNodeS.back(); lcNodeS.pop_back(); agComponent.push_back(lcNode1); lcCurrentArc=lcNode1->incomingArcs().begin(); lcLastArc=lcNode1->incomingArcs().end();
while (lcCurrentArc!=lcLastArc) { lcArc=(*lcCurrentArc).second; lcNode2=lcArc->sourceNode();
if (lcNode2->mark()<lcMark) { lcNode2->mark()=lcMark; lcNodeS.push_back(lcNode2); }
lcCurrentArc++; }
lcCurrentArc=lcNode1->outgoingArcs().begin(); lcLastArc=lcNode1->outgoingArcs().end();
while (lcCurrentArc!=lcLastArc) { lcArc=(*lcCurrentArc).second; lcNode2=lcArc->targetNode();
if (lcNode2->mark()<lcMark) { lcNode2->mark()=lcMark; lcNodeS.push_back(lcNode2); }
lcCurrentArc++; } } } //--------------------------------------------------------------------------FindConnectedComponents /*FUNCTION*/ /* Finds the connected components of a graph. */ template <tdGraph> void findConnectedComponents(clGraph<tuGraph> & agGraph, std_vector(std_vector(clNode<tuGraph> *)) & agComponentS) { typedef std_vector(clNode<tuGraph> *) cpNodeS; typedef typename clGraph<tuGraph>::cpNodeX::const_iterator cpNodeIterator;
cpNodeIterator lcCurrentNode = agGraph.nodes().begin(); cpNodeIterator lcLastNode = agGraph.nodes().end(); tyMark lcMark = agGraph.mark();
while (lcCurrentNode!=lcLastNode) { while (lcCurrentNode!=lcLastNode and (*lcCurrentNode).second->mark()>lcMark) lcCurrentNode++;
if (lcCurrentNode!=lcLastNode) { agComponentS.push_back(cpNodeS()); findConnectedComponent(agGraph,(*lcCurrentNode).second->key(),agComponentS.back()); } } } //-------------------------------------------------------------------FindStronglyConnectedComponent /*FUNCTION*/ /* Finds the strongly connected graph component that contains a given node. */ template <tdGraph> void findStronglyConnectedComponent(clGraph<tuGraph> & agGraph,tyNodeKey agNodeKey, std_vector(clNode<tuGraph> *) & agComponent) { typedef typename clNode<tuGraph>::cpArcX::const_iterator cpArcIterator; typedef std_vector(clNode<tuGraph> *) cpNodeS;
tyMark lcMark1 = ++(agGraph.mark()); tyMark lcMark2 = ++(agGraph.mark()); tyMark lcMark3 = ++(agGraph.mark()); clNode<tuGraph> & lcFirstNode = agGraph.node(agNodeKey);
clArc<tuGraph> * lcArc; cpArcIterator lcCurrentArc; cpArcIterator lcLastArc; cpNodeS lcMarkedNodeS; clNode<tuGraph> * lcNode; cpNodeS lcNodeS;
agComponent.erase(agComponent.begin(),agComponent.end());
// Direct Spreading // lcFirstNode.mark()=lcMark1; lcNodeS.push_back(&lcFirstNode);
while (lcNodeS.size()>0) { lcNode=lcNodeS.back(); lcNodeS.pop_back(); lcCurrentArc=lcNode->incomingArcs().begin(); lcLastArc=lcNode->incomingArcs().end();
while (lcCurrentArc!=lcLastArc) { lcArc=(*lcCurrentArc).second; lcNode=lcArc->sourceNode();
if (lcNode->mark()<lcMark1) { lcNode->mark()=lcMark1; lcNodeS.push_back(lcNode); }
lcCurrentArc++; } }
// Indirect Spreading // lcFirstNode.mark()=lcMark3; lcNodeS.push_back(&lcFirstNode);
while (lcNodeS.size()>0) { lcNode=lcNodeS.back(); lcNodeS.pop_back(); if (lcNode->mark()==lcMark3) agComponent.push_back(lcNode); lcCurrentArc=lcNode->outgoingArcs().begin(); lcLastArc=lcNode->outgoingArcs().end();
while (lcCurrentArc!=lcLastArc) { lcArc=(*lcCurrentArc).second; lcNode=lcArc->targetNode();
if (lcNode->mark()<lcMark2) { if (lcNode->mark()==lcMark1) lcNode->mark()=lcMark3; else lcNode->mark()=lcMark2;
lcNodeS.push_back(lcNode); }
lcCurrentArc++; } } } //------------------------------------------------------------------FindStronglyConnectedComponents /*FUNCTION*/ /* Finds the strongly connected components of a graph. */ template <tdGraph> void findStronglyConnectedComponents(clGraph<tuGraph> & agGraph, std_vector(std_vector(clNode<tuGraph> *)) & agComponentS) { typedef std_vector(clNode<tuGraph> *) cpNodeS; typedef typename clGraph<tuGraph>::cpNodeX::const_iterator cpNodeIterator;
cpNodeIterator lcCurrentNode = agGraph.nodes().begin(); cpNodeIterator lcLastNode = agGraph.nodes().end(); tyMark lcMark = agGraph.mark();
while (lcCurrentNode!=lcLastNode) { while (lcCurrentNode!=lcLastNode and (*lcCurrentNode).second->mark()>lcMark) lcCurrentNode++;
if (lcCurrentNode!=lcLastNode) { agComponentS.push_back(cpNodeS());
private_area::findStronglyConnectedComponent(agGraph,*((*lcCurrentNode).second), agComponentS.back(),lcMark); } } } }
namespace private_area { //-------------------------------------------------------------------FindStronglyConnectedComponent template <tdGraph> void findStronglyConnectedComponent(clGraph<tuGraph> & agGraph,clNode<tuGraph> & agNode, std_vector(clNode<tuGraph> *) & agComponent,tyMark agMark) { typedef typename clNode<tuGraph>::cpArcX::const_iterator cpArcIterator; typedef std_vector(clNode<tuGraph> *) cpNodeS; typedef typename cpNodeS::const_iterator cpNodeIterator;
tyMark lcMark1 = ++(agGraph.mark()); tyMark lcMark2 = ++(agGraph.mark()); tyMark lcMark3 = ++(agGraph.mark());
clArc<tuGraph> * lcArc; cpArcIterator lcCurrentArc; cpNodeIterator lcCurrentNode; cpArcIterator lcLastArc; cpNodeIterator lcLastNode; cpNodeS lcMarkedNodeS; clNode<tuGraph> * lcNode; cpNodeS lcNodeS;
agComponent.erase(agComponent.begin(),agComponent.end());
// Direct Spreading // agNode.mark()=lcMark1; lcNodeS.push_back(&agNode);
while (lcNodeS.size()>0) { lcNode=lcNodeS.back(); lcNodeS.pop_back(); lcCurrentArc=lcNode->incomingArcs().begin(); lcLastArc=lcNode->incomingArcs().end();
while (lcCurrentArc!=lcLastArc) { lcArc=(*lcCurrentArc).second; lcNode=lcArc->sourceNode();
if (lcNode->mark()<lcMark1) { lcNode->mark()=lcMark1; lcNodeS.push_back(lcNode); lcMarkedNodeS.push_back(lcNode); }
lcCurrentArc++; } }
// Indirect Spreading // agNode.mark()=lcMark3; lcNodeS.push_back(&agNode);
while (lcNodeS.size()>0) { lcNode=lcNodeS.back(); lcNodeS.pop_back(); if (lcNode->mark()==lcMark3) agComponent.push_back(lcNode); lcCurrentArc=lcNode->outgoingArcs().begin(); lcLastArc=lcNode->outgoingArcs().end();
while (lcCurrentArc!=lcLastArc) { lcArc=(*lcCurrentArc).second; lcNode=lcArc->targetNode();
if (lcNode->mark()<lcMark2) { if (lcNode->mark()==lcMark1) lcNode->mark()=lcMark3; else { lcNode->mark()=lcMark2; lcMarkedNodeS.push_back(lcNode); }
lcNodeS.push_back(lcNode); }
lcCurrentArc++; } }
// Unmarking // lcCurrentNode=lcMarkedNodeS.begin(); lcLastNode=lcMarkedNodeS.end();
while (lcCurrentNode!=lcLastNode) { if ((*lcCurrentNode)->mark()!=lcMark3) (*lcCurrentNode)->mark()=agMark; lcCurrentNode++; } } }
// End //------------------------------------------------------------------------------------------- } #undef dll_export #undef public_area #undef private_area #undef tdGraph #undef tuGraph #endif |
//================================================================================================== // G r a p h _ p r o b l e m Implementation // C o n n e c t i v i t y // By Bruno Bachelet //================================================================================================== // Copyright (c) 1999-2016 // Bruno Bachelet - bruno@nawouak.net - http://www.nawouak.net // // This file is part of the B++ Library. This library is free software; you can redistribute it // and/or modify it under the terms of the GNU Library General Public License as published by the // Free Software Foundation; either version 2 of the License, or (at your option) any later // version. // // This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; // without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See // the GNU Library General Public License for more details (http://www.gnu.org).
// File Name //------------------------------------------------------------------------------------- #line __LINE__ "graph_problem/connectivity.cpp"
// DLL Belonging //--------------------------------------------------------------------------------- #define GRAPH_PROBLEM_DLL
// Headers //--------------------------------------------------------------------------------------- #include <bpp/graph_problem/connectivity.hpp> /*INTERFACE*/
namespace bpp {
// Namespaces //------------------------------------------------------------------------------------ #define public_area graphProblemConnectivity #define private_area graphProblemConnectivity_private #define dll_export DLL_EXPORT
namespace public_area {} namespace private_area {}
static_module_name("Graph_problem/Connectivity");
// Initialization //-------------------------------------------------------------------------------- #undef iniGraphProblemConnectivity static_constant(private_area::clInitializer,goInitializer);
// Errors //---------------------------------------------------------------------------------------- namespace public_area {}
// Constants & Variables //------------------------------------------------------------------------- dynamic_constant(clString,goDataLocation);
// Static Members //-------------------------------------------------------------------------------- namespace public_area {} namespace private_area {}
// Functions Implementation //---------------------------------------------------------------------- namespace public_area {} namespace private_area {}
// X X X Implementation //------------------------------------------------------------------------- namespace {}
// I n i t i a l i z e r Implementation //--------------------------------------------------------- namespace private_area { //--------------------------------------------------------------------------------------------Start property void clInitializer::start(void) { if (atCounter++ == 0) { try { #include <bpp/modules.hpp> /*NEED*/ registerStop(this); environment::informInitialization(goModuleName);
goDataLocation = new_object(clString(environment::dataLocation()+fileNameSeparator() +"graph_problem"+fileNameSeparator()+"connectivity")); }
initializer_catch; } } //---------------------------------------------------------------------------------------------Stop property void clInitializer::stop(void) { try { environment::informTermination(goModuleName);
delete_object(goDataLocation); }
initializer_catch; } }
// End //------------------------------------------------------------------------------------------- } |
|