bpp-core3  3.0.0
GlobalGraph.h
Go to the documentation of this file.
1 //
2 // File: GlobalGraph.h
3 // Authors:
4 // Thomas Bigot
5 // Laurent Gueguen
6 // Last modified: vendredi 4 novembre 2016, à 10h 19
7 //
8 
9 /*
10  Copyright or © or Copr. Bio++ Development Team, (November 17, 2004)
11 
12  This software is a computer program whose purpose is to provide utilitary
13  classes. This file belongs to the Bio++ Project.
14 
15  This software is governed by the CeCILL license under French law and
16  abiding by the rules of distribution of free software. You can use,
17  modify and/ or redistribute the software under the terms of the CeCILL
18  license as circulated by CEA, CNRS and INRIA at the following URL
19  "http://www.cecill.info".
20 
21  As a counterpart to the access to the source code and rights to copy,
22  modify and redistribute granted by the license, users are provided only
23  with a limited warranty and the software's author, the holder of the
24  economic rights, and the successive licensors have only limited
25  liability.
26 
27  In this respect, the user's attention is drawn to the risks associated
28  with loading, using, modifying and/or developing or reproducing the
29  software by the user in light of its specific status of free software,
30  that may mean that it is complicated to manipulate, and that also
31  therefore means that it is reserved for developers and experienced
32  professionals having in-depth computer knowledge. Users are therefore
33  encouraged to load and test the software's suitability as regards their
34  requirements in conditions enabling the security of their systems and/or
35  data to be ensured and, more generally, to use and operate it in the
36  same conditions as regards security.
37 
38  The fact that you are presently reading this means that you have had
39  knowledge of the CeCILL license and that you accept its terms.
40 */
41 
42 #ifndef BPP_GRAPH_GLOBALGRAPH_H
43 #define BPP_GRAPH_GLOBALGRAPH_H
44 
45 #include <limits>
46 #include <map>
47 #include <set>
48 #include <string>
49 
50 #include "../Clonable.h"
51 #include "Graph.h"
52 
53 namespace bpp
54 {
55 class GlobalGraph :
56  public virtual Graph,
57  public virtual Clonable
58 {
59 public:
62 
75  typedef std::map<Node, std::pair<std::map<Node, Edge>, std::map<Node, Edge> > > nodeStructureType;
76 
82  typedef std::map<Edge, std::pair<Node, Node> > edgeStructureType;
83 
84 private:
88  bool directed_;
89 
93  std::set<GraphObserver*> observers_;
94 
103 
110 
116 
121 
126  virtual void topologyHasChanged_() const
127  {
128  // do nothing: a Graph does not care to be modified
129  }
130 
135  void notify_();
136 
145  void linkInNodeStructure_(const Node& nodeA, const Node& nodeB, const Edge& edge);
146 
155  void linkInEdgeStructure_(const Node& nodeA, const Node& nodeB, const Edge& edge);
156 
157 
167  Edge unlinkInNodeStructure_(const Node& nodeA, const Node& nodeB);
168 
175  void unlinkInEdgeStructure_(const Edge& edge);
176 
177 protected:
183  void nodeMustExist_(const Node& node, std::string name = "") const;
184 
190  void edgeMustExist_(const Edge& edge, std::string name = "") const;
191 
192 private:
199  std::vector<Node> getNeighbors_(const Node& node, bool outgoing = true) const;
200 
207  std::vector<Edge> getEdges_(const Node& node, bool outgoing = true) const;
208 
214  void isolate_(Node& node);
215 
224  void fillListOfLeaves_(const Node& startingNode, std::vector<Node>& foundLeaves, const Node& originNode, unsigned int maxRecursions) const;
225 
232  bool nodesAreMetOnlyOnce_(const Node& node, std::set<Node>& metNodes, const Node& originNode) const;
233 
238  void nodeToDot_(const Node& node, std::ostream& out, std::set<std::pair<Node, Node> >& alreadyFigured) const;
239 
240 public:
244  // /@{
245 
246 
251  GlobalGraph(bool directed = false);
252 
253  GlobalGraph(const GlobalGraph& gg);
254 
255  GlobalGraph& operator=(const GlobalGraph& gg);
256 
257  GlobalGraph* clone() const {return new GlobalGraph(*this); }
258 
260 
261 protected:
267  void setRoot(Graph::NodeId newRoot);
268 
269 public:
274  Graph::NodeId getRoot() const;
275 
286  void makeDirected();
287 
297  void makeUndirected();
298 
299  // /@}
300 
301 
305  // /@{
306 
313 
321 
329 
337 
338 protected:
347 
356  void link(Graph::NodeId nodeA, Graph::NodeId nodeB, GlobalGraph::Edge edgeID);
357 
365  void switchNodes(Graph::NodeId nodeA, Graph::NodeId nodeB);
366 
367 
375  std::vector<Graph::EdgeId> unlink(Graph::NodeId nodeA, Graph::NodeId nodeB);
376 
377 public:
383  void deleteNode(Graph::NodeId node);
384 
385  // /@}
386 
387 
391  // /@{
392 
397  void registerObserver(GraphObserver* observer);
402  void unregisterObserver(GraphObserver* observer);
403  // /@}
404 
405 
409  // /@{
410 
411  template<typename T, bool is_const>
412  friend class NodesIteratorClass;
413 
414  template<typename T, bool is_const>
415  friend class EdgesIteratorClass;
416 
417  /*
418  * @brief builds iterator on all Nodes of the graph
419  *
420  */
421 
422  std::unique_ptr<Graph::NodeIterator> allNodesIterator();
423  std::unique_ptr<Graph::NodeIterator> allNodesIterator() const;
424 
425 
426  /*
427  * @brief builds iterator on the neighbor nodes of a Node
428  *
429  */
430 
431  std::unique_ptr<Graph::NodeIterator> outgoingNeighborNodesIterator(NodeId node);
432  std::unique_ptr<Graph::NodeIterator> outgoingNeighborNodesIterator(NodeId node) const;
433 
434  /*
435  * @brief builds iterator on the neighbor nodes of a Node
436  *
437  */
438 
439  std::unique_ptr<Graph::NodeIterator> incomingNeighborNodesIterator(NodeId node);
440  std::unique_ptr<Graph::NodeIterator> incomingNeighborNodesIterator(NodeId node) const;
441 
446  size_t getNumberOfNodes() const;
447 
452  size_t getNumberOfEdges() const;
453 
460  size_t getDegree(Graph::NodeId node) const;
461 
466  bool isLeaf(Graph::NodeId node) const;
467 
474  size_t getNumberOfNeighbors(Graph::NodeId node) const;
475 
482  size_t getNumberOfOutgoingNeighbors(Graph::NodeId node) const;
483 
490  size_t getNumberOfIncomingNeighbors(Graph::NodeId node) const;
491 
498  std::vector<Graph::NodeId> getNeighbors(Graph::NodeId node) const;
499 
506  std::vector<Graph::NodeId> getOutgoingNeighbors(Graph::NodeId node) const;
507 
514  std::vector<Graph::NodeId> getIncomingNeighbors(Graph::NodeId node) const;
515 
523  std::vector<Graph::NodeId> getLeavesFromNode(Graph::NodeId node, unsigned int maxDepth) const;
524 
531  std::vector<Graph::NodeId> getAllLeaves() const;
532  std::set<NodeId> getSetOfAllLeaves() const;
533 
539  std::vector<Graph::NodeId> getAllNodes() const;
540 
546  std::vector<Graph::NodeId> getAllInnerNodes() const;
547 
555  std::pair<Graph::NodeId, Graph::NodeId> getNodes(Graph::EdgeId edge) const;
556 
564  Graph::NodeId getTop(Graph::EdgeId edge) const;
565 
574 
575 
576  // /@}
577 
581  // /@{
582 
588  bool isTree() const;
589 
595  bool isDA() const;
596 
601  void orientate();
602 
607  bool isDirected() const;
608 
609 
614  bool containsReciprocalRelations() const;
615 
616 
617  // /@}
618 
619  /*
620  * @brief builds iterator on all Nodes of the graph
621  *
622  */
623 
624  std::unique_ptr<EdgeIterator> allEdgesIterator();
625  std::unique_ptr<EdgeIterator> allEdgesIterator() const;
626 
627  /*
628  * @brief builds iterator on the outgoing neighbor nodes of a Node
629  *
630  */
631 
632  std::unique_ptr<EdgeIterator> outgoingEdgesIterator(NodeId node);
633  std::unique_ptr<EdgeIterator> outgoingEdgesIterator(NodeId node) const;
634 
635  /*
636  * @brief builds iterator on the incoming neighbor nodes of a Node
637  *
638  */
639 
640  std::unique_ptr<EdgeIterator> incomingEdgesIterator(NodeId node);
641  std::unique_ptr<EdgeIterator> incomingEdgesIterator(NodeId node) const;
642 
649  std::vector<Graph::EdgeId> getEdges(Graph::NodeId node) const;
650 
657  std::vector<Graph::EdgeId> getOutgoingEdges(Graph::NodeId node) const;
658 
665  std::vector<Graph::EdgeId> getIncomingEdges(Graph::NodeId node) const;
666 
674  Graph::EdgeId getEdge(Graph::NodeId nodeA, Graph::NodeId nodeB) const;
675 
684 
690  std::vector<Graph::EdgeId> getAllEdges() const;
691 
692  // /@}
693 
694 
698  // /@{
699 
705  void notifyDeletedEdges(const std::vector<Graph::EdgeId>& edgesToDelete) const;
706 
711  void notifyDeletedNodes(const std::vector<Graph::NodeId>& nodesToDelete) const;
712 
713 
714  // /@}
715 
722  void outputToDot(std::ostream& out, const std::string& name) const;
723 
724  template<class N, class E, class GraphImpl>
726 };
727 
728 
729 /************************************************/
730 /************************************************/
731 /************************************************/
732 /* ITERATORS */
733 /************************************************/
734 
735 /************************************************/
736 /* NODES ITERATORS */
737 /************************************************/
738 
739 template<class T, bool is_const>
741  virtual public Graph::NodeIterator
742 {
744 };
745 
746 
747 template<bool is_const>
748 class NodesIteratorClass<Graph::ALLGRAPHITER, is_const> :
749  virtual public Graph::NodeIterator
750 {
751 private:
752  typedef typename std::conditional<is_const,
753  GlobalGraph::nodeStructureType::const_iterator,
754  GlobalGraph::nodeStructureType::iterator >::type itType;
755 
756  itType it_, begin_, end_;
757 
758 public:
759  template<bool B = is_const>
760  NodesIteratorClass<Graph::ALLGRAPHITER, is_const>(const GlobalGraph& gg, typename std::enable_if<B>::type* = 0) : it_(gg.nodeStructure_.begin()),
761  begin_(gg.nodeStructure_.begin()),
762  end_(gg.nodeStructure_.end()) {}
763 
764  template<bool B = is_const>
765  NodesIteratorClass<Graph::ALLGRAPHITER, is_const>(GlobalGraph& gg, typename std::enable_if<!B>::type* = 0) : it_(gg.nodeStructure_.begin()),
766  begin_(gg.nodeStructure_.begin()),
767  end_(gg.nodeStructure_.end()) {}
768 
769  ~NodesIteratorClass<Graph::ALLGRAPHITER, is_const>(){}
770 
771  void next() { it_++; }
772  bool end() const { return it_ == end_; }
773  void start() { it_ = begin_; }
774 
775  Graph::NodeId operator*() {return it_->first; }
776 };
777 
778 
784 template<bool is_const>
786 {
787 protected:
788  typedef typename std::conditional<is_const,
789  const std::map<GlobalGraph::Node, GlobalGraph::Edge>&,
790  std::map<GlobalGraph::Node, GlobalGraph::Edge>&>::type mapType;
791 
793 
794  typedef typename std::conditional<is_const,
795  std::map<GlobalGraph::Node, GlobalGraph::Edge>::const_iterator,
796  std::map<GlobalGraph::Node, GlobalGraph::Edge>::iterator>::type itType;
797 
798  itType it_, begin_, end_;
799 
800 public:
802 
803  template<bool B = is_const>
804  NeighborIteratorClass<is_const>(const std::map<GlobalGraph::Node, GlobalGraph::Edge>& map, typename std::enable_if<B>::type* = 0) :
805  map_(map),
806  it_(map_.begin()),
807  begin_(map_.begin()),
808  end_(map_.end()) {}
809 
810  template<bool B = is_const>
811  NeighborIteratorClass<is_const>(std::map<GlobalGraph::Node, GlobalGraph::Edge>& map, typename std::enable_if<!B>::type* = 0) :
812  map_(map),
813  it_(map_.begin()),
814  begin_(map_.begin()),
815  end_(map_.end()) {}
816 
817  void next() { it_++; }
818  bool end() const { return it_ == end_; }
819  void start() { it_ = begin_; }
820 };
821 
822 
828 template<bool is_const>
829 class NodesIteratorClass<Graph::OUTGOINGNEIGHBORITER, is_const> :
830  virtual public NeighborIteratorClass<is_const>,
831  virtual public Graph::NodeIterator
832 {
833 public:
835 
837 
839 
841  bool end() const { return NeighborIteratorClass<is_const>::end(); }
843 
845 };
846 
847 
848 template<bool is_const>
849 class NodesIteratorClass<Graph::INCOMINGNEIGHBORITER, is_const> :
850  virtual public NeighborIteratorClass<is_const>,
851  virtual public Graph::NodeIterator
852 {
853 public:
855 
857 
859 
861  bool end() const { return NeighborIteratorClass<is_const>::end(); }
863 
865 };
866 
867 
868 /************************************************/
869 /* EDGES ITERATORS */
870 /************************************************/
871 
872 template<class T, bool is_const>
874  virtual public Graph::EdgeIterator
875 {};
876 
877 template<bool is_const>
878 class EdgesIteratorClass<Graph::ALLGRAPHITER, is_const> :
879  virtual public Graph::EdgeIterator
880 {
881 private:
882  typedef typename std::conditional<is_const,
883  GlobalGraph::edgeStructureType::const_iterator,
884  GlobalGraph::edgeStructureType::iterator >::type itType;
885 
886  itType it_, begin_, end_;
887 
888 public:
889  template<bool B = is_const>
890  EdgesIteratorClass<Graph::ALLGRAPHITER, is_const>(const GlobalGraph& gg, typename std::enable_if<B>::type* = 0) : it_(gg.edgeStructure_.begin()),
891  begin_(gg.edgeStructure_.begin()),
892  end_(gg.edgeStructure_.end()) {}
893 
894  template<bool B = is_const>
895  EdgesIteratorClass<Graph::ALLGRAPHITER, is_const>(GlobalGraph& gg, typename std::enable_if<!B>::type* = 0) : it_(gg.edgeStructure_.begin()),
896  begin_(gg.edgeStructure_.begin()),
897  end_(gg.edgeStructure_.end()) {}
898 
899  ~EdgesIteratorClass<Graph::ALLGRAPHITER, is_const>(){}
900 
901  void next() { it_++; }
902  bool end() const { return it_ == end_; }
903  void start() { it_ = begin_; }
904 
905  Graph::EdgeId operator*() {return it_->first; }
906 };
907 
908 
909 template<bool is_const>
910 class EdgesIteratorClass<Graph::OUTGOINGNEIGHBORITER, is_const> :
911  public NeighborIteratorClass<is_const>,
912  public Graph::EdgeIterator
913 {
914 public:
916 
918 
920 
922  bool end() const { return NeighborIteratorClass<is_const>::end(); }
924 
926 };
927 
928 template<bool is_const>
929 class EdgesIteratorClass<Graph::INCOMINGNEIGHBORITER, is_const> :
930  public NeighborIteratorClass<is_const>,
931  public Graph::EdgeIterator
932 {
933 public:
935 
937 
939 
941  bool end() const { return NeighborIteratorClass<is_const>::end(); }
943 
945 };
946 }
947 #endif // BPP_GRAPH_GLOBALGRAPH_H
The Clonable interface (allow an object to be cloned).
Definition: Clonable.h:103
std::conditional< is_const, GlobalGraph::edgeStructureType::const_iterator, GlobalGraph::edgeStructureType::iterator >::type itType
Definition: GlobalGraph.h:884
Graph::EdgeId getAnyEdge(Graph::NodeId nodeA, Graph::NodeId nodeB) const
bool isDA() const
bool isTree() const
size_t getNumberOfIncomingNeighbors(Graph::NodeId node) const
std::unique_ptr< Graph::NodeIterator > outgoingNeighborNodesIterator(NodeId node)
std::vector< Graph::NodeId > getNeighbors(Graph::NodeId node) const
GlobalGraph & operator=(const GlobalGraph &gg)
Definition: GlobalGraph.cpp:75
bool isDirected() const
std::vector< Graph::EdgeId > getEdges(Graph::NodeId node) const
void fillListOfLeaves_(const Node &startingNode, std::vector< Node > &foundLeaves, const Node &originNode, unsigned int maxRecursions) const
void deleteNode(Graph::NodeId node)
void edgeMustExist_(const Edge &edge, std::string name="") const
Definition: GlobalGraph.cpp:95
bool nodesAreMetOnlyOnce_(const Node &node, std::set< Node > &metNodes, const Node &originNode) const
Graph::EdgeId link(Graph::NodeId nodeA, Graph::NodeId nodeB)
std::unique_ptr< EdgeIterator > allEdgesIterator()
size_t getNumberOfOutgoingNeighbors(Graph::NodeId node) const
std::set< NodeId > getSetOfAllLeaves() const
std::vector< Graph::NodeId > getLeavesFromNode(Graph::NodeId node, unsigned int maxDepth) const
bool containsReciprocalRelations() const
void nodeToDot_(const Node &node, std::ostream &out, std::set< std::pair< Node, Node > > &alreadyFigured) const
edgeStructureType edgeStructure_
Definition: GlobalGraph.h:115
Graph::NodeId Node
Definition: GlobalGraph.h:60
Graph::EdgeId getEdge(Graph::NodeId nodeA, Graph::NodeId nodeB) const
Graph::NodeId createNodeFromNode(Graph::NodeId origin)
void switchNodes(Graph::NodeId nodeA, Graph::NodeId nodeB)
void unregisterObserver(GraphObserver *observer)
std::unique_ptr< Graph::NodeIterator > incomingNeighborNodesIterator(NodeId node)
Graph::NodeId createNodeOnEdge(Graph::EdgeId edge)
std::pair< Graph::NodeId, Graph::NodeId > getNodes(Graph::EdgeId edge) const
size_t getNumberOfNodes() const
size_t getNumberOfNeighbors(Graph::NodeId node) const
Graph::NodeId getRoot() const
std::unique_ptr< EdgeIterator > incomingEdgesIterator(NodeId node)
std::vector< Edge > getEdges_(const Node &node, bool outgoing=true) const
std::vector< Graph::NodeId > getAllNodes() const
GlobalGraph * clone() const
Create a copy of this object and send a pointer to it.
Definition: GlobalGraph.h:257
std::vector< Node > getNeighbors_(const Node &node, bool outgoing=true) const
std::map< Node, std::pair< std::map< Node, Edge >, std::map< Node, Edge > > > nodeStructureType
Definition: GlobalGraph.h:75
Graph::NodeId createNodeFromEdge(Graph::NodeId origin)
nodeStructureType nodeStructure_
Definition: GlobalGraph.h:109
std::vector< Graph::EdgeId > unlink(Graph::NodeId nodeA, Graph::NodeId nodeB)
void linkInEdgeStructure_(const Node &nodeA, const Node &nodeB, const Edge &edge)
std::set< GraphObserver * > observers_
Definition: GlobalGraph.h:93
bool isLeaf(Graph::NodeId node) const
size_t getNumberOfEdges() const
void linkInNodeStructure_(const Node &nodeA, const Node &nodeB, const Edge &edge)
std::vector< Graph::NodeId > getAllInnerNodes() const
std::unique_ptr< Graph::NodeIterator > allNodesIterator()
std::vector< Graph::NodeId > getIncomingNeighbors(Graph::NodeId node) const
Graph::NodeId getTop(Graph::EdgeId edge) const
Edge unlinkInNodeStructure_(const Node &nodeA, const Node &nodeB)
void unlinkInEdgeStructure_(const Edge &edge)
std::vector< Graph::EdgeId > getIncomingEdges(Graph::NodeId node) const
void isolate_(Node &node)
std::unique_ptr< EdgeIterator > outgoingEdgesIterator(NodeId node)
void registerObserver(GraphObserver *observer)
virtual void topologyHasChanged_() const
Definition: GlobalGraph.h:126
std::vector< Graph::EdgeId > getOutgoingEdges(Graph::NodeId node) const
Graph::EdgeId Edge
Definition: GlobalGraph.h:61
void outputToDot(std::ostream &out, const std::string &name) const
std::map< Edge, std::pair< Node, Node > > edgeStructureType
Definition: GlobalGraph.h:82
size_t getDegree(Graph::NodeId node) const
std::vector< Graph::EdgeId > getAllEdges() const
std::vector< Graph::NodeId > getAllLeaves() const
void notifyDeletedNodes(const std::vector< Graph::NodeId > &nodesToDelete) const
Graph::NodeId createNode()
GlobalGraph(bool directed=false)
Definition: GlobalGraph.cpp:54
void nodeMustExist_(const Node &node, std::string name="") const
Definition: GlobalGraph.cpp:89
Graph::NodeId getBottom(Graph::EdgeId edge) const
std::vector< Graph::NodeId > getOutgoingNeighbors(Graph::NodeId node) const
void setRoot(Graph::NodeId newRoot)
void notifyDeletedEdges(const std::vector< Graph::EdgeId > &edgesToDelete) const
Defines a Graph Observer. It is a template which follows (subscribed to) a Graph. The graph and the g...
Definition: GraphObserver.h:69
virtual bool end() const =0
unsigned int NodeId
Definition: Graph.h:66
unsigned int EdgeId
Definition: Graph.h:67
Abstract class for neighbor iterators.
Definition: GlobalGraph.h:786
std::conditional< is_const, std::map< GlobalGraph::Node, GlobalGraph::Edge >::const_iterator, std::map< GlobalGraph::Node, GlobalGraph::Edge >::iterator >::type itType
Definition: GlobalGraph.h:796
std::conditional< is_const, const std::map< GlobalGraph::Node, GlobalGraph::Edge > &, std::map< GlobalGraph::Node, GlobalGraph::Edge > & >::type mapType
Definition: GlobalGraph.h:790
std::conditional< is_const, GlobalGraph::nodeStructureType::const_iterator, GlobalGraph::nodeStructureType::iterator >::type itType
Definition: GlobalGraph.h:754
std::vector< T > operator*(const std::vector< T > &v1, const std::vector< T > &v2)
Definition: VectorTools.h:136