- Increased max. number of iteration
- Better tests.
3 * This file is a part of LEMON, a generic C++ optimization library
5 * Copyright (C) 2003-2006
6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 * (Egervary Research Group on Combinatorial Optimization, EGRES).
9 * Permission to use, modify and distribute this software is granted
10 * provided that this copyright notice appears in all copies. For
11 * precise terms see the accompanying LICENSE file.
13 * This software is provided "AS IS" with no warranty of any kind,
14 * express or implied, and with no claim as to its suitability for any
19 #ifndef LEMON_TOPOLOGY_H
20 #define LEMON_TOPOLOGY_H
22 #include <lemon/dfs.h>
23 #include <lemon/bfs.h>
24 #include <lemon/graph_utils.h>
25 #include <lemon/graph_adaptor.h>
26 #include <lemon/maps.h>
28 #include <lemon/concept/graph.h>
29 #include <lemon/concept/ugraph.h>
30 #include <lemon/concept_check.h>
32 #include <lemon/bin_heap.h>
33 #include <lemon/linear_heap.h>
40 /// \brief Topology related algorithms
42 /// Topology related algorithms
48 /// \brief Check that the given undirected graph is connected.
50 /// Check that the given undirected graph connected.
51 /// \param graph The undirected graph.
52 /// \return %True when there is path between any two nodes in the graph.
53 /// \note By definition, the empty graph is connected.
54 template <typename UGraph>
55 bool connected(const UGraph& graph) {
56 checkConcept<concept::UGraph, UGraph>();
57 typedef typename UGraph::NodeIt NodeIt;
58 if (NodeIt(graph) == INVALID) return true;
59 Dfs<UGraph> dfs(graph);
60 dfs.run(NodeIt(graph));
61 for (NodeIt it(graph); it != INVALID; ++it) {
62 if (!dfs.reached(it)) {
71 /// \brief Count the number of connected components of an undirected graph
73 /// Count the number of connected components of an undirected graph
75 /// \param graph The graph. It should be undirected.
76 /// \return The number of components
77 /// \note By definition, the empty graph consists
78 /// of zero connected components.
79 template <typename UGraph>
80 int countConnectedComponents(const UGraph &graph) {
81 checkConcept<concept::UGraph, UGraph>();
82 typedef typename UGraph::Node Node;
83 typedef typename UGraph::Edge Edge;
85 typedef NullMap<Node, Edge> PredMap;
86 typedef NullMap<Node, int> DistMap;
89 typename Bfs<UGraph>::
90 template DefPredMap<PredMap>::
91 template DefDistMap<DistMap>::
101 for(typename UGraph::NodeIt n(graph); n != INVALID; ++n) {
102 if (!bfs.reached(n)) {
111 /// \ingroup topology
113 /// \brief Find the connected components of an undirected graph
115 /// Find the connected components of an undirected graph.
117 /// \image html connected_components.png
118 /// \image latex connected_components.eps "Connected components" width=\textwidth
120 /// \param graph The graph. It should be undirected.
121 /// \retval compMap A writable node map. The values will be set from 0 to
122 /// the number of the connected components minus one. Each values of the map
123 /// will be set exactly once, the values of a certain component will be
124 /// set continuously.
125 /// \return The number of components
127 template <class UGraph, class NodeMap>
128 int connectedComponents(const UGraph &graph, NodeMap &compMap) {
129 checkConcept<concept::UGraph, UGraph>();
130 typedef typename UGraph::Node Node;
131 typedef typename UGraph::Edge Edge;
132 checkConcept<concept::WriteMap<Node, int>, NodeMap>();
134 typedef NullMap<Node, Edge> PredMap;
135 typedef NullMap<Node, int> DistMap;
138 typename Bfs<UGraph>::
139 template DefPredMap<PredMap>::
140 template DefDistMap<DistMap>::
144 bfs.predMap(predMap);
147 bfs.distMap(distMap);
150 for(typename UGraph::NodeIt n(graph); n != INVALID; ++n) {
151 if(!bfs.reached(n)) {
153 while (!bfs.emptyQueue()) {
154 compMap.set(bfs.nextNode(), compNum);
155 bfs.processNextNode();
163 namespace _topology_bits {
165 template <typename Graph, typename Iterator >
166 struct LeaveOrderVisitor : public DfsVisitor<Graph> {
168 typedef typename Graph::Node Node;
169 LeaveOrderVisitor(Iterator it) : _it(it) {}
171 void leave(const Node& node) {
179 template <typename Graph, typename Map>
180 struct FillMapVisitor : public DfsVisitor<Graph> {
182 typedef typename Graph::Node Node;
183 typedef typename Map::Value Value;
185 FillMapVisitor(Map& map, Value& value)
186 : _map(map), _value(value) {}
188 void reach(const Node& node) {
189 _map.set(node, _value);
196 template <typename Graph, typename EdgeMap>
197 struct StronglyConnectedCutEdgesVisitor : public DfsVisitor<Graph> {
199 typedef typename Graph::Node Node;
200 typedef typename Graph::Edge Edge;
202 StronglyConnectedCutEdgesVisitor(const Graph& graph, EdgeMap& cutMap,
204 : _graph(graph), _cutMap(cutMap), _cutNum(cutNum),
205 _compMap(graph), _num(0) {
208 void stop(const Node&) {
212 void reach(const Node& node) {
213 _compMap.set(node, _num);
216 void examine(const Edge& edge) {
217 if (_compMap[_graph.source(edge)] != _compMap[_graph.target(edge)]) {
218 _cutMap.set(edge, true);
227 typename Graph::template NodeMap<int> _compMap;
234 /// \ingroup topology
236 /// \brief Check that the given directed graph is strongly connected.
238 /// Check that the given directed graph is strongly connected. The
239 /// graph is strongly connected when any two nodes of the graph are
240 /// connected with directed paths in both direction.
241 /// \return %False when the graph is not strongly connected.
244 /// \note By definition, the empty graph is strongly connected.
245 template <typename Graph>
246 bool stronglyConnected(const Graph& graph) {
247 checkConcept<concept::StaticGraph, Graph>();
248 if (NodeIt(graph) == INVALID) return true;
250 typedef typename Graph::Node Node;
251 typedef typename Graph::NodeIt NodeIt;
253 using namespace _topology_bits;
255 typedef DfsVisitor<Graph> Visitor;
258 DfsVisit<Graph, Visitor> dfs(graph, visitor);
260 dfs.addSource(NodeIt(graph));
263 for (NodeIt it(graph); it != INVALID; ++it) {
264 if (!dfs.reached(it)) {
269 typedef RevGraphAdaptor<const Graph> RGraph;
270 RGraph rgraph(graph);
272 typedef DfsVisitor<Graph> RVisitor;
275 DfsVisit<RGraph, RVisitor> rdfs(rgraph, rvisitor);
277 rdfs.addSource(NodeIt(graph));
280 for (NodeIt it(graph); it != INVALID; ++it) {
281 if (!rdfs.reached(it)) {
289 /// \ingroup topology
291 /// \brief Count the strongly connected components of a directed graph
293 /// Count the strongly connected components of a directed graph.
294 /// The strongly connected components are the classes of an equivalence
295 /// relation on the nodes of the graph. Two nodes are connected with
296 /// directed paths in both direction.
298 /// \param graph The graph.
299 /// \return The number of components
300 /// \note By definition, the empty graph has zero
301 /// strongly connected components.
302 template <typename Graph>
303 int countStronglyConnectedComponents(const Graph& graph) {
304 checkConcept<concept::StaticGraph, Graph>();
306 using namespace _topology_bits;
308 typedef typename Graph::Node Node;
309 typedef typename Graph::Edge Edge;
310 typedef typename Graph::NodeIt NodeIt;
311 typedef typename Graph::EdgeIt EdgeIt;
313 typedef std::vector<Node> Container;
314 typedef typename Container::iterator Iterator;
316 Container nodes(countNodes(graph));
317 typedef LeaveOrderVisitor<Graph, Iterator> Visitor;
318 Visitor visitor(nodes.begin());
320 DfsVisit<Graph, Visitor> dfs(graph, visitor);
322 for (NodeIt it(graph); it != INVALID; ++it) {
323 if (!dfs.reached(it)) {
329 typedef typename Container::reverse_iterator RIterator;
330 typedef RevGraphAdaptor<const Graph> RGraph;
332 RGraph rgraph(graph);
334 typedef DfsVisitor<Graph> RVisitor;
337 DfsVisit<RGraph, RVisitor> rdfs(rgraph, rvisitor);
342 for (RIterator it = nodes.rbegin(); it != nodes.rend(); ++it) {
343 if (!rdfs.reached(*it)) {
352 /// \ingroup topology
354 /// \brief Find the strongly connected components of a directed graph
356 /// Find the strongly connected components of a directed graph.
357 /// The strongly connected components are the classes of an equivalence
358 /// relation on the nodes of the graph. Two nodes are in relationship
359 /// when there are directed paths between them in both direction.
361 /// \image html strongly_connected_components.png
362 /// \image latex strongly_connected_components.eps "Strongly connected components" width=\textwidth
364 /// \param graph The graph.
365 /// \retval compMap A writable node map. The values will be set from 0 to
366 /// the number of the strongly connected components minus one. Each values
367 /// of the map will be set exactly once, the values of a certain component
368 /// will be set continuously.
369 /// \return The number of components
371 template <typename Graph, typename NodeMap>
372 int stronglyConnectedComponents(const Graph& graph, NodeMap& compMap) {
373 checkConcept<concept::StaticGraph, Graph>();
374 typedef typename Graph::Node Node;
375 typedef typename Graph::NodeIt NodeIt;
376 checkConcept<concept::WriteMap<Node, int>, NodeMap>();
378 using namespace _topology_bits;
380 typedef std::vector<Node> Container;
381 typedef typename Container::iterator Iterator;
383 Container nodes(countNodes(graph));
384 typedef LeaveOrderVisitor<Graph, Iterator> Visitor;
385 Visitor visitor(nodes.begin());
387 DfsVisit<Graph, Visitor> dfs(graph, visitor);
389 for (NodeIt it(graph); it != INVALID; ++it) {
390 if (!dfs.reached(it)) {
396 typedef typename Container::reverse_iterator RIterator;
397 typedef RevGraphAdaptor<const Graph> RGraph;
399 RGraph rgraph(graph);
403 typedef FillMapVisitor<RGraph, NodeMap> RVisitor;
404 RVisitor rvisitor(compMap, compNum);
406 DfsVisit<RGraph, RVisitor> rdfs(rgraph, rvisitor);
409 for (RIterator it = nodes.rbegin(); it != nodes.rend(); ++it) {
410 if (!rdfs.reached(*it)) {
419 /// \ingroup topology
421 /// \brief Find the cut edges of the strongly connected components.
423 /// Find the cut edges of the strongly connected components.
424 /// The strongly connected components are the classes of an equivalence
425 /// relation on the nodes of the graph. Two nodes are in relationship
426 /// when there are directed paths between them in both direction.
427 /// The strongly connected components are separated by the cut edges.
429 /// \param graph The graph.
430 /// \retval cutMap A writable node map. The values will be set true when the
431 /// edge is a cut edge.
433 /// \return The number of cut edges
434 template <typename Graph, typename EdgeMap>
435 int stronglyConnectedCutEdges(const Graph& graph, EdgeMap& cutMap) {
436 checkConcept<concept::StaticGraph, Graph>();
437 typedef typename Graph::Node Node;
438 typedef typename Graph::Edge Edge;
439 typedef typename Graph::NodeIt NodeIt;
440 checkConcept<concept::WriteMap<Edge, bool>, EdgeMap>();
442 using namespace _topology_bits;
444 typedef std::vector<Node> Container;
445 typedef typename Container::iterator Iterator;
447 Container nodes(countNodes(graph));
448 typedef LeaveOrderVisitor<Graph, Iterator> Visitor;
449 Visitor visitor(nodes.begin());
451 DfsVisit<Graph, Visitor> dfs(graph, visitor);
453 for (NodeIt it(graph); it != INVALID; ++it) {
454 if (!dfs.reached(it)) {
460 typedef typename Container::reverse_iterator RIterator;
461 typedef RevGraphAdaptor<const Graph> RGraph;
463 RGraph rgraph(graph);
467 typedef StronglyConnectedCutEdgesVisitor<RGraph, EdgeMap> RVisitor;
468 RVisitor rvisitor(rgraph, cutMap, cutNum);
470 DfsVisit<RGraph, RVisitor> rdfs(rgraph, rvisitor);
473 for (RIterator it = nodes.rbegin(); it != nodes.rend(); ++it) {
474 if (!rdfs.reached(*it)) {
482 namespace _topology_bits {
484 template <typename Graph>
485 class CountBiNodeConnectedComponentsVisitor : public DfsVisitor<Graph> {
487 typedef typename Graph::Node Node;
488 typedef typename Graph::Edge Edge;
489 typedef typename Graph::UEdge UEdge;
491 CountBiNodeConnectedComponentsVisitor(const Graph& graph, int &compNum)
492 : _graph(graph), _compNum(compNum),
493 _numMap(graph), _retMap(graph), _predMap(graph), _num(0) {}
495 void start(const Node& node) {
496 _predMap.set(node, INVALID);
499 void reach(const Node& node) {
500 _numMap.set(node, _num);
501 _retMap.set(node, _num);
505 void discover(const Edge& edge) {
506 _predMap.set(_graph.target(edge), _graph.source(edge));
509 void examine(const Edge& edge) {
510 if (_graph.source(edge) == _graph.target(edge) &&
511 _graph.direction(edge)) {
515 if (_predMap[_graph.source(edge)] == _graph.target(edge)) {
518 if (_retMap[_graph.source(edge)] > _numMap[_graph.target(edge)]) {
519 _retMap.set(_graph.source(edge), _numMap[_graph.target(edge)]);
523 void backtrack(const Edge& edge) {
524 if (_retMap[_graph.source(edge)] > _retMap[_graph.target(edge)]) {
525 _retMap.set(_graph.source(edge), _retMap[_graph.target(edge)]);
527 if (_numMap[_graph.source(edge)] <= _retMap[_graph.target(edge)]) {
536 typename Graph::template NodeMap<int> _numMap;
537 typename Graph::template NodeMap<int> _retMap;
538 typename Graph::template NodeMap<Node> _predMap;
542 template <typename Graph, typename EdgeMap>
543 class BiNodeConnectedComponentsVisitor : public DfsVisitor<Graph> {
545 typedef typename Graph::Node Node;
546 typedef typename Graph::Edge Edge;
547 typedef typename Graph::UEdge UEdge;
549 BiNodeConnectedComponentsVisitor(const Graph& graph,
550 EdgeMap& compMap, int &compNum)
551 : _graph(graph), _compMap(compMap), _compNum(compNum),
552 _numMap(graph), _retMap(graph), _predMap(graph), _num(0) {}
554 void start(const Node& node) {
555 _predMap.set(node, INVALID);
558 void reach(const Node& node) {
559 _numMap.set(node, _num);
560 _retMap.set(node, _num);
564 void discover(const Edge& edge) {
565 Node target = _graph.target(edge);
566 _predMap.set(target, edge);
567 _edgeStack.push(edge);
570 void examine(const Edge& edge) {
571 Node source = _graph.source(edge);
572 Node target = _graph.target(edge);
573 if (source == target && _graph.direction(edge)) {
574 _compMap.set(edge, _compNum);
578 if (_numMap[target] < _numMap[source]) {
579 if (_predMap[source] != _graph.oppositeEdge(edge)) {
580 _edgeStack.push(edge);
583 if (_predMap[source] != INVALID &&
584 target == _graph.source(_predMap[source])) {
587 if (_retMap[source] > _numMap[target]) {
588 _retMap.set(source, _numMap[target]);
592 void backtrack(const Edge& edge) {
593 Node source = _graph.source(edge);
594 Node target = _graph.target(edge);
595 if (_retMap[source] > _retMap[target]) {
596 _retMap.set(source, _retMap[target]);
598 if (_numMap[source] <= _retMap[target]) {
599 while (_edgeStack.top() != edge) {
600 _compMap.set(_edgeStack.top(), _compNum);
603 _compMap.set(edge, _compNum);
614 typename Graph::template NodeMap<int> _numMap;
615 typename Graph::template NodeMap<int> _retMap;
616 typename Graph::template NodeMap<Edge> _predMap;
617 std::stack<UEdge> _edgeStack;
622 template <typename Graph, typename NodeMap>
623 class BiNodeConnectedCutNodesVisitor : public DfsVisitor<Graph> {
625 typedef typename Graph::Node Node;
626 typedef typename Graph::Edge Edge;
627 typedef typename Graph::UEdge UEdge;
629 BiNodeConnectedCutNodesVisitor(const Graph& graph, NodeMap& cutMap,
631 : _graph(graph), _cutMap(cutMap), _cutNum(cutNum),
632 _numMap(graph), _retMap(graph), _predMap(graph), _num(0) {}
634 void start(const Node& node) {
635 _predMap.set(node, INVALID);
639 void reach(const Node& node) {
640 _numMap.set(node, _num);
641 _retMap.set(node, _num);
645 void discover(const Edge& edge) {
646 _predMap.set(_graph.target(edge), _graph.source(edge));
649 void examine(const Edge& edge) {
650 if (_graph.source(edge) == _graph.target(edge) &&
651 _graph.direction(edge)) {
652 if (!_cutMap[_graph.source(edge)]) {
653 _cutMap.set(_graph.source(edge), true);
658 if (_predMap[_graph.source(edge)] == _graph.target(edge)) return;
659 if (_retMap[_graph.source(edge)] > _numMap[_graph.target(edge)]) {
660 _retMap.set(_graph.source(edge), _numMap[_graph.target(edge)]);
664 void backtrack(const Edge& edge) {
665 if (_retMap[_graph.source(edge)] > _retMap[_graph.target(edge)]) {
666 _retMap.set(_graph.source(edge), _retMap[_graph.target(edge)]);
668 if (_numMap[_graph.source(edge)] <= _retMap[_graph.target(edge)]) {
669 if (_predMap[_graph.source(edge)] != INVALID) {
670 if (!_cutMap[_graph.source(edge)]) {
671 _cutMap.set(_graph.source(edge), true);
674 } else if (rootCut) {
675 if (!_cutMap[_graph.source(edge)]) {
676 _cutMap.set(_graph.source(edge), true);
690 typename Graph::template NodeMap<int> _numMap;
691 typename Graph::template NodeMap<int> _retMap;
692 typename Graph::template NodeMap<Node> _predMap;
693 std::stack<UEdge> _edgeStack;
700 template <typename UGraph>
701 int countBiNodeConnectedComponents(const UGraph& graph);
703 /// \ingroup topology
705 /// \brief Checks the graph is bi-node-connected.
707 /// This function checks that the undirected graph is bi-node-connected
708 /// graph. The graph is bi-node-connected if any two undirected edge is
711 /// \param graph The graph.
712 /// \return %True when the graph bi-node-connected.
713 /// \todo Make it faster.
714 template <typename UGraph>
715 bool biNodeConnected(const UGraph& graph) {
716 return countBiNodeConnectedComponents(graph) == 1;
719 /// \ingroup topology
721 /// \brief Count the biconnected components.
723 /// This function finds the bi-node-connected components in an undirected
724 /// graph. The biconnected components are the classes of an equivalence
725 /// relation on the undirected edges. Two undirected edge is in relationship
726 /// when they are on same circle.
728 /// \param graph The graph.
729 /// \return The number of components.
730 template <typename UGraph>
731 int countBiNodeConnectedComponents(const UGraph& graph) {
732 checkConcept<concept::UGraph, UGraph>();
733 typedef typename UGraph::NodeIt NodeIt;
735 using namespace _topology_bits;
737 typedef CountBiNodeConnectedComponentsVisitor<UGraph> Visitor;
740 Visitor visitor(graph, compNum);
742 DfsVisit<UGraph, Visitor> dfs(graph, visitor);
745 for (NodeIt it(graph); it != INVALID; ++it) {
746 if (!dfs.reached(it)) {
754 /// \ingroup topology
756 /// \brief Find the bi-node-connected components.
758 /// This function finds the bi-node-connected components in an undirected
759 /// graph. The bi-node-connected components are the classes of an equivalence
760 /// relation on the undirected edges. Two undirected edge are in relationship
761 /// when they are on same circle.
763 /// \image html node_biconnected_components.png
764 /// \image latex node_biconnected_components.eps "bi-node-connected components" width=\textwidth
766 /// \param graph The graph.
767 /// \retval compMap A writable uedge map. The values will be set from 0
768 /// to the number of the biconnected components minus one. Each values
769 /// of the map will be set exactly once, the values of a certain component
770 /// will be set continuously.
771 /// \return The number of components.
773 template <typename UGraph, typename UEdgeMap>
774 int biNodeConnectedComponents(const UGraph& graph,
776 checkConcept<concept::UGraph, UGraph>();
777 typedef typename UGraph::NodeIt NodeIt;
778 typedef typename UGraph::UEdge UEdge;
779 checkConcept<concept::WriteMap<UEdge, int>, UEdgeMap>();
781 using namespace _topology_bits;
783 typedef BiNodeConnectedComponentsVisitor<UGraph, UEdgeMap> Visitor;
786 Visitor visitor(graph, compMap, compNum);
788 DfsVisit<UGraph, Visitor> dfs(graph, visitor);
791 for (NodeIt it(graph); it != INVALID; ++it) {
792 if (!dfs.reached(it)) {
800 /// \ingroup topology
802 /// \brief Find the bi-node-connected cut nodes.
804 /// This function finds the bi-node-connected cut nodes in an undirected
805 /// graph. The bi-node-connected components are the classes of an equivalence
806 /// relation on the undirected edges. Two undirected edges are in
807 /// relationship when they are on same circle. The biconnected components
808 /// are separted by nodes which are the cut nodes of the components.
810 /// \param graph The graph.
811 /// \retval cutMap A writable edge map. The values will be set true when
812 /// the node separate two or more components.
813 /// \return The number of the cut nodes.
814 template <typename UGraph, typename NodeMap>
815 int biNodeConnectedCutNodes(const UGraph& graph, NodeMap& cutMap) {
816 checkConcept<concept::UGraph, UGraph>();
817 typedef typename UGraph::Node Node;
818 typedef typename UGraph::NodeIt NodeIt;
819 checkConcept<concept::WriteMap<Node, bool>, NodeMap>();
821 using namespace _topology_bits;
823 typedef BiNodeConnectedCutNodesVisitor<UGraph, NodeMap> Visitor;
826 Visitor visitor(graph, cutMap, cutNum);
828 DfsVisit<UGraph, Visitor> dfs(graph, visitor);
831 for (NodeIt it(graph); it != INVALID; ++it) {
832 if (!dfs.reached(it)) {
840 namespace _topology_bits {
842 template <typename Graph>
843 class CountBiEdgeConnectedComponentsVisitor : public DfsVisitor<Graph> {
845 typedef typename Graph::Node Node;
846 typedef typename Graph::Edge Edge;
847 typedef typename Graph::UEdge UEdge;
849 CountBiEdgeConnectedComponentsVisitor(const Graph& graph, int &compNum)
850 : _graph(graph), _compNum(compNum),
851 _numMap(graph), _retMap(graph), _predMap(graph), _num(0) {}
853 void start(const Node& node) {
854 _predMap.set(node, INVALID);
857 void reach(const Node& node) {
858 _numMap.set(node, _num);
859 _retMap.set(node, _num);
863 void leave(const Node& node) {
864 if (_numMap[node] <= _retMap[node]) {
869 void discover(const Edge& edge) {
870 _predMap.set(_graph.target(edge), edge);
873 void examine(const Edge& edge) {
874 if (_predMap[_graph.source(edge)] == _graph.oppositeEdge(edge)) {
877 if (_retMap[_graph.source(edge)] > _retMap[_graph.target(edge)]) {
878 _retMap.set(_graph.source(edge), _retMap[_graph.target(edge)]);
882 void backtrack(const Edge& edge) {
883 if (_retMap[_graph.source(edge)] > _retMap[_graph.target(edge)]) {
884 _retMap.set(_graph.source(edge), _retMap[_graph.target(edge)]);
892 typename Graph::template NodeMap<int> _numMap;
893 typename Graph::template NodeMap<int> _retMap;
894 typename Graph::template NodeMap<Edge> _predMap;
898 template <typename Graph, typename NodeMap>
899 class BiEdgeConnectedComponentsVisitor : public DfsVisitor<Graph> {
901 typedef typename Graph::Node Node;
902 typedef typename Graph::Edge Edge;
903 typedef typename Graph::UEdge UEdge;
905 BiEdgeConnectedComponentsVisitor(const Graph& graph,
906 NodeMap& compMap, int &compNum)
907 : _graph(graph), _compMap(compMap), _compNum(compNum),
908 _numMap(graph), _retMap(graph), _predMap(graph), _num(0) {}
910 void start(const Node& node) {
911 _predMap.set(node, INVALID);
914 void reach(const Node& node) {
915 _numMap.set(node, _num);
916 _retMap.set(node, _num);
917 _nodeStack.push(node);
921 void leave(const Node& node) {
922 if (_numMap[node] <= _retMap[node]) {
923 while (_nodeStack.top() != node) {
924 _compMap.set(_nodeStack.top(), _compNum);
927 _compMap.set(node, _compNum);
933 void discover(const Edge& edge) {
934 _predMap.set(_graph.target(edge), edge);
937 void examine(const Edge& edge) {
938 if (_predMap[_graph.source(edge)] == _graph.oppositeEdge(edge)) {
941 if (_retMap[_graph.source(edge)] > _retMap[_graph.target(edge)]) {
942 _retMap.set(_graph.source(edge), _retMap[_graph.target(edge)]);
946 void backtrack(const Edge& edge) {
947 if (_retMap[_graph.source(edge)] > _retMap[_graph.target(edge)]) {
948 _retMap.set(_graph.source(edge), _retMap[_graph.target(edge)]);
957 typename Graph::template NodeMap<int> _numMap;
958 typename Graph::template NodeMap<int> _retMap;
959 typename Graph::template NodeMap<Edge> _predMap;
960 std::stack<Node> _nodeStack;
965 template <typename Graph, typename EdgeMap>
966 class BiEdgeConnectedCutEdgesVisitor : public DfsVisitor<Graph> {
968 typedef typename Graph::Node Node;
969 typedef typename Graph::Edge Edge;
970 typedef typename Graph::UEdge UEdge;
972 BiEdgeConnectedCutEdgesVisitor(const Graph& graph,
973 EdgeMap& cutMap, int &cutNum)
974 : _graph(graph), _cutMap(cutMap), _cutNum(cutNum),
975 _numMap(graph), _retMap(graph), _predMap(graph), _num(0) {}
977 void start(const Node& node) {
978 _predMap[node] = INVALID;
981 void reach(const Node& node) {
982 _numMap.set(node, _num);
983 _retMap.set(node, _num);
987 void leave(const Node& node) {
988 if (_numMap[node] <= _retMap[node]) {
989 if (_predMap[node] != INVALID) {
990 _cutMap.set(_predMap[node], true);
996 void discover(const Edge& edge) {
997 _predMap.set(_graph.target(edge), edge);
1000 void examine(const Edge& edge) {
1001 if (_predMap[_graph.source(edge)] == _graph.oppositeEdge(edge)) {
1004 if (_retMap[_graph.source(edge)] > _retMap[_graph.target(edge)]) {
1005 _retMap.set(_graph.source(edge), _retMap[_graph.target(edge)]);
1009 void backtrack(const Edge& edge) {
1010 if (_retMap[_graph.source(edge)] > _retMap[_graph.target(edge)]) {
1011 _retMap.set(_graph.source(edge), _retMap[_graph.target(edge)]);
1016 const Graph& _graph;
1020 typename Graph::template NodeMap<int> _numMap;
1021 typename Graph::template NodeMap<int> _retMap;
1022 typename Graph::template NodeMap<Edge> _predMap;
1027 template <typename UGraph>
1028 int countbiEdgeConnectedComponents(const UGraph& graph);
1030 /// \ingroup topology
1032 /// \brief Checks that the graph is bi-edge-connected.
1034 /// This function checks that the graph is bi-edge-connected. The undirected
1035 /// graph is bi-edge-connected when any two nodes are connected with two
1036 /// edge-disjoint paths.
1038 /// \param graph The undirected graph.
1039 /// \return The number of components.
1040 /// \todo Make it faster.
1041 template <typename UGraph>
1042 bool biEdgeConnected(const UGraph& graph) {
1043 return countBiEdgeConnectedComponents(graph) == 1;
1046 /// \ingroup topology
1048 /// \brief Count the bi-edge-connected components.
1050 /// This function count the bi-edge-connected components in an undirected
1051 /// graph. The bi-edge-connected components are the classes of an equivalence
1052 /// relation on the nodes. Two nodes are in relationship when they are
1053 /// connected with at least two edge-disjoint paths.
1055 /// \param graph The undirected graph.
1056 /// \return The number of components.
1057 template <typename UGraph>
1058 int countBiEdgeConnectedComponents(const UGraph& graph) {
1059 checkConcept<concept::UGraph, UGraph>();
1060 typedef typename UGraph::NodeIt NodeIt;
1062 using namespace _topology_bits;
1064 typedef CountBiEdgeConnectedComponentsVisitor<UGraph> Visitor;
1067 Visitor visitor(graph, compNum);
1069 DfsVisit<UGraph, Visitor> dfs(graph, visitor);
1072 for (NodeIt it(graph); it != INVALID; ++it) {
1073 if (!dfs.reached(it)) {
1081 /// \ingroup topology
1083 /// \brief Find the bi-edge-connected components.
1085 /// This function finds the bi-edge-connected components in an undirected
1086 /// graph. The bi-edge-connected components are the classes of an equivalence
1087 /// relation on the nodes. Two nodes are in relationship when they are
1088 /// connected at least two edge-disjoint paths.
1090 /// \image html edge_biconnected_components.png
1091 /// \image latex edge_biconnected_components.eps "bi-edge-connected components" width=\textwidth
1093 /// \param graph The graph.
1094 /// \retval compMap A writable node map. The values will be set from 0 to
1095 /// the number of the biconnected components minus one. Each values
1096 /// of the map will be set exactly once, the values of a certain component
1097 /// will be set continuously.
1098 /// \return The number of components.
1100 template <typename UGraph, typename NodeMap>
1101 int biEdgeConnectedComponents(const UGraph& graph, NodeMap& compMap) {
1102 checkConcept<concept::UGraph, UGraph>();
1103 typedef typename UGraph::NodeIt NodeIt;
1104 typedef typename UGraph::Node Node;
1105 checkConcept<concept::WriteMap<Node, int>, NodeMap>();
1107 using namespace _topology_bits;
1109 typedef BiEdgeConnectedComponentsVisitor<UGraph, NodeMap> Visitor;
1112 Visitor visitor(graph, compMap, compNum);
1114 DfsVisit<UGraph, Visitor> dfs(graph, visitor);
1117 for (NodeIt it(graph); it != INVALID; ++it) {
1118 if (!dfs.reached(it)) {
1126 /// \ingroup topology
1128 /// \brief Find the bi-edge-connected cut edges.
1130 /// This function finds the bi-edge-connected components in an undirected
1131 /// graph. The bi-edge-connected components are the classes of an equivalence
1132 /// relation on the nodes. Two nodes are in relationship when they are
1133 /// connected with at least two edge-disjoint paths. The bi-edge-connected
1134 /// components are separted by edges which are the cut edges of the
1137 /// \param graph The graph.
1138 /// \retval cutMap A writable node map. The values will be set true when the
1139 /// edge is a cut edge.
1140 /// \return The number of cut edges.
1141 template <typename UGraph, typename UEdgeMap>
1142 int biEdgeConnectedCutEdges(const UGraph& graph, UEdgeMap& cutMap) {
1143 checkConcept<concept::UGraph, UGraph>();
1144 typedef typename UGraph::NodeIt NodeIt;
1145 typedef typename UGraph::UEdge UEdge;
1146 checkConcept<concept::WriteMap<UEdge, bool>, UEdgeMap>();
1148 using namespace _topology_bits;
1150 typedef BiEdgeConnectedCutEdgesVisitor<UGraph, UEdgeMap> Visitor;
1153 Visitor visitor(graph, cutMap, cutNum);
1155 DfsVisit<UGraph, Visitor> dfs(graph, visitor);
1158 for (NodeIt it(graph); it != INVALID; ++it) {
1159 if (!dfs.reached(it)) {
1168 namespace _topology_bits {
1170 template <typename Graph, typename IntNodeMap>
1171 class TopologicalSortVisitor : public DfsVisitor<Graph> {
1173 typedef typename Graph::Node Node;
1174 typedef typename Graph::Edge edge;
1176 TopologicalSortVisitor(IntNodeMap& order, int num)
1177 : _order(order), _num(num) {}
1179 void leave(const Node& node) {
1180 _order.set(node, --_num);
1190 /// \ingroup topology
1192 /// \brief Sort the nodes of a DAG into topolgical order.
1194 /// Sort the nodes of a DAG into topolgical order.
1196 /// \param graph The graph. It should be directed and acyclic.
1197 /// \retval order A writable node map. The values will be set from 0 to
1198 /// the number of the nodes in the graph minus one. Each values of the map
1199 /// will be set exactly once, the values will be set descending order.
1201 /// \see checkedTopologicalSort
1203 template <typename Graph, typename NodeMap>
1204 void topologicalSort(const Graph& graph, NodeMap& order) {
1205 using namespace _topology_bits;
1207 checkConcept<concept::StaticGraph, Graph>();
1208 checkConcept<concept::WriteMap<typename Graph::Node, int>, NodeMap>();
1210 typedef typename Graph::Node Node;
1211 typedef typename Graph::NodeIt NodeIt;
1212 typedef typename Graph::Edge Edge;
1214 TopologicalSortVisitor<Graph, NodeMap>
1215 visitor(order, countNodes(graph));
1217 DfsVisit<Graph, TopologicalSortVisitor<Graph, NodeMap> >
1218 dfs(graph, visitor);
1221 for (NodeIt it(graph); it != INVALID; ++it) {
1222 if (!dfs.reached(it)) {
1229 /// \ingroup topology
1231 /// \brief Sort the nodes of a DAG into topolgical order.
1233 /// Sort the nodes of a DAG into topolgical order. It also checks
1234 /// that the given graph is DAG.
1236 /// \param graph The graph. It should be directed and acyclic.
1237 /// \retval order A readable - writable node map. The values will be set
1238 /// from 0 to the number of the nodes in the graph minus one. Each values
1239 /// of the map will be set exactly once, the values will be set descending
1241 /// \return %False when the graph is not DAG.
1243 /// \see topologicalSort
1245 template <typename Graph, typename NodeMap>
1246 bool checkedTopologicalSort(const Graph& graph, NodeMap& order) {
1247 using namespace _topology_bits;
1249 checkConcept<concept::StaticGraph, Graph>();
1250 checkConcept<concept::ReadWriteMap<typename Graph::Node, int>, NodeMap>();
1252 typedef typename Graph::Node Node;
1253 typedef typename Graph::NodeIt NodeIt;
1254 typedef typename Graph::Edge Edge;
1256 order = constMap<Node, int, -1>();
1258 TopologicalSortVisitor<Graph, NodeMap>
1259 visitor(order, countNodes(graph));
1261 DfsVisit<Graph, TopologicalSortVisitor<Graph, NodeMap> >
1262 dfs(graph, visitor);
1265 for (NodeIt it(graph); it != INVALID; ++it) {
1266 if (!dfs.reached(it)) {
1268 while (!dfs.emptyQueue()) {
1269 Edge edge = dfs.nextEdge();
1270 Node target = graph.target(edge);
1271 if (dfs.reached(target) && order[target] == -1) {
1274 dfs.processNextEdge();
1281 /// \ingroup topology
1283 /// \brief Check that the given directed graph is a DAG.
1285 /// Check that the given directed graph is a DAG. The DAG is
1286 /// an Directed Acyclic Graph.
1287 /// \return %False when the graph is not DAG.
1289 template <typename Graph>
1290 bool dag(const Graph& graph) {
1292 checkConcept<concept::StaticGraph, Graph>();
1294 typedef typename Graph::Node Node;
1295 typedef typename Graph::NodeIt NodeIt;
1296 typedef typename Graph::Edge Edge;
1298 typedef typename Graph::template NodeMap<bool> ProcessedMap;
1300 typename Dfs<Graph>::template DefProcessedMap<ProcessedMap>::
1303 ProcessedMap processed(graph);
1304 dfs.processedMap(processed);
1307 for (NodeIt it(graph); it != INVALID; ++it) {
1308 if (!dfs.reached(it)) {
1310 while (!dfs.emptyQueue()) {
1311 Edge edge = dfs.nextEdge();
1312 Node target = graph.target(edge);
1313 if (dfs.reached(target) && !processed[target]) {
1316 dfs.processNextEdge();
1323 /// \ingroup topology
1325 /// \brief Check that the given undirected graph is acyclic.
1327 /// Check that the given undirected graph acyclic.
1328 /// \param graph The undirected graph.
1329 /// \return %True when there is no circle in the graph.
1331 template <typename UGraph>
1332 bool acyclic(const UGraph& graph) {
1333 checkConcept<concept::UGraph, UGraph>();
1334 typedef typename UGraph::Node Node;
1335 typedef typename UGraph::NodeIt NodeIt;
1336 typedef typename UGraph::Edge Edge;
1337 Dfs<UGraph> dfs(graph);
1339 for (NodeIt it(graph); it != INVALID; ++it) {
1340 if (!dfs.reached(it)) {
1342 while (!dfs.emptyQueue()) {
1343 Edge edge = dfs.nextEdge();
1344 Node source = graph.source(edge);
1345 Node target = graph.target(edge);
1346 if (dfs.reached(target) &&
1347 dfs.predEdge(source) != graph.oppositeEdge(edge)) {
1350 dfs.processNextEdge();
1357 /// \ingroup topology
1359 /// \brief Check that the given undirected graph is tree.
1361 /// Check that the given undirected graph is tree.
1362 /// \param graph The undirected graph.
1363 /// \return %True when the graph is acyclic and connected.
1364 template <typename UGraph>
1365 bool tree(const UGraph& graph) {
1366 checkConcept<concept::UGraph, UGraph>();
1367 typedef typename UGraph::Node Node;
1368 typedef typename UGraph::NodeIt NodeIt;
1369 typedef typename UGraph::Edge Edge;
1370 Dfs<UGraph> dfs(graph);
1372 dfs.addSource(NodeIt(graph));
1373 while (!dfs.emptyQueue()) {
1374 Edge edge = dfs.nextEdge();
1375 Node source = graph.source(edge);
1376 Node target = graph.target(edge);
1377 if (dfs.reached(target) &&
1378 dfs.predEdge(source) != graph.oppositeEdge(edge)) {
1381 dfs.processNextEdge();
1383 for (NodeIt it(graph); it != INVALID; ++it) {
1384 if (!dfs.reached(it)) {
1391 /// \ingroup topology
1393 /// \brief Check if the given undirected graph is bipartite or not
1395 /// The function checks if the given undirected \c graph graph is bipartite
1396 /// or not. The \ref Bfs algorithm is used to calculate the result.
1397 /// \param graph The undirected graph.
1398 /// \return %True if \c graph is bipartite, %false otherwise.
1399 /// \sa bipartitePartitions
1401 /// \author Balazs Attila Mihaly
1402 template<typename UGraph>
1403 inline bool bipartite(const UGraph &graph){
1404 checkConcept<concept::UGraph, UGraph>();
1406 typedef typename UGraph::NodeIt NodeIt;
1407 typedef typename UGraph::EdgeIt EdgeIt;
1409 Bfs<UGraph> bfs(graph);
1411 for(NodeIt i(graph);i!=INVALID;++i){
1412 if(!bfs.reached(i)){
1416 for(EdgeIt i(graph);i!=INVALID;++i){
1417 if(bfs.dist(graph.source(i))==bfs.dist(graph.target(i)))return false;
1422 /// \ingroup topology
1424 /// \brief Check if the given undirected graph is bipartite or not
1426 /// The function checks if the given undirected graph is bipartite
1427 /// or not. The \ref Bfs algorithm is used to calculate the result.
1428 /// During the execution, the \c partMap will be set as the two
1429 /// partitions of the graph.
1430 /// \param graph The undirected graph.
1431 /// \retval partMap A writable bool map of nodes. It will be set as the
1432 /// two partitions of the graph.
1433 /// \return %True if \c graph is bipartite, %false otherwise.
1435 /// \author Balazs Attila Mihaly
1437 /// \image html bipartite_partitions.png
1438 /// \image latex bipartite_partitions.eps "Bipartite partititions" width=\textwidth
1439 template<typename UGraph, typename NodeMap>
1440 inline bool bipartitePartitions(const UGraph &graph, NodeMap &partMap){
1441 checkConcept<concept::UGraph, UGraph>();
1443 typedef typename UGraph::Node Node;
1444 typedef typename UGraph::NodeIt NodeIt;
1445 typedef typename UGraph::EdgeIt EdgeIt;
1447 Bfs<UGraph> bfs(graph);
1449 for(NodeIt i(graph);i!=INVALID;++i){
1450 if(!bfs.reached(i)){
1452 for(Node j=bfs.processNextNode();!bfs.emptyQueue();
1453 j=bfs.processNextNode()){
1454 partMap.set(j,bfs.dist(j)%2==0);
1458 for(EdgeIt i(graph);i!=INVALID;++i){
1459 if(bfs.dist(graph.source(i)) == bfs.dist(graph.target(i)))return false;
1466 #endif //LEMON_TOPOLOGY_H