lemon/edge_set.h
author deba
Mon, 27 Feb 2006 10:17:33 +0000
changeset 1985 8782ff6fd98a
parent 1962 c1c3a0fae8a1
child 1990 15fb7a4ea6be
permissions -rw-r--r--
Bug fix
     1 /* -*- C++ -*-
     2  *
     3  * This file is a part of LEMON, a generic C++ optimization library
     4  *
     5  * Copyright (C) 2003-2006
     6  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
     7  * (Egervary Research Group on Combinatorial Optimization, EGRES).
     8  *
     9  * Permission to use, modify and distribute this software is granted
    10  * provided that this copyright notice appears in all copies. For
    11  * precise terms see the accompanying LICENSE file.
    12  *
    13  * This software is provided "AS IS" with no warranty of any kind,
    14  * express or implied, and with no claim as to its suitability for any
    15  * purpose.
    16  *
    17  */
    18 
    19 #ifndef LEMON_EDGE_SET_H
    20 #define LEMON_EDGE_SET_H
    21 
    22 
    23 #include <lemon/bits/edge_set_extender.h>
    24 
    25 /// \ingroup graphs
    26 /// \file
    27 /// \brief EdgeSet classes.
    28 ///
    29 /// Graphs which use another graph's node-set as own. 
    30 
    31 namespace lemon {
    32 
    33   template <typename _Graph>
    34   class ListEdgeSetBase {
    35   public:
    36 
    37     typedef _Graph Graph;
    38     typedef typename Graph::Node Node;
    39     typedef typename Graph::NodeIt NodeIt;
    40 
    41   protected:
    42 
    43     struct NodeT {
    44       int first_out, first_in;
    45       NodeT() : first_out(-1), first_in(-1) {}
    46     };
    47 
    48     typedef typename Graph::template NodeMap<NodeT> NodesImplBase;
    49 
    50     NodesImplBase* nodes;
    51 
    52     struct EdgeT {
    53       Node source, target;
    54       int next_out, next_in;
    55       int prev_out, prev_in;
    56       EdgeT() : prev_out(-1), prev_in(-1) {}
    57     };
    58 
    59     std::vector<EdgeT> edges;
    60 
    61     int first_edge;
    62     int first_free_edge;
    63 
    64     const Graph* graph;
    65 
    66     void initalize(const Graph& _graph, NodesImplBase& _nodes) {
    67       graph = &_graph;
    68       nodes = &_nodes;
    69     }
    70     
    71   public:
    72 
    73     class Edge {
    74       friend class ListEdgeSetBase<Graph>;
    75     protected:
    76       Edge(int _id) : id(_id) {}
    77       int id;
    78     public:
    79       Edge() {}
    80       Edge(Invalid) : id(-1) {}
    81       bool operator==(const Edge& edge) const { return id == edge.id; }
    82       bool operator!=(const Edge& edge) const { return id != edge.id; }
    83       bool operator<(const Edge& edge) const { return id < edge.id; }
    84     };
    85 
    86     ListEdgeSetBase() : first_edge(-1), first_free_edge(-1) {} 
    87 
    88     Edge addEdge(const Node& source, const Node& target) {
    89       int n;
    90       if (first_free_edge == -1) {
    91 	n = edges.size();
    92 	edges.push_back(EdgeT());
    93       } else {
    94 	n = first_free_edge;
    95 	first_free_edge = edges[first_free_edge].next_in;
    96       }
    97       edges[n].next_in = (*nodes)[target].first_in;
    98       if ((*nodes)[target].first_in != -1) {
    99         edges[(*nodes)[target].first_in].prev_in = n;
   100       }
   101       (*nodes)[target].first_in = n;
   102       edges[n].next_out = (*nodes)[source].first_out;
   103       if ((*nodes)[source].first_out != -1) {
   104         edges[(*nodes)[source].first_out].prev_out = n;
   105       }
   106       (*nodes)[source].first_out = n;
   107       edges[n].source = source;
   108       edges[n].target = target;
   109       return Edge(n);
   110     }
   111 
   112     void erase(const Edge& edge) {
   113       int n = edge.id;
   114       if (edges[n].prev_in != -1) {
   115 	edges[edges[n].prev_in].next_in = edges[n].next_in;
   116       } else {
   117 	(*nodes)[edges[n].target].first_in = edges[n].next_in;
   118       }
   119       if (edges[n].next_in != -1) {
   120 	edges[edges[n].next_in].prev_in = edges[n].prev_in;
   121       }
   122 
   123       if (edges[n].prev_out != -1) {
   124 	edges[edges[n].prev_out].next_out = edges[n].next_out;
   125       } else {
   126 	(*nodes)[edges[n].source].first_out = edges[n].next_out;
   127       }
   128       if (edges[n].next_out != -1) {
   129 	edges[edges[n].next_out].prev_out = edges[n].prev_out;
   130       }
   131            
   132     }
   133 
   134     void clear() {
   135       Node node;
   136       for (first(node); node != INVALID; next(node)) {
   137         (*nodes)[node].first_in = -1;
   138         (*nodes)[node].first_out = -1;
   139       }
   140       edges.clear();
   141       first_edge = -1;
   142       first_free_edge = -1;
   143     }
   144 
   145     void first(Node& node) const {
   146       graph->first(node);
   147     }
   148 
   149     void next(Node& node) const {
   150       graph->next(node);
   151     }
   152 
   153     void first(Edge& edge) const {
   154       Node node;
   155       for (first(node); node != INVALID && (*nodes)[node].first_in == -1; 
   156 	   next(node));
   157       edge.id = (node == INVALID) ? -1 : (*nodes)[node].first_in;
   158     }
   159 
   160     void next(Edge& edge) const {
   161       if (edges[edge.id].next_in != -1) {
   162 	edge.id = edges[edge.id].next_in;
   163       } else {
   164 	Node node = edges[edge.id].target;
   165 	for (next(node); node != INVALID && (*nodes)[node].first_in == -1; 
   166 	     next(node));
   167 	edge.id = (node == INVALID) ? -1 : (*nodes)[node].first_in;
   168       }      
   169     }
   170 
   171     void firstOut(Edge& edge, const Node& node) const {
   172       edge.id = (*nodes)[node].first_out;    
   173     }
   174     
   175     void nextOut(Edge& edge) const {
   176       edge.id = edges[edge.id].next_out;        
   177     }
   178 
   179     void firstIn(Edge& edge, const Node& node) const {
   180       edge.id = (*nodes)[node].first_in;          
   181     }
   182 
   183     void nextIn(Edge& edge) const {
   184       edge.id = edges[edge.id].next_in;    
   185     }
   186 
   187     int id(const Node& node) const { return graph->id(node); }
   188     int id(const Edge& edge) const { return edge.id; }
   189 
   190     Node nodeFromId(int id) const { return graph->nodeFromId(id); }
   191     Edge edgeFromId(int id) const { return Edge(id); }
   192 
   193     int maxNodeId() const { return graph->maxNodeId(); };
   194     int maxEdgeId() const { return edges.size() - 1; }
   195 
   196     Node source(const Edge& edge) const { return edges[edge.id].source;}
   197     Node target(const Edge& edge) const { return edges[edge.id].target;}
   198 
   199     template <typename _Value>
   200     class NodeMap : public Graph::template NodeMap<_Value> {
   201     public:
   202       typedef typename _Graph::template NodeMap<_Value> Parent;
   203       explicit NodeMap(const ListEdgeSetBase<Graph>& edgeset) 
   204 	: Parent(*edgeset.graph) { }
   205       NodeMap(const ListEdgeSetBase<Graph>& edgeset, const _Value& value)
   206 	: Parent(*edgeset.graph, value) { }
   207     };
   208 
   209   };
   210 
   211   /// \ingroup semi_adaptors
   212   ///
   213   /// \brief Graph using a node set of another graph and an
   214   /// own edge set.
   215   ///
   216   /// This structure can be used to establish another graph over a node set
   217   /// of an existing one. The node iterator will go through the nodes of the
   218   /// original graph.
   219   ///
   220   /// \param _Graph The type of the graph which shares its node set with 
   221   /// this class. Its interface must conform to the \ref concept::StaticGraph
   222   /// "StaticGraph" concept.
   223   ///
   224   /// In the edge extension and removing it conforms to the 
   225   /// \ref concept::ErasableGraph "ErasableGraph" concept.
   226   template <typename _Graph>
   227   class ListEdgeSet : public EdgeSetExtender<ListEdgeSetBase<_Graph> > {
   228 
   229   public:
   230 
   231     typedef EdgeSetExtender<ListEdgeSetBase<_Graph> > Parent;
   232     
   233     typedef typename Parent::Node Node;
   234     typedef typename Parent::Edge Edge;
   235     
   236     typedef _Graph Graph;
   237 
   238 
   239     typedef typename Parent::NodesImplBase NodesImplBase;
   240 
   241     void eraseNode(const Node& node) {
   242       Edge edge;
   243       Parent::firstOut(edge, node);
   244       while (edge != INVALID ) {
   245 	erase(edge);
   246 	Parent::firstOut(edge, node);
   247       } 
   248 
   249       Parent::firstIn(edge, node);
   250       while (edge != INVALID ) {
   251 	erase(edge);
   252 	Parent::firstIn(edge, node);
   253       }
   254     }
   255     
   256     void clearNodes() {
   257       Parent::clear();
   258     }
   259 
   260     class NodesImpl : public NodesImplBase {
   261     public:
   262       typedef NodesImplBase Parent;
   263       
   264       NodesImpl(const Graph& graph, ListEdgeSet& edgeset) 
   265 	: Parent(graph), _edgeset(edgeset) {}
   266 
   267       virtual ~NodesImpl() {}
   268       
   269     protected:
   270 
   271       virtual void erase(const Node& node) {
   272 	_edgeset.eraseNode(node);
   273 	Parent::erase(node);
   274       }
   275       virtual void erase(const std::vector<Node>& nodes) {
   276         for (int i = 0; i < (int)nodes.size(); ++i) {
   277           _edgeset.eraseNode(nodes[i]);
   278         }
   279 	Parent::erase(nodes);
   280       }
   281       virtual void clear() {
   282 	_edgeset.clearNodes();
   283 	Parent::clear();
   284       }
   285 
   286     private:
   287       ListEdgeSet& _edgeset;
   288     };
   289 
   290     NodesImpl nodes;
   291     
   292   public:
   293 
   294     /// \brief Constructor of the adaptor.
   295     /// 
   296     /// Constructor of the adaptor.
   297     ListEdgeSet(const Graph& graph) : nodes(graph, *this) {
   298       Parent::initalize(graph, nodes);
   299     }
   300     
   301   };
   302 
   303   /// \ingroup semi_adaptors
   304   ///
   305   /// \brief Graph using a node set of another graph and an
   306   /// own uedge set.
   307   ///
   308   /// This structure can be used to establish another graph over a node set
   309   /// of an existing one. The node iterator will go through the nodes of the
   310   /// original graph.
   311   ///
   312   /// \param _Graph The type of the graph which shares its node set with 
   313   /// this class. Its interface must conform to the \ref concept::StaticGraph
   314   /// "StaticGraph" concept.
   315   ///
   316   /// In the edge extension and removing it conforms to the 
   317   /// \ref concept::ErasableUGraph "ErasableUGraph" concept.
   318   template <typename _Graph>
   319   class ListUEdgeSet 
   320     : public UEdgeSetExtender<UGraphBaseExtender<ListEdgeSetBase<_Graph> > > {
   321 
   322   public:
   323 
   324     typedef UEdgeSetExtender<UGraphBaseExtender<
   325       ListEdgeSetBase<_Graph> > > Parent;
   326     
   327     typedef typename Parent::Node Node;
   328     typedef typename Parent::Edge Edge;
   329     
   330     typedef _Graph Graph;
   331 
   332 
   333     typedef typename Parent::NodesImplBase NodesImplBase;
   334 
   335     void eraseNode(const Node& node) {
   336       Edge edge;
   337       Parent::firstOut(edge, node);
   338       while (edge != INVALID ) {
   339 	erase(edge);
   340 	Parent::firstOut(edge, node);
   341       } 
   342 
   343     }
   344     
   345     void clearNodes() {
   346       Parent::clear();
   347     }
   348 
   349     class NodesImpl : public NodesImplBase {
   350     public:
   351       typedef NodesImplBase Parent;
   352       
   353       NodesImpl(const Graph& graph, ListUEdgeSet& edgeset) 
   354 	: Parent(graph), _edgeset(edgeset) {}
   355 
   356       virtual ~NodesImpl() {}
   357       
   358     protected:
   359 
   360       virtual void erase(const Node& node) {
   361 	_edgeset.eraseNode(node);
   362 	Parent::erase(node);
   363       }
   364       virtual void erase(const std::vector<Node>& nodes) {
   365 	for (int i = 0; i < (int)nodes.size(); ++i) {
   366 	  _edgeset.eraseNode(nodes[i]);
   367 	}
   368 	Parent::erase(nodes);
   369       }
   370       virtual void clear() {
   371 	_edgeset.clearNodes();
   372 	Parent::clear();
   373       }
   374 
   375     private:
   376       ListUEdgeSet& _edgeset;
   377     };
   378 
   379     NodesImpl nodes;
   380     
   381   public:
   382 
   383     /// \brief Constructor of the adaptor.
   384     /// 
   385     /// Constructor of the adaptor.
   386     ListUEdgeSet(const Graph& graph) : nodes(graph, *this) {
   387       Parent::initalize(graph, nodes);
   388     }
   389     
   390   };
   391 
   392   template <typename _Graph>
   393   class SmartEdgeSetBase {
   394   public:
   395 
   396     typedef _Graph Graph;
   397     typedef typename Graph::Node Node;
   398     typedef typename Graph::NodeIt NodeIt;
   399 
   400   protected:
   401 
   402     struct NodeT {
   403       int first_out, first_in;
   404       NodeT() : first_out(-1), first_in(-1) {}
   405     };
   406 
   407     typedef typename Graph::template NodeMap<NodeT> NodesImplBase;
   408 
   409     NodesImplBase* nodes;
   410 
   411     struct EdgeT {
   412       Node source, target;
   413       int next_out, next_in;
   414       EdgeT() {}
   415     };
   416 
   417     std::vector<EdgeT> edges;
   418 
   419     const Graph* graph;
   420 
   421     void initalize(const Graph& _graph, NodesImplBase& _nodes) {
   422       graph = &_graph;
   423       nodes = &_nodes;
   424     }
   425     
   426   public:
   427 
   428     class Edge {
   429       friend class SmartEdgeSetBase<Graph>;
   430     protected:
   431       Edge(int _id) : id(_id) {}
   432       int id;
   433     public:
   434       Edge() {}
   435       Edge(Invalid) : id(-1) {}
   436       bool operator==(const Edge& edge) const { return id == edge.id; }
   437       bool operator!=(const Edge& edge) const { return id != edge.id; }
   438       bool operator<(const Edge& edge) const { return id < edge.id; }
   439     };
   440 
   441     SmartEdgeSetBase() {} 
   442 
   443     Edge addEdge(const Node& source, const Node& target) {
   444       int n = edges.size();
   445       edges.push_back(EdgeT());
   446       edges[n].next_in = (*nodes)[target].first_in;
   447       (*nodes)[target].first_in = n;
   448       edges[n].next_out = (*nodes)[source].first_out;
   449       (*nodes)[source].first_out = n;
   450       edges[n].source = source;
   451       edges[n].target = target;
   452       return Edge(n);
   453     }
   454 
   455     void clear() {
   456       Node node;
   457       for (first(node); node != INVALID; next(node)) {
   458         (*nodes)[node].first_in = -1;
   459         (*nodes)[node].first_out = -1;
   460       }
   461       edges.clear();
   462     }
   463 
   464     void first(Node& node) const {
   465       graph->first(node);
   466     }
   467 
   468     void next(Node& node) const {
   469       graph->next(node);
   470     }
   471 
   472     void first(Edge& edge) const {
   473       edge.id = edges.size() - 1;
   474     }
   475 
   476     void next(Edge& edge) const {
   477       --edge.id;
   478     }
   479 
   480     void firstOut(Edge& edge, const Node& node) const {
   481       edge.id = (*nodes)[node].first_out;    
   482     }
   483     
   484     void nextOut(Edge& edge) const {
   485       edge.id = edges[edge.id].next_out;        
   486     }
   487 
   488     void firstIn(Edge& edge, const Node& node) const {
   489       edge.id = (*nodes)[node].first_in;          
   490     }
   491 
   492     void nextIn(Edge& edge) const {
   493       edge.id = edges[edge.id].next_in;    
   494     }
   495 
   496     int id(const Node& node) const { return graph->id(node); }
   497     int id(const Edge& edge) const { return edge.id; }
   498 
   499     Node nodeFromId(int id) const { return graph->nodeFromId(id); }
   500     Edge edgeFromId(int id) const { return Edge(id); }
   501 
   502     int maxNodeId() const { return graph->maxNodeId(); };
   503     int maxEdgeId() const { return edges.size() - 1; }
   504 
   505     Node source(const Edge& edge) const { return edges[edge.id].source;}
   506     Node target(const Edge& edge) const { return edges[edge.id].target;}
   507 
   508     template <typename _Value>
   509     class NodeMap : public Graph::template NodeMap<_Value> {
   510     public:
   511       typedef typename _Graph::template NodeMap<_Value> Parent;
   512       explicit NodeMap(const SmartEdgeSetBase<Graph>& edgeset) 
   513 	: Parent(*edgeset.graph) { }
   514       NodeMap(const SmartEdgeSetBase<Graph>& edgeset, const _Value& value)
   515 	: Parent(*edgeset.graph, value) { }
   516     };
   517 
   518   };
   519 
   520 
   521   /// \ingroup semi_adaptors
   522   ///
   523   /// \brief Graph using a node set of another graph and an
   524   /// own edge set.
   525   ///
   526   /// This structure can be used to establish another graph over a node set
   527   /// of an existing one. The node iterator will go through the nodes of the
   528   /// original graph.
   529   ///
   530   /// \param _Graph The type of the graph which shares its node set with 
   531   /// this class. Its interface must conform to the \ref concept::StaticGraph
   532   /// "StaticGraph" concept.
   533   ///
   534   /// In the edge extension and removing it conforms to the 
   535   /// \ref concept::ExtendableGraph "ExtendableGraph" concept.
   536   template <typename _Graph>
   537   class SmartEdgeSet : public EdgeSetExtender<SmartEdgeSetBase<_Graph> > {
   538 
   539   public:
   540 
   541     typedef EdgeSetExtender<SmartEdgeSetBase<_Graph> > Parent;
   542     
   543     typedef typename Parent::Node Node;
   544     typedef typename Parent::Edge Edge;
   545     
   546     typedef _Graph Graph;
   547 
   548     class UnsupportedOperation : public LogicError {
   549     public:
   550       virtual const char* exceptionName() const {
   551         return "lemon::SmartEdgeSet::UnsupportedOperation";
   552       }
   553     };
   554     
   555 
   556 
   557   protected:
   558 
   559     typedef typename Parent::NodesImplBase NodesImplBase;
   560 
   561     void eraseNode(const Node&) {
   562       throw UnsupportedOperation();
   563     }
   564     
   565     void clearNodes() {
   566       Parent::clear();
   567     }
   568 
   569     class NodesImpl : public NodesImplBase {
   570     public:
   571       typedef NodesImplBase Parent;
   572       
   573       NodesImpl(const Graph& graph, SmartEdgeSet& edgeset) 
   574 	: Parent(graph), _edgeset(edgeset) {}
   575 
   576       virtual ~NodesImpl() {}
   577       
   578     protected:
   579 
   580       virtual void erase(const Node& node) {
   581 	_edgeset.eraseNode(node);
   582 	Parent::erase(node);
   583       }
   584       virtual void erase(const std::vector<Node>& nodes) {
   585         for (int i = 0; i < (int)nodes.size(); ++i) {
   586           _edgeset.eraseNode(nodes[i]);
   587         }
   588 	Parent::erase(nodes);
   589       }
   590       virtual void clear() {
   591 	_edgeset.clearNodes();
   592 	Parent::clear();
   593       }
   594 
   595     private:
   596       SmartEdgeSet& _edgeset;
   597     };
   598 
   599     NodesImpl nodes;
   600     
   601   public:
   602 
   603     /// \brief Constructor of the adaptor.
   604     /// 
   605     /// Constructor of the adaptor.
   606     SmartEdgeSet(const Graph& graph) : nodes(graph, *this) {
   607       Parent::initalize(graph, nodes);
   608     }
   609     
   610   };
   611 
   612   /// \ingroup semi_adaptors
   613   ///
   614   /// \brief Graph using a node set of another graph and an
   615   /// own uedge set.
   616   ///
   617   /// This structure can be used to establish another graph over a node set
   618   /// of an existing one. The node iterator will go through the nodes of the
   619   /// original graph.
   620   ///
   621   /// \param _Graph The type of the graph which shares its node set with 
   622   /// this class. Its interface must conform to the \ref concept::StaticGraph
   623   /// "StaticGraph" concept.
   624   ///
   625   /// In the edge extension and removing it conforms to the 
   626   /// \ref concept::ExtendableUGraph "ExtendableUGraph" concept.
   627   template <typename _Graph>
   628   class SmartUEdgeSet 
   629     : public UEdgeSetExtender<UGraphBaseExtender<SmartEdgeSetBase<_Graph> > > {
   630 
   631   public:
   632 
   633     typedef UEdgeSetExtender<UGraphBaseExtender<
   634       SmartEdgeSetBase<_Graph> > > Parent;
   635     
   636     typedef typename Parent::Node Node;
   637     typedef typename Parent::Edge Edge;
   638     
   639     typedef _Graph Graph;
   640 
   641     class UnsupportedOperation : public LogicError {
   642     public:
   643       virtual const char* exceptionName() const {
   644         return "lemon::SmartUEdgeSet::UnsupportedOperation";
   645       }
   646     };
   647 
   648   protected:
   649 
   650     typedef typename Parent::NodesImplBase NodesImplBase;
   651 
   652     void eraseNode(const Node&) {
   653       throw UnsupportedOperation();
   654     }
   655     
   656     void clearNodes() {
   657       Parent::clear();
   658     }
   659 
   660     class NodesImpl : public NodesImplBase {
   661     public:
   662       typedef NodesImplBase Parent;
   663       
   664       NodesImpl(const Graph& graph, SmartUEdgeSet& edgeset) 
   665 	: Parent(graph), _edgeset(edgeset) {}
   666 
   667       virtual ~NodesImpl() {}
   668       
   669     protected:
   670 
   671       virtual void erase(const Node& node) {
   672 	_edgeset.eraseNode(node);
   673 	Parent::erase(node);
   674       }
   675       virtual void erase(const std::vector<Node>& nodes) {
   676 	for (int i = 0; i < (int)nodes.size(); ++i) {
   677 	  _edgeset.eraseNode(nodes[i]);
   678 	}
   679 	Parent::erase(nodes);
   680       }
   681       virtual void clear() {
   682 	_edgeset.clearNodes();
   683 	Parent::clear();
   684       }
   685 
   686     private:
   687       SmartUEdgeSet& _edgeset;
   688     };
   689 
   690     NodesImpl nodes;
   691     
   692   public:
   693 
   694     /// \brief Constructor of the adaptor.
   695     /// 
   696     /// Constructor of the adaptor.
   697     SmartUEdgeSet(const Graph& graph) : nodes(graph, *this) {
   698       Parent::initalize(graph, nodes);
   699     }
   700     
   701   };
   702 
   703 }
   704 
   705 #endif