[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