bpp-core3  3.0.0
GlobalGraph.h
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: The Bio++ Development Group
2 //
3 // SPDX-License-Identifier: CECILL-2.1
4 
5 #ifndef BPP_GRAPH_GLOBALGRAPH_H
6 #define BPP_GRAPH_GLOBALGRAPH_H
7 
8 #include <limits>
9 #include <map>
10 #include <set>
11 #include <string>
12 
13 #include "../Clonable.h"
14 #include "Graph.h"
15 
16 namespace bpp
17 {
18 class GlobalGraph :
19  public virtual Graph,
20  public virtual Clonable
21 {
22 public:
25 
38  typedef std::map<Node, std::pair<std::map<Node, Edge>, std::map<Node, Edge>>> nodeStructureType;
39 
45  typedef std::map<Edge, std::pair<Node, Node>> edgeStructureType;
46 
47 private:
51  bool directed_;
52 
56  std::set<GraphObserver*> observers_;
57 
66 
72  nodeStructureType nodeStructure_;
73 
78  edgeStructureType edgeStructure_;
79 
83  Node root_;
84 
89  virtual void topologyHasChanged_() const
90  {
91  // do nothing: a Graph does not care to be modified
92  }
93 
98  void notify_();
99 
108  void linkInNodeStructure_(const Node& nodeA, const Node& nodeB, const Edge& edge);
109 
118  void linkInEdgeStructure_(const Node& nodeA, const Node& nodeB, const Edge& edge);
119 
120 
130  Edge unlinkInNodeStructure_(const Node& nodeA, const Node& nodeB);
131 
138  void unlinkInEdgeStructure_(const Edge& edge);
139 
140 protected:
146  void nodeMustExist_(const Node& node, std::string name = "") const;
147 
153  void edgeMustExist_(const Edge& edge, std::string name = "") const;
154 
155 private:
162  std::vector<Node> getNeighbors_(const Node& node, bool outgoing = true) const;
163 
170  std::vector<Edge> getEdges_(const Node& node, bool outgoing = true) const;
171 
177  void isolate_(Node& node);
178 
187  void fillListOfLeaves_(const Node& startingNode, std::vector<Node>& foundLeaves, const Node& originNode, unsigned int maxRecursions) const;
188 
195  bool nodesAreMetOnlyOnce_(const Node& node, std::set<Node>& metNodes, const Node& originNode) const;
196 
201  void nodeToDot_(const Node& node, std::ostream& out, std::set<std::pair<Node, Node>>& alreadyFigured) const;
202 
203 public:
207  // /@{
208 
209 
214  GlobalGraph(bool directed = false);
215 
216  GlobalGraph(const GlobalGraph& gg);
217 
218  GlobalGraph& operator=(const GlobalGraph& gg);
219 
220  GlobalGraph* clone() const {return new GlobalGraph(*this); }
221 
223 
224 protected:
230  void setRoot(Graph::NodeId newRoot);
231 
232 public:
237  Graph::NodeId getRoot() const;
238 
249  void makeDirected();
250 
260  void makeUndirected();
261 
262  // /@}
263 
264 
268  // /@{
269 
276 
284 
292 
300 
301 protected:
310 
319  void link(Graph::NodeId nodeA, Graph::NodeId nodeB, GlobalGraph::Edge edgeID);
320 
328  void switchNodes(Graph::NodeId nodeA, Graph::NodeId nodeB);
329 
330 
338  std::vector<Graph::EdgeId> unlink(Graph::NodeId nodeA, Graph::NodeId nodeB);
339 
340 public:
346  void deleteNode(Graph::NodeId node);
347 
348  // /@}
349 
350 
354  // /@{
355 
360  void registerObserver(GraphObserver* observer);
365  void unregisterObserver(GraphObserver* observer);
366  // /@}
367 
368 
372  // /@{
373 
374  template<typename T, bool is_const>
375  friend class NodesIteratorClass;
376 
377  template<typename T, bool is_const>
378  friend class EdgesIteratorClass;
379 
380  /*
381  * @brief builds iterator on all Nodes of the graph
382  *
383  */
384 
385  std::unique_ptr<Graph::NodeIterator> allNodesIterator();
386  std::unique_ptr<Graph::NodeIterator> allNodesIterator() const;
387 
388 
389  /*
390  * @brief builds iterator on the neighbor nodes of a Node
391  *
392  */
393 
394  std::unique_ptr<Graph::NodeIterator> outgoingNeighborNodesIterator(NodeId node);
395  std::unique_ptr<Graph::NodeIterator> outgoingNeighborNodesIterator(NodeId node) const;
396 
397  /*
398  * @brief builds iterator on the neighbor nodes of a Node
399  *
400  */
401 
402  std::unique_ptr<Graph::NodeIterator> incomingNeighborNodesIterator(NodeId node);
403  std::unique_ptr<Graph::NodeIterator> incomingNeighborNodesIterator(NodeId node) const;
404 
409  size_t getNumberOfNodes() const;
410 
415  size_t getNumberOfEdges() const;
416 
423  size_t getDegree(Graph::NodeId node) const;
424 
429  bool isLeaf(Graph::NodeId node) const;
430 
437  size_t getNumberOfNeighbors(Graph::NodeId node) const;
438 
445  size_t getNumberOfOutgoingNeighbors(Graph::NodeId node) const;
446 
453  size_t getNumberOfIncomingNeighbors(Graph::NodeId node) const;
454 
461  std::vector<Graph::NodeId> getNeighbors(Graph::NodeId node) const;
462 
469  std::vector<Graph::NodeId> getOutgoingNeighbors(Graph::NodeId node) const;
470 
477  std::vector<Graph::NodeId> getIncomingNeighbors(Graph::NodeId node) const;
478 
486  std::vector<Graph::NodeId> getLeavesFromNode(Graph::NodeId node, unsigned int maxDepth) const;
487 
494  std::vector<Graph::NodeId> getAllLeaves() const;
495  std::set<NodeId> getSetOfAllLeaves() const;
496 
502  std::vector<Graph::NodeId> getAllNodes() const;
503 
509  std::vector<Graph::NodeId> getAllInnerNodes() const;
510 
518  std::pair<Graph::NodeId, Graph::NodeId> getNodes(Graph::EdgeId edge) const;
519 
527  Graph::NodeId getTop(Graph::EdgeId edge) const;
528 
537 
538 
539  // /@}
540 
544  // /@{
545 
551  bool isTree() const;
552 
558  bool isDA() const;
559 
564  void orientate();
565 
570  bool isDirected() const;
571 
572 
577  bool containsReciprocalRelations() const;
578 
579 
580  // /@}
581 
582  /*
583  * @brief builds iterator on all Nodes of the graph
584  *
585  */
586 
587  std::unique_ptr<EdgeIterator> allEdgesIterator();
588  std::unique_ptr<EdgeIterator> allEdgesIterator() const;
589 
590  /*
591  * @brief builds iterator on the outgoing neighbor nodes of a Node
592  *
593  */
594 
595  std::unique_ptr<EdgeIterator> outgoingEdgesIterator(NodeId node);
596  std::unique_ptr<EdgeIterator> outgoingEdgesIterator(NodeId node) const;
597 
598  /*
599  * @brief builds iterator on the incoming neighbor nodes of a Node
600  *
601  */
602 
603  std::unique_ptr<EdgeIterator> incomingEdgesIterator(NodeId node);
604  std::unique_ptr<EdgeIterator> incomingEdgesIterator(NodeId node) const;
605 
612  std::vector<Graph::EdgeId> getEdges(Graph::NodeId node) const;
613 
620  std::vector<Graph::EdgeId> getOutgoingEdges(Graph::NodeId node) const;
621 
628  std::vector<Graph::EdgeId> getIncomingEdges(Graph::NodeId node) const;
629 
637  Graph::EdgeId getEdge(Graph::NodeId nodeA, Graph::NodeId nodeB) const;
638 
647 
653  std::vector<Graph::EdgeId> getAllEdges() const;
654 
655  // /@}
656 
657 
661  // /@{
662 
668  void notifyDeletedEdges(const std::vector<Graph::EdgeId>& edgesToDelete) const;
669 
674  void notifyDeletedNodes(const std::vector<Graph::NodeId>& nodesToDelete) const;
675 
676 
677  // /@}
678 
685  void outputToDot(std::ostream& out, const std::string& name) const;
686 
687  template<class N, class E, class GraphImpl>
689 };
690 
691 
692 /************************************************/
693 /************************************************/
694 /************************************************/
695 /* ITERATORS */
696 /************************************************/
697 
698 /************************************************/
699 /* NODES ITERATORS */
700 /************************************************/
701 
702 template<class T, bool is_const>
704  virtual public Graph::NodeIterator
705 {
707 };
708 
709 
710 template<bool is_const>
711 class NodesIteratorClass<Graph::ALLGRAPHITER, is_const> :
712  virtual public Graph::NodeIterator
713 {
714 private:
715  typedef typename std::conditional<is_const,
716  GlobalGraph::nodeStructureType::const_iterator,
717  GlobalGraph::nodeStructureType::iterator >::type itType;
718 
719  itType it_, begin_, end_;
720 
721 public:
722  template<bool B = is_const>
723  NodesIteratorClass<Graph::ALLGRAPHITER, is_const>(const GlobalGraph& gg, typename std::enable_if<B>::type* = 0) : it_(gg.nodeStructure_.begin()),
724  begin_(gg.nodeStructure_.begin()),
725  end_(gg.nodeStructure_.end()) {}
726 
727  template<bool B = is_const>
728  NodesIteratorClass<Graph::ALLGRAPHITER, is_const>(GlobalGraph& gg, typename std::enable_if<!B>::type* = 0) : it_(gg.nodeStructure_.begin()),
729  begin_(gg.nodeStructure_.begin()),
730  end_(gg.nodeStructure_.end()) {}
731 
733 
734  void next() { it_++; }
735  bool end() const { return it_ == end_; }
736  void start() { it_ = begin_; }
737 
738  Graph::NodeId operator*() {return it_->first; }
739 };
740 
741 
747 template<bool is_const>
749 {
750 protected:
751  typedef typename std::conditional<is_const,
752  const std::map<GlobalGraph::Node, GlobalGraph::Edge>&,
753  std::map<GlobalGraph::Node, GlobalGraph::Edge>&>::type mapType;
754 
755  mapType map_;
756 
757  typedef typename std::conditional<is_const,
758  std::map<GlobalGraph::Node, GlobalGraph::Edge>::const_iterator,
759  std::map<GlobalGraph::Node, GlobalGraph::Edge>::iterator>::type itType;
760 
761  itType it_, begin_, end_;
762 
763 public:
765 
766  template<bool B = is_const>
767  NeighborIteratorClass<is_const>(const std::map<GlobalGraph::Node, GlobalGraph::Edge>& map, typename std::enable_if<B>::type* = 0) :
768  map_(map),
769  it_(map_.begin()),
770  begin_(map_.begin()),
771  end_(map_.end()) {}
772 
773  template<bool B = is_const>
774  NeighborIteratorClass<is_const>(std::map<GlobalGraph::Node, GlobalGraph::Edge>& map, typename std::enable_if<!B>::type* = 0) :
775  map_(map),
776  it_(map_.begin()),
777  begin_(map_.begin()),
778  end_(map_.end()) {}
779 
780  void next() { it_++; }
781  bool end() const { return it_ == end_; }
782  void start() { it_ = begin_; }
783 };
784 
785 
791 template<bool is_const>
792 class NodesIteratorClass<Graph::OUTGOINGNEIGHBORITER, is_const> :
793  virtual public NeighborIteratorClass<is_const>,
794  virtual public Graph::NodeIterator
795 {
796 public:
798 
800 
802 
804  bool end() const { return NeighborIteratorClass<is_const>::end(); }
806 
808 };
809 
810 
811 template<bool is_const>
812 class NodesIteratorClass<Graph::INCOMINGNEIGHBORITER, is_const> :
813  virtual public NeighborIteratorClass<is_const>,
814  virtual public Graph::NodeIterator
815 {
816 public:
818 
820 
822 
824  bool end() const { return NeighborIteratorClass<is_const>::end(); }
826 
828 };
829 
830 
831 /************************************************/
832 /* EDGES ITERATORS */
833 /************************************************/
834 
835 template<class T, bool is_const>
837  virtual public Graph::EdgeIterator
838 {};
839 
840 template<bool is_const>
841 class EdgesIteratorClass<Graph::ALLGRAPHITER, is_const> :
842  virtual public Graph::EdgeIterator
843 {
844 private:
845  typedef typename std::conditional<is_const,
846  GlobalGraph::edgeStructureType::const_iterator,
847  GlobalGraph::edgeStructureType::iterator >::type itType;
848 
849  itType it_, begin_, end_;
850 
851 public:
852  template<bool B = is_const>
853  EdgesIteratorClass<Graph::ALLGRAPHITER, is_const>(const GlobalGraph& gg, typename std::enable_if<B>::type* = 0) : it_(gg.edgeStructure_.begin()),
854  begin_(gg.edgeStructure_.begin()),
855  end_(gg.edgeStructure_.end()) {}
856 
857  template<bool B = is_const>
858  EdgesIteratorClass<Graph::ALLGRAPHITER, is_const>(GlobalGraph& gg, typename std::enable_if<!B>::type* = 0) : it_(gg.edgeStructure_.begin()),
859  begin_(gg.edgeStructure_.begin()),
860  end_(gg.edgeStructure_.end()) {}
861 
863 
864  void next() { it_++; }
865  bool end() const { return it_ == end_; }
866  void start() { it_ = begin_; }
867 
868  Graph::EdgeId operator*() {return it_->first; }
869 };
870 
871 
872 template<bool is_const>
873 class EdgesIteratorClass<Graph::OUTGOINGNEIGHBORITER, is_const> :
874  public NeighborIteratorClass<is_const>,
875  public Graph::EdgeIterator
876 {
877 public:
879 
881 
883 
885  bool end() const { return NeighborIteratorClass<is_const>::end(); }
887 
889 };
890 
891 template<bool is_const>
892 class EdgesIteratorClass<Graph::INCOMINGNEIGHBORITER, is_const> :
893  public NeighborIteratorClass<is_const>,
894  public Graph::EdgeIterator
895 {
896 public:
898 
900 
902 
904  bool end() const { return NeighborIteratorClass<is_const>::end(); }
906 
908 };
909 }
910 #endif // BPP_GRAPH_GLOBALGRAPH_H
virtual void topologyHasChanged_() const
Definition: GlobalGraph.h:89
std::vector< Graph::EdgeId > getOutgoingEdges(Graph::NodeId node) const
size_t getNumberOfEdges() const
std::unique_ptr< EdgeIterator > allEdgesIterator()
Abstract class for neighbor iterators.
Definition: GlobalGraph.h:748
size_t getNumberOfOutgoingNeighbors(Graph::NodeId node) const
void unregisterObserver(GraphObserver *observer)
virtual bool end() const =0
void notifyDeletedEdges(const std::vector< Graph::EdgeId > &edgesToDelete) const
Graph::NodeId getBottom(Graph::EdgeId edge) const
void switchNodes(Graph::NodeId nodeA, Graph::NodeId nodeB)
void outputToDot(std::ostream &out, const std::string &name) const
void edgeMustExist_(const Edge &edge, std::string name="") const
Definition: GlobalGraph.cpp:60
Graph::EdgeId getEdge(Graph::NodeId nodeA, Graph::NodeId nodeB) const
std::conditional< is_const, const std::map< GlobalGraph::Node, GlobalGraph::Edge > &, std::map< GlobalGraph::Node, GlobalGraph::Edge > & >::type mapType
Definition: GlobalGraph.h:753
Graph::EdgeId getAnyEdge(Graph::NodeId nodeA, Graph::NodeId nodeB) const
std::map< Edge, std::pair< Node, Node > > edgeStructureType
Definition: GlobalGraph.h:45
Graph::EdgeId Edge
Definition: GlobalGraph.h:24
void deleteNode(Graph::NodeId node)
GlobalGraph * clone() const
Create a copy of this object and send a pointer to it.
Definition: GlobalGraph.h:220
std::vector< Graph::NodeId > getIncomingNeighbors(Graph::NodeId node) const
std::vector< Graph::EdgeId > getIncomingEdges(Graph::NodeId node) const
std::conditional< is_const, std::map< GlobalGraph::Node, GlobalGraph::Edge >::const_iterator, std::map< GlobalGraph::Node, GlobalGraph::Edge >::iterator >::type itType
Definition: GlobalGraph.h:759
Graph::NodeId createNodeOnEdge(Graph::EdgeId edge)
unsigned int NodeId
Definition: Graph.h:30
bool isDA() const
void nodeMustExist_(const Node &node, std::string name="") const
Definition: GlobalGraph.cpp:54
bool containsReciprocalRelations() const
Graph::NodeId createNode()
bool nodesAreMetOnlyOnce_(const Node &node, std::set< Node > &metNodes, const Node &originNode) const
std::vector< Node > getNeighbors_(const Node &node, bool outgoing=true) const
std::set< GraphObserver * > observers_
Definition: GlobalGraph.h:56
void setRoot(Graph::NodeId newRoot)
std::vector< Graph::NodeId > getAllLeaves() const
Edge unlinkInNodeStructure_(const Node &nodeA, const Node &nodeB)
std::conditional< is_const, GlobalGraph::nodeStructureType::const_iterator, GlobalGraph::nodeStructureType::iterator >::type itType
Definition: GlobalGraph.h:717
void linkInEdgeStructure_(const Node &nodeA, const Node &nodeB, const Edge &edge)
std::vector< Graph::NodeId > getLeavesFromNode(Graph::NodeId node, unsigned int maxDepth) const
std::vector< Edge > getEdges_(const Node &node, bool outgoing=true) const
Graph::NodeId createNodeFromEdge(Graph::NodeId origin)
Graph::EdgeId link(Graph::NodeId nodeA, Graph::NodeId nodeB)
Definition: GlobalGraph.cpp:67
virtual bool end() const =0
std::unique_ptr< Graph::NodeIterator > incomingNeighborNodesIterator(NodeId node)
GlobalGraph(bool directed=false)
Definition: GlobalGraph.cpp:19
std::map< Node, std::pair< std::map< Node, Edge >, std::map< Node, Edge > > > nodeStructureType
Definition: GlobalGraph.h:38
size_t getNumberOfNodes() const
Graph::NodeId getTop(Graph::EdgeId edge) const
size_t getNumberOfIncomingNeighbors(Graph::NodeId node) const
void unlinkInEdgeStructure_(const Edge &edge)
std::unique_ptr< Graph::NodeIterator > allNodesIterator()
GlobalGraph & operator=(const GlobalGraph &gg)
Definition: GlobalGraph.cpp:40
std::unique_ptr< EdgeIterator > outgoingEdgesIterator(NodeId node)
bool isLeaf(Graph::NodeId node) const
std::vector< Graph::EdgeId > unlink(Graph::NodeId nodeA, Graph::NodeId nodeB)
Definition: GlobalGraph.cpp:96
void fillListOfLeaves_(const Node &startingNode, std::vector< Node > &foundLeaves, const Node &originNode, unsigned int maxRecursions) const
std::vector< Graph::NodeId > getOutgoingNeighbors(Graph::NodeId node) const
std::unique_ptr< Graph::NodeIterator > outgoingNeighborNodesIterator(NodeId node)
The Clonable interface (allow an object to be cloned).
Definition: Clonable.h:63
void linkInNodeStructure_(const Node &nodeA, const Node &nodeB, const Edge &edge)
std::unique_ptr< EdgeIterator > incomingEdgesIterator(NodeId node)
std::vector< Graph::NodeId > getAllInnerNodes() const
Graph::NodeId Node
Definition: GlobalGraph.h:23
std::vector< Graph::NodeId > getNeighbors(Graph::NodeId node) const
std::vector< Graph::EdgeId > getAllEdges() const
nodeStructureType nodeStructure_
Definition: GlobalGraph.h:72
Graph::NodeId createNodeFromNode(Graph::NodeId origin)
size_t getDegree(Graph::NodeId node) const
void registerObserver(GraphObserver *observer)
Defines a Graph Observer. It is a template which follows (subscribed to) a Graph. The graph and the g...
Definition: GraphObserver.h:31
void notifyDeletedNodes(const std::vector< Graph::NodeId > &nodesToDelete) const
std::vector< Graph::NodeId > getAllNodes() const
std::set< NodeId > getSetOfAllLeaves() const
size_t getNumberOfNeighbors(Graph::NodeId node) const
bool isDirected() const
std::pair< Graph::NodeId, Graph::NodeId > getNodes(Graph::EdgeId edge) const
void nodeToDot_(const Node &node, std::ostream &out, std::set< std::pair< Node, Node >> &alreadyFigured) const
std::conditional< is_const, GlobalGraph::edgeStructureType::const_iterator, GlobalGraph::edgeStructureType::iterator >::type itType
Definition: GlobalGraph.h:847
unsigned int EdgeId
Definition: Graph.h:31
edgeStructureType edgeStructure_
Definition: GlobalGraph.h:78
Graph::NodeId getRoot() const
std::vector< Graph::EdgeId > getEdges(Graph::NodeId node) const
bool isTree() const
void isolate_(Node &node)