# HG changeset patch # User deba # Date 1147799622 0 # Node ID 67258b5a057ba911b532b0f9be900513e00d4b69 # Parent 3fc072264f7748828d17d6ced99399a563b2bbe0 DirUGraphAdaptor documentation diff -r 3fc072264f77 -r 67258b5a057b lemon/ugraph_adaptor.h --- a/lemon/ugraph_adaptor.h Tue May 16 16:59:57 2006 +0000 +++ b/lemon/ugraph_adaptor.h Tue May 16 17:13:42 2006 +0000 @@ -879,6 +879,11 @@ return EdgeSubUGraphAdaptor(graph, efm); } + /// \brief Base of direct undirected graph adaptor + /// + /// Base class of the direct undirected graph adaptor. All public member + /// of this class can be used with the DirUGraphAdaptor too. + /// \sa DirUGraphAdaptor template class DirUGraphAdaptorBase { public: @@ -889,10 +894,20 @@ typedef typename _UGraph::Node Node; typedef typename _UGraph::UEdge Edge; + /// \brief Reverse edge + /// + /// It reverse the given edge. It simply negate the direction in the map. void reverseEdge(const Edge& edge) { direction->set(edge, !(*direction)[edge]); } + /// \brief Returns the original direction in the undirected graph. + /// + /// Returns the original direction in the undirected graph. + bool direction(const Edge& edge) const { + return (*direction)[edge]; + } + void first(Node& i) const { graph->first(i); } void first(Edge& i) const { graph->first(i); } void firstIn(Edge& i, const Node& n) const { @@ -1057,12 +1072,78 @@ /// /// \brief A directed graph is made from an undirected graph by an adaptor /// - /// This adaptor gives a direction for each uedge in the undirected graph. - /// The direction of the edges stored in the DirectionMap. This map is - /// a bool map on the undirected edges. If the uedge is mapped to true - /// then the direction of the directed edge will be the same as the - /// default direction of the uedge. The edges can be easily reverted - /// by the reverseEdge member in the adaptor. + /// This adaptor gives a direction for each uedge in the undirected + /// graph. The direction of the edges stored in the + /// DirectionMap. This map is a bool map on the undirected edges. If + /// the uedge is mapped to true then the direction of the directed + /// edge will be the same as the default direction of the uedge. The + /// edges can be easily reverted by the \ref + /// DirUGraphAdaptorBase::reverseEdge "reverseEdge()" member in the + /// adaptor. + /// + /// It can be used to solve orientation problems on directed graphs. + /// By example how can we orient an undirected graph to get the minimum + /// number of strongly connected components. If we orient the edges with + /// the dfs algorithm out from the source then we will get such an + /// orientation. + /// + /// We use the \ref DfsVisitor "visitor" interface of the + /// \ref DfsVisit "dfs" algorithm: + ///\code + /// template + /// class OrientVisitor : public DfsVisitor { + /// public: + /// + /// OrientVisitor(const UGraph& ugraph, DirMap& dirMap) + /// : _ugraph(ugraph), _dirMap(dirMap), _processed(ugraph, false) {} + /// + /// void discover(const Edge& edge) { + /// _processed.set(edge, true); + /// _dirMap.set(edge, _ugraph.direction(edge)); + /// } + /// + /// void examine(const Edge& edge) { + /// if (_processed[edge]) return; + /// _processed.set(edge, true); + /// _dirMap.set(edge, _ugraph.direction(edge)); + /// } + /// + /// private: + /// const UGraph& _ugraph; + /// DirMap& _dirMap; + /// UGraph::UEdgeMap _processed; + /// }; + ///\endcode + /// + /// And now we can use the orientation: + ///\code + /// UGraph::UEdgeMap dmap(ugraph); + /// + /// typedef OrientVisitor > Visitor; + /// Visitor visitor(ugraph, dmap); + /// + /// DfsVisit dfs(ugraph, visitor); + /// + /// dfs.run(); + /// + /// typedef DirUGraphAdaptor DGraph; + /// DGraph dgraph(ugraph, dmap); + /// + /// LEMON_ASSERT(countStronglyConnectedComponents(dgraph) == + /// countBiEdgeConnectedComponents(ugraph), "Wrong Orientation"); + ///\endcode + /// + /// The number of the bi-connected components is a lower bound for + /// the number of the strongly connected components in the directed + /// graph because if we contract the bi-connected components to + /// nodes we will get a tree therefore we cannot orient edges in + /// both direction between bi-connected components. In the other way + /// the algorithm will orient one component to be strongly + /// connected. The two relations proof that the assertion will + /// be always true and the found solution is optimal. + /// + /// \sa DirUGraphAdaptorBase + /// \sa dirUGraphAdaptor template > class DirUGraphAdaptor : @@ -1075,12 +1156,19 @@ protected: DirUGraphAdaptor() { } public: + + /// \brief Constructor of the adaptor + /// + /// Constructor of the adaptor DirUGraphAdaptor(_Graph& _graph, DirectionMap& _direction_map) { setGraph(_graph); setDirectionMap(_direction_map); } }; + /// \brief Just gives back a DirUGraphAdaptor + /// + /// Just gives back a DirUGraphAdaptor template DirUGraphAdaptor dirUGraphAdaptor(const UGraph& graph, DirectionMap& dm) {