lemon/edge_set.h
changeset 1977 8ef02f0c4245
parent 1956 a055123339d5
child 1979 c2992fd74dad
equal deleted inserted replaced
4:84171ffce88e 5:9b2c097d5b50
    17  */
    17  */
    18 
    18 
    19 #ifndef LEMON_EDGE_SET_H
    19 #ifndef LEMON_EDGE_SET_H
    20 #define LEMON_EDGE_SET_H
    20 #define LEMON_EDGE_SET_H
    21 
    21 
       
    22 #include <lemon/bits/erasable_graph_extender.h>
       
    23 #include <lemon/bits/clearable_graph_extender.h>
       
    24 #include <lemon/bits/extendable_graph_extender.h>
       
    25 #include <lemon/bits/iterable_graph_extender.h>
       
    26 #include <lemon/bits/alteration_notifier.h>
       
    27 #include <lemon/bits/default_map.h>
       
    28 #include <lemon/bits/graph_extender.h>
       
    29 
    22 /// \ingroup graphs
    30 /// \ingroup graphs
    23 /// \file
    31 /// \file
    24 /// \brief EdgeSet classes.
    32 /// \brief EdgeSet classes.
    25 ///
    33 ///
    26 /// Graphs which use another graph's node-set as own. 
    34 /// Graphs which use another graph's node-set as own. 
    90       } else {
    98       } else {
    91 	n = first_free_edge;
    99 	n = first_free_edge;
    92 	first_free_edge = edges[first_free_edge].next_in;
   100 	first_free_edge = edges[first_free_edge].next_in;
    93       }
   101       }
    94       edges[n].next_in = (*nodes)[target].first_in;
   102       edges[n].next_in = (*nodes)[target].first_in;
       
   103       if ((*nodes)[target].first_in != -1) {
       
   104         edges[(*nodes)[target].first_in].prev_in = n;
       
   105       }
    95       (*nodes)[target].first_in = n;
   106       (*nodes)[target].first_in = n;
    96       edges[n].next_out = (*nodes)[source].first_out;
   107       edges[n].next_out = (*nodes)[source].first_out;
       
   108       if ((*nodes)[source].first_out != -1) {
       
   109         edges[(*nodes)[source].first_out].prev_out = n;
       
   110       }
    97       (*nodes)[source].first_out = n;
   111       (*nodes)[source].first_out = n;
    98       edges[n].source = source;
   112       edges[n].source = source;
    99       edges[n].target = target;
   113       edges[n].target = target;
   100       return Edge(n);
   114       return Edge(n);
   101     }
   115     }
   121       }
   135       }
   122            
   136            
   123     }
   137     }
   124 
   138 
   125     void clear() {
   139     void clear() {
       
   140       Node node;
       
   141       for (first(node); node != INVALID; next(node)) {
       
   142         (*nodes)[node].first_in = -1;
       
   143         (*nodes)[node].first_out = -1;
       
   144       }
   126       edges.clear();
   145       edges.clear();
   127       first_edge = -1;
   146       first_edge = -1;
   128       first_free_edge = -1;
   147       first_free_edge = -1;
   129     }
   148     }
   130 
   149 
   171     }
   190     }
   172 
   191 
   173     int id(const Node& node) const { return graph->id(node); }
   192     int id(const Node& node) const { return graph->id(node); }
   174     int id(const Edge& edge) const { return edge.id; }
   193     int id(const Edge& edge) const { return edge.id; }
   175 
   194 
   176     Node nodeFromId(int id) const { return graph->fromId(id, Node()); }
   195     Node nodeFromId(int id) const { return graph->nodeFromId(id); }
   177     Edge edgeFromId(int id) const { return Edge(id); }
   196     Edge edgeFromId(int id) const { return Edge(id); }
   178 
   197 
   179     int maxNodeId() const { return graph->maxId(Node()); };
   198     int maxNodeId() const { return graph->maxNodeId(); };
   180     int maxEdgeId() const { return edges.size() - 1; }
   199     int maxEdgeId() const { return edges.size() - 1; }
   181 
   200 
   182     Node source(const Edge& edge) const { return edges[edge.id].source;}
   201     Node source(const Edge& edge) const { return edges[edge.id].source;}
   183     Node target(const Edge& edge) const { return edges[edge.id].target;}
   202     Node target(const Edge& edge) const { return edges[edge.id].target;}
   184 
   203 
   206   /// \param _Graph The type of the graph which shares its node set with 
   225   /// \param _Graph The type of the graph which shares its node set with 
   207   /// this class. Its interface must conform to the \ref concept::StaticGraph
   226   /// this class. Its interface must conform to the \ref concept::StaticGraph
   208   /// "StaticGraph" concept.
   227   /// "StaticGraph" concept.
   209   ///
   228   ///
   210   /// In the edge extension and removing it conforms to the 
   229   /// In the edge extension and removing it conforms to the 
   211   /// \ref concept::ExtendableGraph "ExtendableGraph" concept.
   230   /// \ref concept::ErasableGraph "ErasableGraph" concept.
   212   template <typename _Graph>
   231   template <typename _Graph>
   213   class ListEdgeSet :
   232   class ListEdgeSet :
   214     public ErasableEdgeSetExtender<
   233     public ErasableEdgeSetExtender<
   215     ClearableEdgeSetExtender<
   234     ClearableEdgeSetExtender<
   216     ExtendableEdgeSetExtender<
   235     ExtendableEdgeSetExtender<
   262     public:
   281     public:
   263       typedef NodesImplBase Parent;
   282       typedef NodesImplBase Parent;
   264       
   283       
   265       NodesImpl(const Graph& graph, ListEdgeSet& edgeset) 
   284       NodesImpl(const Graph& graph, ListEdgeSet& edgeset) 
   266 	: Parent(graph), _edgeset(edgeset) {}
   285 	: Parent(graph), _edgeset(edgeset) {}
       
   286 
       
   287       virtual ~NodesImpl() {}
   267       
   288       
   268     protected:
   289     protected:
   269 
   290 
   270       virtual void erase(const Node& node) {
   291       virtual void erase(const Node& node) {
   271 	_edgeset.eraseNode(node);
   292 	_edgeset.eraseNode(node);
   272 	Parent::erase(node);
   293 	Parent::erase(node);
       
   294       }
       
   295       virtual void erase(const std::vector<Node>& nodes) {
       
   296         for (int i = 0; i < (int)nodes.size(); ++i) {
       
   297           _edgeset.eraseNode(nodes[i]);
       
   298         }
       
   299 	Parent::erase(nodes);
   273       }
   300       }
   274       virtual void clear() {
   301       virtual void clear() {
   275 	_edgeset.clearNodes();
   302 	_edgeset.clearNodes();
   276 	Parent::clear();
   303 	Parent::clear();
   277       }
   304       }
   305   /// \param _Graph The type of the graph which shares its node set with 
   332   /// \param _Graph The type of the graph which shares its node set with 
   306   /// this class. Its interface must conform to the \ref concept::StaticGraph
   333   /// this class. Its interface must conform to the \ref concept::StaticGraph
   307   /// "StaticGraph" concept.
   334   /// "StaticGraph" concept.
   308   ///
   335   ///
   309   /// In the edge extension and removing it conforms to the 
   336   /// In the edge extension and removing it conforms to the 
   310   /// \ref concept::ExtendableGraph "ExtendableGraph" concept.
   337   /// \ref concept::ErasableUGraph "ErasableUGraph" concept.
   311   template <typename _Graph>
   338   template <typename _Graph>
   312   class ListUEdgeSet :
   339   class ListUEdgeSet :
   313     public ErasableUEdgeSetExtender<
   340     public ErasableUEdgeSetExtender<
   314     ClearableUEdgeSetExtender<
   341     ClearableUEdgeSetExtender<
   315     ExtendableUEdgeSetExtender<
   342     ExtendableUEdgeSetExtender<
   356     public:
   383     public:
   357       typedef NodesImplBase Parent;
   384       typedef NodesImplBase Parent;
   358       
   385       
   359       NodesImpl(const Graph& graph, ListUEdgeSet& edgeset) 
   386       NodesImpl(const Graph& graph, ListUEdgeSet& edgeset) 
   360 	: Parent(graph), _edgeset(edgeset) {}
   387 	: Parent(graph), _edgeset(edgeset) {}
       
   388 
       
   389       virtual ~NodesImpl() {}
   361       
   390       
   362     protected:
   391     protected:
   363 
   392 
   364       virtual void erase(const Node& node) {
   393       virtual void erase(const Node& node) {
   365 	_edgeset.eraseNode(node);
   394 	_edgeset.eraseNode(node);
   366 	Parent::erase(node);
   395 	Parent::erase(node);
   367       }
   396       }
   368       virtual void erase(const std::vector<Node>& nodes) {
   397       virtual void erase(const std::vector<Node>& nodes) {
   369 	for (int i = 0; i < nodes.size(); ++i) {
   398 	for (int i = 0; i < (int)nodes.size(); ++i) {
   370 	  _edgeset.eraseNode(nodes[i]);
   399 	  _edgeset.eraseNode(nodes[i]);
   371 	}
   400 	}
   372 	Parent::erase(nodes);
   401 	Parent::erase(nodes);
   373       }
   402       }
   374       virtual void clear() {
   403       virtual void clear() {
   391       Parent::initalize(graph, nodes);
   420       Parent::initalize(graph, nodes);
   392     }
   421     }
   393     
   422     
   394   };
   423   };
   395 
   424 
       
   425   template <typename _Graph>
       
   426   class SmartEdgeSetBase {
       
   427   public:
       
   428 
       
   429     typedef _Graph Graph;
       
   430     typedef typename Graph::Node Node;
       
   431     typedef typename Graph::NodeIt NodeIt;
       
   432 
       
   433   protected:
       
   434 
       
   435     struct NodeT {
       
   436       int first_out, first_in;
       
   437       NodeT() : first_out(-1), first_in(-1) {}
       
   438     };
       
   439 
       
   440     typedef typename Graph::template NodeMap<NodeT> NodesImplBase;
       
   441 
       
   442     NodesImplBase* nodes;
       
   443 
       
   444     struct EdgeT {
       
   445       Node source, target;
       
   446       int next_out, next_in;
       
   447       EdgeT() {}
       
   448     };
       
   449 
       
   450     std::vector<EdgeT> edges;
       
   451 
       
   452     const Graph* graph;
       
   453 
       
   454     void initalize(const Graph& _graph, NodesImplBase& _nodes) {
       
   455       graph = &_graph;
       
   456       nodes = &_nodes;
       
   457     }
       
   458     
       
   459   public:
       
   460 
       
   461     class Edge {
       
   462       friend class SmartEdgeSetBase<Graph>;
       
   463     protected:
       
   464       Edge(int _id) : id(_id) {}
       
   465       int id;
       
   466     public:
       
   467       Edge() {}
       
   468       Edge(Invalid) : id(-1) {}
       
   469       bool operator==(const Edge& edge) const { return id == edge.id; }
       
   470       bool operator!=(const Edge& edge) const { return id != edge.id; }
       
   471       bool operator<(const Edge& edge) const { return id < edge.id; }
       
   472     };
       
   473 
       
   474     SmartEdgeSetBase() {} 
       
   475 
       
   476     Edge addEdge(const Node& source, const Node& target) {
       
   477       int n = edges.size();
       
   478       edges.push_back(EdgeT());
       
   479       edges[n].next_in = (*nodes)[target].first_in;
       
   480       (*nodes)[target].first_in = n;
       
   481       edges[n].next_out = (*nodes)[source].first_out;
       
   482       (*nodes)[source].first_out = n;
       
   483       edges[n].source = source;
       
   484       edges[n].target = target;
       
   485       return Edge(n);
       
   486     }
       
   487 
       
   488     void clear() {
       
   489       Node node;
       
   490       for (first(node); node != INVALID; next(node)) {
       
   491         (*nodes)[node].first_in = -1;
       
   492         (*nodes)[node].first_out = -1;
       
   493       }
       
   494       edges.clear();
       
   495     }
       
   496 
       
   497     void first(Node& node) const {
       
   498       graph->first(node);
       
   499     }
       
   500 
       
   501     void next(Node& node) const {
       
   502       graph->next(node);
       
   503     }
       
   504 
       
   505     void first(Edge& edge) const {
       
   506       edge.id = edges.size() - 1;
       
   507     }
       
   508 
       
   509     void next(Edge& edge) const {
       
   510       --edge.id;
       
   511     }
       
   512 
       
   513     void firstOut(Edge& edge, const Node& node) const {
       
   514       edge.id = (*nodes)[node].first_out;    
       
   515     }
       
   516     
       
   517     void nextOut(Edge& edge) const {
       
   518       edge.id = edges[edge.id].next_out;        
       
   519     }
       
   520 
       
   521     void firstIn(Edge& edge, const Node& node) const {
       
   522       edge.id = (*nodes)[node].first_in;          
       
   523     }
       
   524 
       
   525     void nextIn(Edge& edge) const {
       
   526       edge.id = edges[edge.id].next_in;    
       
   527     }
       
   528 
       
   529     int id(const Node& node) const { return graph->id(node); }
       
   530     int id(const Edge& edge) const { return edge.id; }
       
   531 
       
   532     Node nodeFromId(int id) const { return graph->nodeFromId(id); }
       
   533     Edge edgeFromId(int id) const { return Edge(id); }
       
   534 
       
   535     int maxNodeId() const { return graph->maxNodeId(); };
       
   536     int maxEdgeId() const { return edges.size() - 1; }
       
   537 
       
   538     Node source(const Edge& edge) const { return edges[edge.id].source;}
       
   539     Node target(const Edge& edge) const { return edges[edge.id].target;}
       
   540 
       
   541     template <typename _Value>
       
   542     class NodeMap : public Graph::template NodeMap<_Value> {
       
   543     public:
       
   544       typedef typename _Graph::template NodeMap<_Value> Parent;
       
   545       explicit NodeMap(const SmartEdgeSetBase<Graph>& edgeset) 
       
   546 	: Parent(*edgeset.graph) { }
       
   547       NodeMap(const SmartEdgeSetBase<Graph>& edgeset, const _Value& value)
       
   548 	: Parent(*edgeset.graph, value) { }
       
   549     };
       
   550 
       
   551   };
       
   552 
       
   553 
       
   554   /// \ingroup semi_adaptors
       
   555   ///
       
   556   /// \brief Graph using a node set of another graph and an
       
   557   /// own edge set.
       
   558   ///
       
   559   /// This structure can be used to establish another graph over a node set
       
   560   /// of an existing one. The node iterator will go through the nodes of the
       
   561   /// original graph.
       
   562   ///
       
   563   /// \param _Graph The type of the graph which shares its node set with 
       
   564   /// this class. Its interface must conform to the \ref concept::StaticGraph
       
   565   /// "StaticGraph" concept.
       
   566   ///
       
   567   /// In the edge extension and removing it conforms to the 
       
   568   /// \ref concept::ExtendableGraph "ExtendableGraph" concept.
       
   569   template <typename _Graph>
       
   570   class SmartEdgeSet :
       
   571     public ClearableEdgeSetExtender<
       
   572     ExtendableEdgeSetExtender<
       
   573     MappableEdgeSetExtender<
       
   574     IterableGraphExtender<
       
   575     AlterableEdgeSetExtender<
       
   576     GraphExtender<
       
   577     SmartEdgeSetBase<_Graph> > > > > > > {
       
   578 
       
   579   public:
       
   580 
       
   581     typedef ClearableEdgeSetExtender<
       
   582       ExtendableEdgeSetExtender<
       
   583       MappableEdgeSetExtender<
       
   584       IterableGraphExtender<
       
   585       AlterableEdgeSetExtender<
       
   586       GraphExtender<
       
   587       SmartEdgeSetBase<_Graph> > > > > > > Parent;
       
   588     
       
   589     typedef typename Parent::Node Node;
       
   590     typedef typename Parent::Edge Edge;
       
   591     
       
   592     typedef _Graph Graph;
       
   593 
       
   594     class UnsupportedOperation : public LogicError {
       
   595     public:
       
   596       virtual const char* exceptionName() const {
       
   597         return "lemon::SmartEdgeSet::UnsupportedOperation";
       
   598       }
       
   599     };
       
   600     
       
   601 
       
   602 
       
   603   protected:
       
   604 
       
   605     typedef typename Parent::NodesImplBase NodesImplBase;
       
   606 
       
   607     void eraseNode(const Node&) {
       
   608       throw UnsupportedOperation();
       
   609     }
       
   610     
       
   611     void clearNodes() {
       
   612       Parent::clear();
       
   613     }
       
   614 
       
   615     class NodesImpl : public NodesImplBase {
       
   616     public:
       
   617       typedef NodesImplBase Parent;
       
   618       
       
   619       NodesImpl(const Graph& graph, SmartEdgeSet& edgeset) 
       
   620 	: Parent(graph), _edgeset(edgeset) {}
       
   621 
       
   622       virtual ~NodesImpl() {}
       
   623       
       
   624     protected:
       
   625 
       
   626       virtual void erase(const Node& node) {
       
   627 	_edgeset.eraseNode(node);
       
   628 	Parent::erase(node);
       
   629       }
       
   630       virtual void erase(const std::vector<Node>& nodes) {
       
   631         for (int i = 0; i < (int)nodes.size(); ++i) {
       
   632           _edgeset.eraseNode(nodes[i]);
       
   633         }
       
   634 	Parent::erase(nodes);
       
   635       }
       
   636       virtual void clear() {
       
   637 	_edgeset.clearNodes();
       
   638 	Parent::clear();
       
   639       }
       
   640 
       
   641     private:
       
   642       SmartEdgeSet& _edgeset;
       
   643     };
       
   644 
       
   645     NodesImpl nodes;
       
   646     
       
   647   public:
       
   648 
       
   649     /// \brief Constructor of the adaptor.
       
   650     /// 
       
   651     /// Constructor of the adaptor.
       
   652     SmartEdgeSet(const Graph& graph) : nodes(graph, *this) {
       
   653       Parent::initalize(graph, nodes);
       
   654     }
       
   655     
       
   656   };
       
   657 
       
   658   /// \ingroup semi_adaptors
       
   659   ///
       
   660   /// \brief Graph using a node set of another graph and an
       
   661   /// own uedge set.
       
   662   ///
       
   663   /// This structure can be used to establish another graph over a node set
       
   664   /// of an existing one. The node iterator will go through the nodes of the
       
   665   /// original graph.
       
   666   ///
       
   667   /// \param _Graph The type of the graph which shares its node set with 
       
   668   /// this class. Its interface must conform to the \ref concept::StaticGraph
       
   669   /// "StaticGraph" concept.
       
   670   ///
       
   671   /// In the edge extension and removing it conforms to the 
       
   672   /// \ref concept::ExtendableUGraph "ExtendableUGraph" concept.
       
   673   template <typename _Graph>
       
   674   class SmartUEdgeSet :
       
   675     public ClearableUEdgeSetExtender<
       
   676     ExtendableUEdgeSetExtender<
       
   677     MappableUEdgeSetExtender<
       
   678     IterableUGraphExtender<
       
   679     AlterableUEdgeSetExtender<
       
   680     UGraphExtender<
       
   681     SmartEdgeSetBase<_Graph> > > > > > > {
       
   682 
       
   683   public:
       
   684 
       
   685     typedef ClearableUEdgeSetExtender<
       
   686       ExtendableUEdgeSetExtender<
       
   687       MappableUEdgeSetExtender<
       
   688       IterableUGraphExtender<
       
   689       AlterableUEdgeSetExtender<
       
   690       UGraphExtender<
       
   691       SmartEdgeSetBase<_Graph> > > > > > > Parent;
       
   692     
       
   693     typedef typename Parent::Node Node;
       
   694     typedef typename Parent::Edge Edge;
       
   695     
       
   696     typedef _Graph Graph;
       
   697 
       
   698     class UnsupportedOperation : public LogicError {
       
   699     public:
       
   700       virtual const char* exceptionName() const {
       
   701         return "lemon::SmartUEdgeSet::UnsupportedOperation";
       
   702       }
       
   703     };
       
   704 
       
   705   protected:
       
   706 
       
   707     typedef typename Parent::NodesImplBase NodesImplBase;
       
   708 
       
   709     void eraseNode(const Node&) {
       
   710       throw UnsupportedOperation();
       
   711     }
       
   712     
       
   713     void clearNodes() {
       
   714       Parent::clear();
       
   715     }
       
   716 
       
   717     class NodesImpl : public NodesImplBase {
       
   718     public:
       
   719       typedef NodesImplBase Parent;
       
   720       
       
   721       NodesImpl(const Graph& graph, SmartUEdgeSet& edgeset) 
       
   722 	: Parent(graph), _edgeset(edgeset) {}
       
   723 
       
   724       virtual ~NodesImpl() {}
       
   725       
       
   726     protected:
       
   727 
       
   728       virtual void erase(const Node& node) {
       
   729 	_edgeset.eraseNode(node);
       
   730 	Parent::erase(node);
       
   731       }
       
   732       virtual void erase(const std::vector<Node>& nodes) {
       
   733 	for (int i = 0; i < (int)nodes.size(); ++i) {
       
   734 	  _edgeset.eraseNode(nodes[i]);
       
   735 	}
       
   736 	Parent::erase(nodes);
       
   737       }
       
   738       virtual void clear() {
       
   739 	_edgeset.clearNodes();
       
   740 	Parent::clear();
       
   741       }
       
   742 
       
   743     private:
       
   744       SmartUEdgeSet& _edgeset;
       
   745     };
       
   746 
       
   747     NodesImpl nodes;
       
   748     
       
   749   public:
       
   750 
       
   751     /// \brief Constructor of the adaptor.
       
   752     /// 
       
   753     /// Constructor of the adaptor.
       
   754     SmartUEdgeSet(const Graph& graph) : nodes(graph, *this) {
       
   755       Parent::initalize(graph, nodes);
       
   756     }
       
   757     
       
   758   };
       
   759 
   396 }
   760 }
   397 
   761 
   398 #endif
   762 #endif