Correcting the structure of the graph's and adaptor's map.
The template assign operators and map iterators can be used for adaptors also.
Some bugfix in the adaptors
New class SwapBpUGraphAdaptor which swaps the two nodeset of the graph.
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