[Lemon-commits] [lemon_svn] marci: r1258 - in hugo/trunk/src: lemon test

Lemon SVN svn at lemon.cs.elte.hu
Mon Nov 6 20:44:13 CET 2006


Author: marci
Date: Fri Oct  1 13:31:03 2004
New Revision: 1258

Modified:
   hugo/trunk/src/lemon/graph_wrapper.h
   hugo/trunk/src/test/graph_wrapper_test.cc

Log:
NodeSubGraphWrapper, test, and ducumentation modifications.


Modified: hugo/trunk/src/lemon/graph_wrapper.h
==============================================================================
--- hugo/trunk/src/lemon/graph_wrapper.h	(original)
+++ hugo/trunk/src/lemon/graph_wrapper.h	Fri Oct  1 13:31:03 2004
@@ -368,115 +368,9 @@
   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);
-  
-  typedef EdgeSubGraphWrapper<Graph, TightEdgeFilter> SubGW;
-  SubGW gw(g, 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);
+  For other examples see also the documentation of NodeSubGraphWrapper and 
+  EdgeSubGraphWrapper.
 
-  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, 
@@ -670,6 +564,36 @@
   };
 
 
+  /*! \brief A wrapper for hiding nodes 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.
+  
+  A wrapper for hiding nodes from a graph.
+  This wrapper specializes SubGraphWrapper in the way that only the node-set 
+  can be filtered. Note that this does not mean of considering induced 
+  subgraph, the edge-iterators consider the original edge-set.
+  \author Marton Makai
+  */
+  template<typename Graph, typename NodeFilterMap>
+  class NodeSubGraphWrapper : 
+    public SubGraphWrapper<Graph, NodeFilterMap, 
+			   ConstMap<typename Graph::Edge,bool> > {
+  public:
+    typedef SubGraphWrapper<Graph, NodeFilterMap, 
+			    ConstMap<typename Graph::Edge,bool> > Parent;
+  protected:
+    ConstMap<typename Graph::Edge, bool> const_true_map;
+  public:
+    NodeSubGraphWrapper(Graph& _graph, NodeFilterMap& _node_filter_map) : 
+      Parent(), const_true_map(true) { 
+      Parent::setGraph(_graph);
+      Parent::setNodeFilterMap(_node_filter_map);
+      Parent::setEdgeFilterMap(const_true_map);
+    }
+  };
+
+
   /*! \brief A wrapper for hiding edges from a graph.
 
   \warning Graph wrappers are in even more experimental state than the other
@@ -677,7 +601,123 @@
   
   A wrapper for hiding edges from a graph.
   This wrapper specializes SubGraphWrapper in the way that only the edge-set 
-  can be filtered.
+  can be filtered. The usefulness of this wrapper is demonstrated in the 
+  problem of searching a maximum number of edge-disjoint shortest paths 
+  between 
+  two nodes \c s and \c t. Shortest here means being shortest w.r.t. 
+  non-negative edge-lengths. Note that 
+  the comprehension of the presented solution 
+  need's some knowledge from elementary combinatorial optimization. 
+
+  If a single 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 paths 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);
+  
+  typedef EdgeSubGraphWrapper<Graph, TightEdgeFilter> SubGW;
+  SubGW gw(g, 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 EdgeFilterMap>

Modified: hugo/trunk/src/test/graph_wrapper_test.cc
==============================================================================
--- hugo/trunk/src/test/graph_wrapper_test.cc	(original)
+++ hugo/trunk/src/test/graph_wrapper_test.cc	Fri Oct  1 13:31:03 2004
@@ -49,6 +49,14 @@
 			Graph::EdgeMap<bool> > SubGW;
 template void checkCompileStaticGraph<SubGW>(SubGW &);
 
+//Compile NodeSubGraphWrapper
+typedef NodeSubGraphWrapper<Graph, Graph::NodeMap<bool> > NodeSubGW;
+template void checkCompileStaticGraph<NodeSubGW>(NodeSubGW &);
+
+//Compile EdgeSubGraphWrapper
+typedef EdgeSubGraphWrapper<Graph, Graph::EdgeMap<bool> > EdgeSubGW;
+template void checkCompileStaticGraph<EdgeSubGW>(EdgeSubGW &);
+
 //Compile UndirGraphWrapper
 /// \bug UndirGraphWrapper cannot pass the StaticGraph test
 //typedef UndirGraphWrapper<Graph> UndirGW;



More information about the Lemon-commits mailing list