[Lemon-commits] Balazs Dezso: Port topology.h as connectivity.h ...
Lemon HG
hg at lemon.cs.elte.hu
Tue Dec 2 16:35:21 CET 2008
details: http://lemon.cs.elte.hu/hg/lemon/rev/6ff53afe98b5
changeset: 433:6ff53afe98b5
user: Balazs Dezso <deba [at] inf.elte.hu>
date: Sun Nov 30 22:06:52 2008 +0100
description:
Port topology.h as connectivity.h from SVN -r3509 (#61)
diffstat:
1 file changed, 1572 insertions(+)
lemon/connectivity.h | 1572 ++++++++++++++++++++++++++++++++++++++++++++++++++
diffs (truncated from 1576 to 300 lines):
diff -r 76287c8caa26 -r 6ff53afe98b5 lemon/connectivity.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/lemon/connectivity.h Sun Nov 30 22:06:52 2008 +0100
@@ -0,0 +1,1572 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2008
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#ifndef LEMON_TOPOLOGY_H
+#define LEMON_TOPOLOGY_H
+
+#include <lemon/dfs.h>
+#include <lemon/bfs.h>
+#include <lemon/core.h>
+#include <lemon/maps.h>
+#include <lemon/adaptors.h>
+
+#include <lemon/concepts/digraph.h>
+#include <lemon/concepts/graph.h>
+#include <lemon/concept_check.h>
+
+#include <stack>
+#include <functional>
+
+/// \ingroup connectivity
+/// \file
+/// \brief Connectivity algorithms
+///
+/// Connectivity algorithms
+
+namespace lemon {
+
+ /// \ingroup connectivity
+ ///
+ /// \brief Check whether the given undirected graph is connected.
+ ///
+ /// Check whether the given undirected graph is connected.
+ /// \param graph The undirected graph.
+ /// \return %True when there is path between any two nodes in the graph.
+ /// \note By definition, the empty graph is connected.
+ template <typename Graph>
+ bool connected(const Graph& graph) {
+ checkConcept<concepts::Graph, Graph>();
+ typedef typename Graph::NodeIt NodeIt;
+ if (NodeIt(graph) == INVALID) return true;
+ Dfs<Graph> dfs(graph);
+ dfs.run(NodeIt(graph));
+ for (NodeIt it(graph); it != INVALID; ++it) {
+ if (!dfs.reached(it)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /// \ingroup connectivity
+ ///
+ /// \brief Count the number of connected components of an undirected graph
+ ///
+ /// Count the number of connected components of an undirected graph
+ ///
+ /// \param graph The graph. It must be undirected.
+ /// \return The number of components
+ /// \note By definition, the empty graph consists
+ /// of zero connected components.
+ template <typename Graph>
+ int countConnectedComponents(const Graph &graph) {
+ checkConcept<concepts::Graph, Graph>();
+ typedef typename Graph::Node Node;
+ typedef typename Graph::Arc Arc;
+
+ typedef NullMap<Node, Arc> PredMap;
+ typedef NullMap<Node, int> DistMap;
+
+ int compNum = 0;
+ typename Bfs<Graph>::
+ template SetPredMap<PredMap>::
+ template SetDistMap<DistMap>::
+ Create bfs(graph);
+
+ PredMap predMap;
+ bfs.predMap(predMap);
+
+ DistMap distMap;
+ bfs.distMap(distMap);
+
+ bfs.init();
+ for(typename Graph::NodeIt n(graph); n != INVALID; ++n) {
+ if (!bfs.reached(n)) {
+ bfs.addSource(n);
+ bfs.start();
+ ++compNum;
+ }
+ }
+ return compNum;
+ }
+
+ /// \ingroup connectivity
+ ///
+ /// \brief Find the connected components of an undirected graph
+ ///
+ /// Find the connected components of an undirected graph.
+ ///
+ /// \param graph The graph. It must be undirected.
+ /// \retval compMap A writable node map. The values will be set from 0 to
+ /// the number of the connected components minus one. Each values of the map
+ /// will be set exactly once, the values of a certain component will be
+ /// set continuously.
+ /// \return The number of components
+ ///
+ template <class Graph, class NodeMap>
+ int connectedComponents(const Graph &graph, NodeMap &compMap) {
+ checkConcept<concepts::Graph, Graph>();
+ typedef typename Graph::Node Node;
+ typedef typename Graph::Arc Arc;
+ checkConcept<concepts::WriteMap<Node, int>, NodeMap>();
+
+ typedef NullMap<Node, Arc> PredMap;
+ typedef NullMap<Node, int> DistMap;
+
+ int compNum = 0;
+ typename Bfs<Graph>::
+ template SetPredMap<PredMap>::
+ template SetDistMap<DistMap>::
+ Create bfs(graph);
+
+ PredMap predMap;
+ bfs.predMap(predMap);
+
+ DistMap distMap;
+ bfs.distMap(distMap);
+
+ bfs.init();
+ for(typename Graph::NodeIt n(graph); n != INVALID; ++n) {
+ if(!bfs.reached(n)) {
+ bfs.addSource(n);
+ while (!bfs.emptyQueue()) {
+ compMap.set(bfs.nextNode(), compNum);
+ bfs.processNextNode();
+ }
+ ++compNum;
+ }
+ }
+ return compNum;
+ }
+
+ namespace _topology_bits {
+
+ template <typename Digraph, typename Iterator >
+ struct LeaveOrderVisitor : public DfsVisitor<Digraph> {
+ public:
+ typedef typename Digraph::Node Node;
+ LeaveOrderVisitor(Iterator it) : _it(it) {}
+
+ void leave(const Node& node) {
+ *(_it++) = node;
+ }
+
+ private:
+ Iterator _it;
+ };
+
+ template <typename Digraph, typename Map>
+ struct FillMapVisitor : public DfsVisitor<Digraph> {
+ public:
+ typedef typename Digraph::Node Node;
+ typedef typename Map::Value Value;
+
+ FillMapVisitor(Map& map, Value& value)
+ : _map(map), _value(value) {}
+
+ void reach(const Node& node) {
+ _map.set(node, _value);
+ }
+ private:
+ Map& _map;
+ Value& _value;
+ };
+
+ template <typename Digraph, typename ArcMap>
+ struct StronglyConnectedCutEdgesVisitor : public DfsVisitor<Digraph> {
+ public:
+ typedef typename Digraph::Node Node;
+ typedef typename Digraph::Arc Arc;
+
+ StronglyConnectedCutEdgesVisitor(const Digraph& digraph,
+ ArcMap& cutMap,
+ int& cutNum)
+ : _digraph(digraph), _cutMap(cutMap), _cutNum(cutNum),
+ _compMap(digraph), _num(0) {
+ }
+
+ void stop(const Node&) {
+ ++_num;
+ }
+
+ void reach(const Node& node) {
+ _compMap.set(node, _num);
+ }
+
+ void examine(const Arc& arc) {
+ if (_compMap[_digraph.source(arc)] !=
+ _compMap[_digraph.target(arc)]) {
+ _cutMap.set(arc, true);
+ ++_cutNum;
+ }
+ }
+ private:
+ const Digraph& _digraph;
+ ArcMap& _cutMap;
+ int& _cutNum;
+
+ typename Digraph::template NodeMap<int> _compMap;
+ int _num;
+ };
+
+ }
+
+
+ /// \ingroup connectivity
+ ///
+ /// \brief Check whether the given directed graph is strongly connected.
+ ///
+ /// Check whether the given directed graph is strongly connected. The
+ /// graph is strongly connected when any two nodes of the graph are
+ /// connected with directed paths in both direction.
+ /// \return %False when the graph is not strongly connected.
+ /// \see connected
+ ///
+ /// \note By definition, the empty graph is strongly connected.
+ template <typename Digraph>
+ bool stronglyConnected(const Digraph& digraph) {
+ checkConcept<concepts::Digraph, Digraph>();
+
+ typedef typename Digraph::Node Node;
+ typedef typename Digraph::NodeIt NodeIt;
+
+ typename Digraph::Node source = NodeIt(digraph);
+ if (source == INVALID) return true;
+
+ using namespace _topology_bits;
+
+ typedef DfsVisitor<Digraph> Visitor;
+ Visitor visitor;
+
+ DfsVisit<Digraph, Visitor> dfs(digraph, visitor);
+ dfs.init();
+ dfs.addSource(source);
+ dfs.start();
+
+ for (NodeIt it(digraph); it != INVALID; ++it) {
+ if (!dfs.reached(it)) {
+ return false;
+ }
+ }
+
+ typedef ReverseDigraph<const Digraph> RDigraph;
+ RDigraph rdigraph(digraph);
+
+ typedef DfsVisitor<Digraph> RVisitor;
+ RVisitor rvisitor;
+
+ DfsVisit<RDigraph, RVisitor> rdfs(rdigraph, rvisitor);
+ rdfs.init();
+ rdfs.addSource(source);
+ rdfs.start();
+
+ for (NodeIt it(rdigraph); it != INVALID; ++it) {
+ if (!rdfs.reached(it)) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ /// \ingroup connectivity
+ ///
+ /// \brief Count the strongly connected components of a directed graph
+ ///
+ /// Count the strongly connected components of a directed graph.
+ /// The strongly connected components are the classes of an
+ /// equivalence relation on the nodes of the graph. Two nodes are in
+ /// the same class if they are connected with directed paths in both
+ /// direction.
+ ///
More information about the Lemon-commits
mailing list