[Lemon-commits] [lemon_svn] deba: r2440 - in hugo/trunk: doc lemon

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


Author: deba
Date: Mon Dec 19 15:58:09 2005
New Revision: 2440

Added:
   hugo/trunk/lemon/sub_graph.h
Modified:
   hugo/trunk/doc/groups.dox
   hugo/trunk/lemon/Makefile.am
   hugo/trunk/lemon/edge_set.h

Log:
New file and data structures: sub_graph
Moved to new group with the edge_sets




Modified: hugo/trunk/doc/groups.dox
==============================================================================
--- hugo/trunk/doc/groups.dox	(original)
+++ hugo/trunk/doc/groups.dox	Mon Dec 19 15:58:09 2005
@@ -40,6 +40,16 @@
 */
 
 /**
+ at defgroup semi_adaptors Semi-Adaptors Classes for Graphs
+ at ingroup graphs
+\brief Graph types between real graphs and graph adaptors.
+
+Graph types between real graphs and graph adaptors. These classes
+wrap graphs to give new functionality as the adaptors do it. But the
+other way they are not light-weigth structures as the adaptors.
+*/
+
+/**
 @defgroup maps Maps 
 @ingroup datas
 \brief Some special purpose map to make life easier.
@@ -48,7 +58,6 @@
 new maps from existing ones.
 */
 
-
 /**
 @defgroup graph_maps Graph Maps 
 @ingroup maps

Modified: hugo/trunk/lemon/Makefile.am
==============================================================================
--- hugo/trunk/lemon/Makefile.am	(original)
+++ hugo/trunk/lemon/Makefile.am	Mon Dec 19 15:58:09 2005
@@ -62,6 +62,7 @@
 	radix_heap.h \
 	radix_sort.h \
 	smart_graph.h \
+	sub_graph.h \
 	time_measure.h \
 	topology.h \
 	traits.h \

Modified: hugo/trunk/lemon/edge_set.h
==============================================================================
--- hugo/trunk/lemon/edge_set.h	(original)
+++ hugo/trunk/lemon/edge_set.h	Mon Dec 19 15:58:09 2005
@@ -192,7 +192,7 @@
 
   };
 
-  /// \ingroup graphs
+  /// \ingroup semi_adaptors
   ///
   /// \brief Graph using a node set of another graph and an
   /// own edge set.
@@ -291,7 +291,7 @@
     
   };
 
-  /// \ingroup graphs
+  /// \ingroup semi_adaptors
   ///
   /// \brief Graph using a node set of another graph and an
   /// own undir edge set.
@@ -363,6 +363,12 @@
 	_edgeset.eraseNode(node);
 	Parent::erase(node);
       }
+      virtual void erase(const std::vector<Node>& nodes) {
+	for (int i = 0; i < nodes.size(); ++i) {
+	  _edgeset.eraseNode(nodes[i]);
+	}
+	Parent::erase(nodes);
+      }
       virtual void clear() {
 	_edgeset.clearNodes();
 	Parent::clear();

Added: hugo/trunk/lemon/sub_graph.h
==============================================================================
--- (empty file)
+++ hugo/trunk/lemon/sub_graph.h	Mon Dec 19 15:58:09 2005
@@ -0,0 +1,805 @@
+/* -*- C++ -*-
+ * lemon/sub_graph.h - Part of LEMON, a generic C++ optimization library
+ *
+ * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#ifndef LEMON_SUB_GRAPH_H
+#define LEMON_SUB_GRAPH_H
+
+#include <lemon/graph_adaptor.h>
+
+namespace lemon {
+
+  /// \brief Base for the SubGraph.
+  ///
+  /// Base for the SubGraph.
+  template <typename _Graph>
+  class SubGraphBase : public GraphAdaptorBase<const _Graph> {
+  public:
+    typedef _Graph Graph;
+    typedef SubGraphBase<_Graph> SubGraph;
+    typedef GraphAdaptorBase<const _Graph> Parent;
+    typedef Parent Base;
+
+    typedef typename Parent::Node Node;
+    typedef typename Parent::Edge Edge;
+
+
+  protected:
+
+    class NodesImpl;
+    class EdgesImpl;
+
+    SubGraphBase() {}
+
+    void construct(const Graph& _graph, NodesImpl& _nodes, EdgesImpl& _edges) {
+      Parent::setGraph(_graph);
+      nodes = &_nodes;
+      edges = &_edges;
+      firstNode = INVALID;
+
+      Node node;
+      Parent::first(node);
+      while (node != INVALID) {
+	(*nodes)[node].prev = node;
+	(*nodes)[node].firstIn = INVALID;
+	(*nodes)[node].firstOut = INVALID;
+	Parent::next(node);
+      }
+
+      Edge edge;
+      Parent::first(edge);
+      while (edge != INVALID) {
+	(*edges)[edge].prevOut = edge;
+	Parent::next(edge);
+      }
+    }
+
+  public:
+
+    void first(Node& node) const {
+      node = firstNode;
+    }
+    void next(Node& node) const {
+      node = (*nodes)[node].next;
+    }
+
+    void first(Edge& edge) const {
+      Node node = firstNode;
+      while (node != INVALID && (*nodes)[node].firstOut == INVALID) {
+	node = (*nodes)[node].next;
+      }
+      if (node == INVALID) {
+	edge = INVALID;
+      } else {
+	edge = (*nodes)[node].firstOut;
+      }
+    }
+    void next(Edge& edge) const {
+      if ((*edges)[edge].nextOut != INVALID) {
+	edge = (*edges)[edge].nextOut;
+      } else {
+	Node node = (*nodes)[source(edge)].next;
+	while (node != INVALID && (*nodes)[node].firstOut == INVALID) {
+	  node = (*nodes)[node].next;
+	}
+	if (node == INVALID) {
+	  edge = INVALID;
+	} else {
+	  edge = (*nodes)[node].firstOut;
+	}
+      }
+    }
+
+    void firstOut(Edge& edge, const Node& node) const {
+      edge = (*nodes)[node].firstOut;
+    }
+    void nextOut(Edge& edge) const {
+      edge = (*edges)[edge].nextOut;
+    }
+
+    void firstIn(Edge& edge, const Node& node) const {
+      edge = (*nodes)[node].firstIn;
+    }
+    void nextIn(Edge& edge) const {
+      edge = (*edges)[edge].nextIn;
+    }
+
+    /// \brief Returns true when the given node is hidden.
+    ///
+    /// Returns true when the given node is hidden.
+    bool hidden(const Node& node) const {
+      return (*nodes)[node].prev == node;
+    }
+
+    /// \brief Hide the given node in the sub-graph.
+    ///
+    /// Hide the given node in the sub graph. It just lace out from
+    /// the linked lists the given node. If there are incoming or outgoing
+    /// edges into or from this node then all of these will be hidden.
+    void hide(const Node& node) {
+      if (hidden(node)) return;
+      Edge edge;
+      firstOut(edge, node);
+      while (edge != INVALID) {
+	hide(edge);
+	firstOut(edge, node);
+      }
+
+      firstOut(edge, node);
+      while (edge != INVALID) {
+	hide(edge);
+	firstOut(edge, node);
+      }
+      if ((*nodes)[node].prev != INVALID) {
+	(*nodes)[(*nodes)[node].prev].next = (*nodes)[node].next;
+      } else {
+	firstNode = (*nodes)[node].next;
+      }
+      if ((*nodes)[node].next != INVALID) {
+	(*nodes)[(*nodes)[node].next].prev = (*nodes)[node].prev;
+      }
+      (*nodes)[node].prev = node;
+      (*nodes)[node].firstIn = INVALID;
+      (*nodes)[node].firstOut = INVALID;
+    }
+
+    /// \brief Unhide the given node in the sub-graph.
+    ///
+    /// Unhide the given node in the sub graph. It just lace in the given
+    /// node into the linked lists.
+    void unHide(const Node& node) {
+      if (!hidden(node)) return;
+      (*nodes)[node].next = firstNode;
+      (*nodes)[node].prev = INVALID;
+      if ((*nodes)[node].next != INVALID) {
+	(*nodes)[(*nodes)[node].next].prev = node;
+      }
+      firstNode = node;
+    }
+
+    /// \brief Returns true when the given edge is hidden.
+    ///
+    /// Returns true when the given edge is hidden.
+    bool hidden(const Edge& edge) const {
+      return (*edges)[edge].prevOut == edge;
+    }
+
+    /// \brief Hide the given edge in the sub-graph.
+    ///
+    /// Hide the given edge in the sub graph. It just lace out from
+    /// the linked lists the given edge.
+    void hide(const Edge& edge) {
+      if (hidden(edge)) return;
+      if ((*edges)[edge].prevOut == edge) return;
+      if ((*edges)[edge].prevOut != INVALID) {
+	(*edges)[(*edges)[edge].prevOut].nextOut = (*edges)[edge].nextOut;
+      } else {
+	(*nodes)[source(edge)].firstOut = (*edges)[edge].nextOut;
+      }
+      if ((*edges)[edge].nextOut != INVALID) {
+	(*edges)[(*edges)[edge].nextOut].prevOut = (*edges)[edge].prevOut;
+      }
+
+      if ((*edges)[edge].prevIn != INVALID) {
+	(*edges)[(*edges)[edge].prevIn].nextIn = (*edges)[edge].nextIn;
+      } else {
+	(*nodes)[target(edge)].firstIn = (*edges)[edge].nextIn;
+      }
+      if ((*edges)[edge].nextIn != INVALID) {
+	(*edges)[(*edges)[edge].nextIn].prevIn = (*edges)[edge].prevIn;
+      }
+      (*edges)[edge].next = edge;
+    }
+
+    /// \brief Unhide the given edge in the sub-graph.
+    ///
+    /// Unhide the given edge in the sub graph. It just lace in the given
+    /// edge into the linked lists. If the source or the target of the
+    /// node is hidden then it will unhide it.
+    void unHide(const Edge& edge) {
+      if (!hidden(edge)) return;
+
+      Node node;
+
+      node = Parent::source(edge);
+      unHide(node);
+      (*edges)[edge].nextOut = (*nodes)[node].firstOut;
+      (*edges)[edge].prevOut = INVALID;
+      if ((*edges)[edge].nextOut != INVALID) {
+	(*edges)[(*edges)[edge].nextOut].prevOut = edge;
+      }
+      (*nodes)[node].firstOut = edge;
+
+      node = Parent::target(edge);
+      unHide(node);
+      (*edges)[edge].nextIn = (*nodes)[node].firstIn;
+      (*edges)[edge].prevIn = INVALID;
+      if ((*edges)[edge].nextIn != INVALID) {
+	(*edges)[(*edges)[edge].nextIn].prevIn = edge;
+      }
+      (*nodes)[node].firstIn = edge;      
+    }
+    
+    typedef False NodeNumTag;
+    typedef False EdgeNumTag;
+
+  protected:
+    struct NodeT {
+      Node prev, next;
+      Edge firstIn, firstOut;
+    };
+    class NodesImpl : public Graph::template NodeMap<NodeT> {
+      friend class SubGraphBase;
+    public:
+      typedef typename Graph::template NodeMap<NodeT> Parent;
+
+      NodesImpl(SubGraph& _adaptor, const Graph& _graph) 
+	: Parent(_graph), adaptor(_adaptor) {}
+
+      virtual ~NodesImpl() {}
+
+      virtual void build() {
+	Parent::build();
+	Node node;
+	adaptor.Base::first(node);
+	while (node != INVALID) {
+	  Parent::operator[](node).prev = node;
+	  Parent::operator[](node).firstIn = INVALID;
+	  Parent::operator[](node).firstOut = INVALID;
+	  adaptor.Base::next(node);
+	}
+      }
+
+      virtual void clear() {
+	adaptor.firstNode = INVALID;
+	Parent::clear();
+      }
+
+      virtual void add(const Node& node) {
+	Parent::add(node);
+	Parent::operator[](node).prev = node;
+	Parent::operator[](node).firstIn = INVALID;
+	Parent::operator[](node).firstOut = INVALID;
+      }
+      virtual void add(const std::vector<Node>& nodes) {
+	Parent::add(nodes);
+	for (int i = 0; i < (int)nodes.size(); ++i) {
+	  Parent::operator[](nodes[i]).prev = nodes[i];
+	  Parent::operator[](nodes[i]).firstIn = INVALID;
+	  Parent::operator[](nodes[i]).firstOut = INVALID;
+	}
+      } 
+
+      virtual void erase(const Node& node) {
+	adaptor.hide(node);
+	Parent::erase(node);
+      }
+
+      virtual void erase(const std::vector<Node>& nodes) {
+	for (int i = 0; i < (int)nodes.size(); ++i) {
+	  adaptor.hide(nodes[i]);
+	}
+	Parent::erase(nodes);
+      }
+
+    private:
+      SubGraph& adaptor;
+    };
+
+    struct EdgeT {
+      Edge prevOut, nextOut;
+      Edge prevIn, nextIn;
+    };
+    class EdgesImpl : public Graph::template EdgeMap<EdgeT> {
+      friend class SubGraphBase;
+    public:
+      typedef typename Graph::template EdgeMap<EdgeT> Parent;
+
+      EdgesImpl(SubGraph& _adaptor, const Graph& _graph) 
+	: Parent(_graph), adaptor(_adaptor) {}
+
+      virtual ~EdgesImpl() {}
+
+      virtual void build() {
+	Parent::build();
+	Edge edge;
+	adaptor.Base::first(edge);
+	while (edge != INVALID) {
+	  Parent::operator[](edge).prevOut = edge;
+	  adaptor.Base::next(edge);
+	}
+      }
+
+      virtual void clear() {
+	Node node;
+	adaptor.first(node);
+	while (node != INVALID) {
+	  (*adaptor.nodes).firstIn = INVALID;
+	  (*adaptor.nodes).firstOut = INVALID;
+	  adaptor.next(node);
+	}
+	Parent::clear();
+      }
+
+      virtual void add(const Edge& edge) {
+	Parent::add(edge);
+	Parent::operator[](edge).prevOut = edge;
+      }
+
+      virtual void add(const std::vector<Edge>& edges) {
+	Parent::add(edges);
+	for (int i = 0; i < (int)edges.size(); ++i) {
+	  Parent::operator[](edges[i]).prevOut = edges[i];
+	}
+      }
+
+      virtual void erase(const Edge& edge) {
+	adaptor.hide(edge);
+	Parent::erase(edge);
+      }
+
+      virtual void erase(const std::vector<Edge>& edges) {
+	for (int i = 0; i < (int)edges.size(); ++i) {
+	  adaptor.hide(edges[i]);
+	}
+	Parent::erase(edge);
+      }
+
+    private:
+      SubGraph& adaptor;
+    };
+
+    NodesImpl* nodes;
+    EdgesImpl* edges;
+    Node firstNode;
+  };
+
+  /// \ingroup semi_adaptors
+  ///
+  /// \brief Graph which uses a subset of an other graph's nodes and edges.
+  ///
+  /// Graph which uses a subset of an other graph's nodes and edges. This class
+  /// is an alternative to the SubGraphAdaptor which is created for the
+  /// same reason. The main difference between the two class that it
+  /// makes linked lists on the unhidden nodes and edges what cause that
+  /// on sparse subgraphs the algorithms can be more efficient and some times
+  /// provide better time complexity. On other way this implemetation is
+  /// less efficient in most case when the subgraph filters out only
+  /// a few nodes or edges.
+  /// 
+  /// \see SubGraphAdaptor
+  /// \see EdgeSubGraphBase
+  template <typename Graph>
+  class SubGraph 
+    : public IterableGraphExtender< SubGraphBase<Graph> > {
+  public:
+    typedef IterableGraphExtender< SubGraphBase<Graph> > Parent;
+  public:
+    /// \brief Constructor for sub-graph.
+    ///
+    /// Constructor for sub-graph. Initially all the edges and nodes
+    /// are hidden in the graph.
+    SubGraph(const Graph& _graph) 
+      : Parent(), nodes(*this, _graph), edges(*this, _graph) { 
+      Parent::construct(_graph, nodes, edges);
+    }
+  private:
+    typename Parent::NodesImpl nodes;
+    typename Parent::EdgesImpl edges;
+  };
+
+  /// \brief Base for the EdgeSubGraph.
+  ///
+  /// Base for the EdgeSubGraph.
+  template <typename _Graph>
+  class EdgeSubGraphBase : public GraphAdaptorBase<const _Graph> {
+  public:
+    typedef _Graph Graph;
+    typedef EdgeSubGraphBase<_Graph> SubGraph;
+    typedef GraphAdaptorBase<const _Graph> Parent;
+    typedef Parent Base;
+
+    typedef typename Parent::Node Node;
+    typedef typename Parent::Edge Edge;
+
+
+  protected:
+
+    class NodesImpl;
+    class EdgesImpl;
+
+    EdgeSubGraphBase() {}
+
+    void construct(const Graph& _graph, NodesImpl& _nodes, EdgesImpl& _edges) {
+      Parent::setGraph(_graph);
+      nodes = &_nodes;
+      edges = &_edges;
+
+      Node node;
+      Parent::first(node);
+      while (node != INVALID) {
+	(*nodes)[node].firstIn = INVALID;
+	(*nodes)[node].firstOut = INVALID;
+	Parent::next(node);
+      }
+
+      Edge edge;
+      Parent::first(edge);
+      while (edge != INVALID) {
+	(*edges)[edge].prevOut = edge;
+	Parent::next(edge);
+      }
+    }
+
+  public:
+
+    void first(Node& node) const {
+      Parent::first(node);
+    }
+    void next(Node& node) const {
+      Parent::next(node);
+    }
+
+    void first(Edge& edge) const {
+      Node node;
+      Parent::first(node);
+      while (node != INVALID && (*nodes)[node].firstOut == INVALID) {
+	Parent::next(node);
+      }
+      if (node == INVALID) {
+	edge = INVALID;
+      } else {
+	edge = (*nodes)[node].firstOut;
+      }
+    }
+    void next(Edge& edge) const {
+      if ((*edges)[edge].nextOut != INVALID) {
+	edge = (*edges)[edge].nextOut;
+      } else {
+	Node node = source(edge);
+	Parent::next(node);
+	while (node != INVALID && (*nodes)[node].firstOut == INVALID) {
+	  Parent::next(node);
+	}
+	if (node == INVALID) {
+	  edge = INVALID;
+	} else {
+	  edge = (*nodes)[node].firstOut;
+	}
+      }
+    }
+
+    void firstOut(Edge& edge, const Node& node) const {
+      edge = (*nodes)[node].firstOut;
+    }
+    void nextOut(Edge& edge) const {
+      edge = (*edges)[edge].nextOut;
+    }
+
+    void firstIn(Edge& edge, const Node& node) const {
+      edge = (*nodes)[node].firstIn;
+    }
+    void nextIn(Edge& edge) const {
+      edge = (*edges)[edge].nextIn;
+    }
+
+    /// \brief Returns true when the given edge is hidden.
+    ///
+    /// Returns true when the given edge is hidden.
+    bool hidden(const Edge& edge) const {
+      return (*edges)[edge].prevOut == edge;
+    }
+
+    /// \brief Hide the given edge in the sub-graph.
+    ///
+    /// Hide the given edge in the sub graph. It just lace out from
+    /// the linked lists the given edge.
+    void hide(const Edge& edge) {
+      if (hidden(edge)) return;
+      if ((*edges)[edge].prevOut != INVALID) {
+	(*edges)[(*edges)[edge].prevOut].nextOut = (*edges)[edge].nextOut;
+      } else {
+	(*nodes)[source(edge)].firstOut = (*edges)[edge].nextOut;
+      }
+      if ((*edges)[edge].nextOut != INVALID) {
+	(*edges)[(*edges)[edge].nextOut].prevOut = (*edges)[edge].prevOut;
+      }
+
+      if ((*edges)[edge].prevIn != INVALID) {
+	(*edges)[(*edges)[edge].prevIn].nextIn = (*edges)[edge].nextIn;
+      } else {
+	(*nodes)[target(edge)].firstIn = (*edges)[edge].nextIn;
+      }
+      if ((*edges)[edge].nextIn != INVALID) {
+	(*edges)[(*edges)[edge].nextIn].prevIn = (*edges)[edge].prevIn;
+      }
+      (*edges)[edge].prevOut = edge;
+    }
+
+    /// \brief Unhide the given edge in the sub-graph.
+    ///
+    /// Unhide the given edge in the sub graph. It just lace in the given
+    /// edge into the linked lists.
+    void unHide(const Edge& edge) {
+      if (!hidden(edge)) return;
+      Node node;
+
+      node = Parent::source(edge);
+      (*edges)[edge].nextOut = (*nodes)[node].firstOut;
+      (*edges)[edge].prevOut = INVALID;
+      if ((*edges)[edge].nextOut != INVALID) {
+	(*edges)[(*edges)[edge].nextOut].prevOut = edge;
+      }
+      (*nodes)[node].firstOut = edge;
+
+      node = Parent::target(edge);
+      (*edges)[edge].nextIn = (*nodes)[node].firstIn;
+      (*edges)[edge].prevIn = INVALID;
+      if ((*edges)[edge].nextIn != INVALID) {
+	(*edges)[(*edges)[edge].nextIn].prevIn = edge;
+      }
+      (*nodes)[node].firstIn = edge;      
+    }
+    
+  protected:
+    struct NodeT {
+      Edge firstIn, firstOut;
+    };
+    class NodesImpl : public Graph::template NodeMap<NodeT> {
+      friend class EdgeSubGraphBase;
+    public:
+      typedef typename Graph::template NodeMap<NodeT> Parent;
+
+      NodesImpl(SubGraph& _adaptor, const Graph& _graph) 
+	: Parent(_graph), adaptor(_adaptor) {}
+
+      virtual ~NodesImpl() {}
+
+      virtual void build() {
+	Parent::build();
+	Node node;
+	adaptor.Base::first(node);
+	while (node != INVALID) {
+	  Parent::operator[](node).firstIn = INVALID;
+	  Parent::operator[](node).firstOut = INVALID;
+	  adaptor.Base::next(node);
+	}
+      }
+
+      virtual void add(const Node& node) {
+	Parent::add(node);
+	Parent::operator[](node).firstIn = INVALID;
+	Parent::operator[](node).firstOut = INVALID;
+      }
+
+    private:
+      SubGraph& adaptor;
+    };
+
+    struct EdgeT {
+      Edge prevOut, nextOut;
+      Edge prevIn, nextIn;
+    };
+    class EdgesImpl : public Graph::template EdgeMap<EdgeT> {
+      friend class EdgeSubGraphBase;
+    public:
+      typedef typename Graph::template EdgeMap<EdgeT> Parent;
+
+      EdgesImpl(SubGraph& _adaptor, const Graph& _graph) 
+	: Parent(_graph), adaptor(_adaptor) {}
+
+      virtual ~EdgesImpl() {}
+
+      virtual void build() {
+	Parent::build();
+	Edge edge;
+	adaptor.Base::first(edge);
+	while (edge != INVALID) {
+	  Parent::operator[](edge).prevOut = edge;
+	  adaptor.Base::next(edge);
+	}
+      }
+
+      virtual void clear() {
+	Node node;
+	adaptor.Base::first(node);
+	while (node != INVALID) {
+	  (*adaptor.nodes)[node].firstIn = INVALID;
+	  (*adaptor.nodes)[node].firstOut = INVALID;
+	  adaptor.Base::next(node);
+	}
+	Parent::clear();
+      }
+
+      virtual void add(const Edge& edge) {
+	Parent::add(edge);
+	Parent::operator[](edge).prevOut = edge;
+      }
+
+      virtual void add(const std::vector<Edge>& edges) {
+	Parent::add(edges);
+	for (int i = 0; i < (int)edges.size(); ++i) {
+	  Parent::operator[](edges[i]).prevOut = edges[i];
+	}
+      }
+
+      virtual void erase(const Edge& edge) {
+	adaptor.hide(edge);
+	Parent::erase(edge);
+      }
+
+      virtual void erase(const std::vector<Edge>& edges) {
+	for (int i = 0; i < (int)edges.size(); ++i) {
+	  adaptor.hide(edges[i]);
+	}
+	Parent::erase(edge);
+      }
+
+    private:
+      SubGraph& adaptor;
+    };
+
+    NodesImpl* nodes;
+    EdgesImpl* edges;
+  };
+
+  /// \ingroup semi_adaptors
+  ///
+  /// \brief Graph which uses a subset of an other graph's edges.
+  ///
+  /// Graph which uses a subset of an other graph's edges. This class
+  /// is an alternative to the EdgeSubGraphAdaptor which is created for the
+  /// same reason. The main difference between the two class that it
+  /// makes linked lists on the unhidden edges what cause that
+  /// on sparse subgraphs the algorithms can be more efficient and some times
+  /// provide better time complexity. On other way this implemetation is
+  /// less efficient in most case when the subgraph filters out only
+  /// a few edges.
+  /// 
+  /// \see EdgeSubGraphAdaptor
+  /// \see EdgeSubGraphBase
+  template <typename Graph>
+  class EdgeSubGraph 
+    : public IterableGraphExtender< EdgeSubGraphBase<Graph> > {
+  public:
+    typedef IterableGraphExtender< EdgeSubGraphBase<Graph> > Parent;
+  public:
+    /// \brief Constructor for sub-graph.
+    ///
+    /// Constructor for sub-graph. Initially all the edges are hidden in the 
+    /// graph.
+    EdgeSubGraph(const Graph& _graph) 
+      : Parent(), nodes(*this, _graph), edges(*this, _graph) { 
+      Parent::construct(_graph, nodes, edges);
+    }
+  private:
+    typename Parent::NodesImpl nodes;
+    typename Parent::EdgesImpl edges;
+  };
+
+
+//   template<typename Graph, typename Number, 
+// 	   typename CapacityMap, typename FlowMap>
+//   class ResGraph
+//     : public IterableGraphExtender<EdgeSubGraphBase<
+//     UndirGraphAdaptor<Graph> > > {
+//   public:
+//     typedef IterableGraphExtender<EdgeSubGraphBase<
+//       UndirGraphAdaptor<Graph> > > Parent;
+
+//   protected:
+//     UndirGraphAdaptor<Graph> undir;
+
+//     const CapacityMap* capacity;
+//     FlowMap* flow;
+
+//     typename Parent::NodesImpl nodes;
+//     typename Parent::EdgesImpl edges;
+
+//     void setCapacityMap(const CapacityMap& _capacity) {
+//       capacity=&_capacity;
+//     }
+
+//     void setFlowMap(FlowMap& _flow) {
+//       flow=&_flow;
+//     }
+
+//   public:
+
+//     typedef typename UndirGraphAdaptor<Graph>::Node Node;
+//     typedef typename UndirGraphAdaptor<Graph>::Edge Edge;
+//     typedef typename UndirGraphAdaptor<Graph>::UndirEdge UndirEdge;
+
+//     ResGraphAdaptor(Graph& _graph, 
+// 		    const CapacityMap& _capacity, FlowMap& _flow) 
+//       : Parent(), undir(_graph), capacity(&_capacity), flow(&_flow),
+// 	nodes(*this, _graph), edges(*this, _graph) {
+//       Parent::construct(undir, nodes, edges);
+//       setFlowMap(_flow);
+//       setCapacityMap(_capacity);
+//       typename Graph::Edge edge; 
+//       for (_graph.first(edge); edge != INVALID; _graph.next(edge)) {
+// 	if ((*flow)[edge] != (*capacity)[edge]) {
+// 	  Parent::unHide(direct(edge, true));
+// 	}
+// 	if ((*flow)[edge] != 0) {
+// 	  Parent::unHide(direct(edge, false));
+// 	}
+//       }
+//     }
+
+//     void augment(const Edge& e, Number a) {
+//       if (direction(e)) {
+// 	flow->set(e, (*flow)[e]+a);
+//       } else { 
+// 	flow->set(e, (*flow)[e]-a);
+//       }
+//       if ((*flow)[e] == (*capacity)[e]) {
+// 	Parent::hide(e);
+//       } else {
+// 	Parent::unHide(e);
+//       }
+//       if ((*flow)[e] == 0) {
+// 	Parent::hide(oppositeEdge(e));
+//       } else {
+// 	Parent::unHide(oppositeEdge(e));
+//       }
+//     }
+
+//     Number resCap(const Edge& e) {
+//       if (direction(e)) { 
+// 	return (*capacity)[e]-(*flow)[e]; 
+//       } else { 
+// 	return (*flow)[e];
+//       }
+//     }
+    
+//     bool direction(const Edge& edge) const {
+//       return Parent::getGraph().direction(edge);
+//     }
+
+//     Edge direct(const UndirEdge& edge, bool direction) const {
+//       return Parent::getGraph().direct(edge, direction);
+//     }
+
+//     Edge direct(const UndirEdge& edge, const Node& node) const {
+//       return Parent::getGraph().direct(edge, node);
+//     }
+
+//     Edge oppositeEdge(const Edge& edge) const {
+//       return Parent::getGraph().oppositeEdge(edge);
+//     }
+
+//     /// \brief Residual capacity map.
+//     ///
+//     /// In generic residual graphs the residual capacity can be obtained 
+//     /// as a map. 
+//     class ResCap {
+//     protected:
+//       const ResGraphAdaptor* res_graph;
+//     public:
+//       typedef Number Value;
+//       typedef Edge Key;
+//       ResCap(const ResGraphAdaptor& _res_graph) 
+// 	: res_graph(&_res_graph) {}
+//       Number operator[](const Edge& e) const {
+// 	return res_graph->resCap(e);
+//       }
+//     };
+//   };
+
+}
+
+#endif



More information about the Lemon-commits mailing list