[Lemon-commits] [lemon_svn] marci: r1252 - hugo/trunk/src/lemon
Lemon SVN
svn at lemon.cs.elte.hu
Mon Nov 6 20:44:11 CET 2006
Author: marci
Date: Thu Sep 30 19:30:20 2004
New Revision: 1252
Modified:
hugo/trunk/src/lemon/graph_wrapper.h
Log:
documentation os SubGraphWrapper with code example.
Modified: hugo/trunk/src/lemon/graph_wrapper.h
==============================================================================
--- hugo/trunk/src/lemon/graph_wrapper.h (original)
+++ hugo/trunk/src/lemon/graph_wrapper.h Thu Sep 30 19:30:20 2004
@@ -327,48 +327,159 @@
- /// A graph wrapper for hiding nodes and edges from a graph.
+ /*! \brief A graph wrapper for hiding nodes and edges from a graph.
- ///\warning Graph wrappers are in even more experimental state than the other
- ///parts of the lib. Use them at you own risk.
- ///
- /// This wrapper shows a graph with filtered node-set and
- /// edge-set.
- /// Given a bool-valued map on the node-set and one on
- /// the edge-set of the graph, the iterators show only the objects
- /// having true value. We have to note that this does not mean that an
- /// induced subgraph is obtained, the node-iterator cares only the filter
- /// on the node-set, and the edge-iterators care only the filter on the
- /// edge-set.
- /// \code
- /// typedef SmartGraph Graph;
- /// Graph g;
- /// typedef Graph::Node Node;
- /// typedef Graph::Edge Edge;
- /// Node u=g.addNode(); //node of id 0
- /// Node v=g.addNode(); //node of id 1
- /// Node e=g.addEdge(u, v); //edge of id 0
- /// Node f=g.addEdge(v, u); //edge of id 1
- /// Graph::NodeMap<bool> nm(g, true);
- /// nm.set(u, false);
- /// Graph::EdgeMap<bool> em(g, true);
- /// em.set(e, false);
- /// typedef SubGraphWrapper<Graph, Graph::NodeMap<bool>, Graph::EdgeMap<bool> > SubGW;
- /// SubGW gw(g, nm, em);
- /// for (SubGW::NodeIt n(gw); n!=INVALID; ++n) std::cout << g.id(n) << std::endl;
- /// std::cout << ":-)" << std::endl;
- /// for (SubGW::EdgeIt e(gw); e!=INVALID; ++e) std::cout << g.id(e) << std::endl;
- /// \endcode
- /// The output of the above code is the following.
- /// \code
- /// 1
- /// :-)
- /// 1
- /// \endcode
- /// Note that \c n is of type \c SubGW::NodeIt, but it can be converted to
- /// \c Graph::Node that is why \c g.id(n) can be applied.
- ///
- ///\author Marton Makai
+ \warning Graph wrappers are in even more experimental state than the other
+ parts of the lib. Use them at you own risk.
+
+ This wrapper shows a graph with filtered node-set and
+ edge-set.
+ Given a bool-valued map on the node-set and one on
+ the edge-set of the graph, the iterators show only the objects
+ having true value. We have to note that this does not mean that an
+ induced subgraph is obtained, the node-iterator cares only the filter
+ on the node-set, and the edge-iterators care only the filter on the
+ edge-set.
+ \code
+ typedef SmartGraph Graph;
+ Graph g;
+ typedef Graph::Node Node;
+ typedef Graph::Edge Edge;
+ Node u=g.addNode(); //node of id 0
+ Node v=g.addNode(); //node of id 1
+ Node e=g.addEdge(u, v); //edge of id 0
+ Node f=g.addEdge(v, u); //edge of id 1
+ Graph::NodeMap<bool> nm(g, true);
+ nm.set(u, false);
+ Graph::EdgeMap<bool> em(g, true);
+ em.set(e, false);
+ typedef SubGraphWrapper<Graph, Graph::NodeMap<bool>, Graph::EdgeMap<bool> > SubGW;
+ SubGW gw(g, nm, em);
+ for (SubGW::NodeIt n(gw); n!=INVALID; ++n) std::cout << g.id(n) << std::endl;
+ std::cout << ":-)" << std::endl;
+ for (SubGW::EdgeIt e(gw); e!=INVALID; ++e) std::cout << g.id(e) << std::endl;
+ \endcode
+ The output of the above code is the following.
+ \code
+ 1
+ :-)
+ 1
+ \endcode
+ Note that \c n is of type \c SubGW::NodeIt, but it can be converted to
+ \c Graph::Node that is why \c g.id(n) can be applied.
+
+ Consider now a mathematically more invloved problem, where the application
+ of SubGraphWrapper is reasonable sure enough. If a shortest path is to be
+ searched between two nodes \c s and \c t, then this can be done easily by
+ applying the Dijkstra algorithm class. What happens, if a maximum number of
+ edge-disjoint shortest paths is to be computed. It can be proved that an
+ edge can be in a shortest path if and only if it is tight with respect to
+ the potential function computed by Dijkstra. Moreover, any path containing
+ only such edges is a shortest one. Thus we have to compute a maximum number
+ of edge-disjoint path between \c s and \c t in the graph which has edge-set
+ all the tight edges. The computation will be demonstrated on the following
+ graph, which is read from a dimacs file.
+
+ \dot
+ digraph lemon_dot_example {
+ node [ shape=ellipse, fontname=Helvetica, fontsize=10 ];
+ n0 [ label="0 (s)" ];
+ n1 [ label="1" ];
+ n2 [ label="2" ];
+ n3 [ label="3" ];
+ n4 [ label="4" ];
+ n5 [ label="5" ];
+ n6 [ label="6 (t)" ];
+ edge [ shape=ellipse, fontname=Helvetica, fontsize=10 ];
+ n5 -> n6 [ label="9, length:4" ];
+ n4 -> n6 [ label="8, length:2" ];
+ n3 -> n5 [ label="7, length:1" ];
+ n2 -> n5 [ label="6, length:3" ];
+ n2 -> n6 [ label="5, length:5" ];
+ n2 -> n4 [ label="4, length:2" ];
+ n1 -> n4 [ label="3, length:3" ];
+ n0 -> n3 [ label="2, length:1" ];
+ n0 -> n2 [ label="1, length:2" ];
+ n0 -> n1 [ label="0, length:3" ];
+ }
+ \enddot
+
+ \code
+ Graph g;
+ Node s, t;
+ LengthMap length(g);
+
+ readDimacs(std::cin, g, length, s, t);
+
+ cout << "edges with lengths (of form id, tail--length->head): " << endl;
+ for(EdgeIt e(g); e!=INVALID; ++e)
+ cout << g.id(e) << ", " << g.id(g.tail(e)) << "--"
+ << length[e] << "->" << g.id(g.head(e)) << endl;
+
+ cout << "s: " << g.id(s) << " t: " << g.id(t) << endl;
+ \endcode
+ Next, the potential function is computed with Dijkstra.
+ \code
+ typedef Dijkstra<Graph, LengthMap> Dijkstra;
+ Dijkstra dijkstra(g, length);
+ dijkstra.run(s);
+ \endcode
+ Next, we consrtruct a map which filters the edge-set to the tight edges.
+ \code
+ typedef TightEdgeFilterMap<Graph, const Dijkstra::DistMap, LengthMap>
+ TightEdgeFilter;
+ TightEdgeFilter tight_edge_filter(g, dijkstra.distMap(), length);
+
+ ConstMap<Node, bool> const_true_map(true);
+ typedef SubGraphWrapper<Graph, ConstMap<Node, bool>, TightEdgeFilter> SubGW;
+ SubGW gw(g, const_true_map, tight_edge_filter);
+ \endcode
+ Then, the maximum nimber of edge-disjoint \c s-\c t paths are computed
+ with a max flow algorithm Preflow.
+ \code
+ ConstMap<Edge, int> const_1_map(1);
+ Graph::EdgeMap<int> flow(g, 0);
+
+ Preflow<SubGW, int, ConstMap<Edge, int>, Graph::EdgeMap<int> >
+ preflow(gw, s, t, const_1_map, flow);
+ preflow.run();
+ \endcode
+ Last, the output is:
+ \code
+ cout << "maximum number of edge-disjoint shortest path: "
+ << preflow.flowValue() << endl;
+ cout << "edges of the maximum number of edge-disjoint shortest s-t paths: "
+ << endl;
+ for(EdgeIt e(g); e!=INVALID; ++e)
+ if (flow[e])
+ cout << " " << g.id(g.tail(e)) << "--"
+ << length[e] << "->" << g.id(g.head(e)) << endl;
+ \endcode
+ The program has the following (expected :-)) output:
+ \code
+ edges with lengths (of form id, tail--length->head):
+ 9, 5--4->6
+ 8, 4--2->6
+ 7, 3--1->5
+ 6, 2--3->5
+ 5, 2--5->6
+ 4, 2--2->4
+ 3, 1--3->4
+ 2, 0--1->3
+ 1, 0--2->2
+ 0, 0--3->1
+ s: 0 t: 6
+ maximum number of edge-disjoint shortest path: 2
+ edges of the maximum number of edge-disjoint shortest s-t paths:
+ 9, 5--4->6
+ 8, 4--2->6
+ 7, 3--1->5
+ 4, 2--2->4
+ 2, 0--1->3
+ 1, 0--2->2
+ \endcode
+ \author Marton Makai
+ */
template<typename Graph, typename NodeFilterMap,
typename EdgeFilterMap>
class SubGraphWrapper : public GraphWrapper<Graph> {
More information about the Lemon-commits
mailing list