bpp-core3  3.0.0
AssociationGraphImplObserver.h
Go to the documentation of this file.
1 //
2 // File: AssociationGraphImplObserver.h
3 // Authors:
4 // Thomas Bigot
5 // Last modified: 2017-06-27 00:00:00
6 //
7 
8 /*
9  Copyright or © or Copr. Bio++ Development Team, (November 17, 2004)
10 
11  This software is a computer program whose purpose is to provide utilitary
12  classes. This file belongs to the Bio++ Project.
13 
14  This software is governed by the CeCILL license under French law and
15  abiding by the rules of distribution of free software. You can use,
16  modify and/ or redistribute the software under the terms of the CeCILL
17  license as circulated by CEA, CNRS and INRIA at the following URL
18  "http://www.cecill.info".
19 
20  As a counterpart to the access to the source code and rights to copy,
21  modify and redistribute granted by the license, users are provided only
22  with a limited warranty and the software's author, the holder of the
23  economic rights, and the successive licensors have only limited
24  liability.
25 
26  In this respect, the user's attention is drawn to the risks associated
27  with loading, using, modifying and/or developing or reproducing the
28  software by the user in light of its specific status of free software,
29  that may mean that it is complicated to manipulate, and that also
30  therefore means that it is reserved for developers and experienced
31  professionals having in-depth computer knowledge. Users are therefore
32  encouraged to load and test the software's suitability as regards their
33  requirements in conditions enabling the security of their systems and/or
34  data to be ensured and, more generally, to use and operate it in the
35  same conditions as regards security.
36 
37  The fact that you are presently reading this means that you have had
38  knowledge of the CeCILL license and that you accept its terms.
39 */
40 
41 #ifndef BPP_GRAPH_ASSOCIATIONGRAPHIMPLOBSERVER_H
42 #define BPP_GRAPH_ASSOCIATIONGRAPHIMPLOBSERVER_H
43 
44 #include <algorithm>
45 #include <fstream>
46 #include <iostream>
47 #include <map>
48 #include <memory>
49 #include <ostream>
50 #include <type_traits>
51 #include <vector>
52 
53 #include "../Clonable.h"
54 #include "../Exceptions.h"
55 #include "../Text/TextTools.h"
57 #include "GlobalGraph.h"
58 
59 namespace bpp
60 {
61 template<class N, class E, class GraphImpl>
63 {
64 public:
67 
70 
71  using Eref = std::shared_ptr<E>;
72  using Nref = std::shared_ptr<N>;
73 
74 protected:
80  std::shared_ptr<GraphImpl> subjectGraph_;
81 
82 private:
93  std::vector<Nref > graphidToN_;
94 
99  std::vector<Eref > graphidToE_;
100 
104  std::map<Nref, NodeGraphid> NToGraphid_;
105 
109  std::map<Eref, EdgeGraphid> EToGraphid_;
110 
111  /*
112  * @}
113  */
114 
124  std::vector<Nref > indexToN_;
125 
129  std::vector<Eref > indexToE_;
130 
134  std::map<Nref, NodeIndex> NToIndex_;
135 
139  std::map<Eref, EdgeIndex> EToIndex_;
140 
141  /*
142  * @}
143  */
144 
145 public:
151  AssociationGraphImplObserver(bool directed = false) :
152  subjectGraph_(std::shared_ptr<GraphImpl>(new GraphImpl(directed))),
153  graphidToN_(),
154  graphidToE_(),
155  NToGraphid_(),
156  EToGraphid_(),
157  indexToN_(),
158  indexToE_(),
159  NToIndex_(),
160  EToIndex_()
161  {
162  getGraph()->registerObserver(this);
163  }
164 
174  AssociationGraphImplObserver(std::shared_ptr<GraphImpl> subjectGraph = 00) :
175  subjectGraph_(subjectGraph ? subjectGraph : std::shared_ptr<GraphImpl>(new GraphImpl(true))),
176  graphidToN_(),
177  graphidToE_(),
178  NToGraphid_(),
179  EToGraphid_(),
180  indexToN_(),
181  indexToE_(),
182  NToIndex_(),
183  EToIndex_()
184  {
185  getGraph()->registerObserver(this);
186  }
187 
193  template<class N2, class E2>
195  subjectGraph_(graphObserver.getGraph()),
196  graphidToN_(graphObserver.graphidToN_.size()),
197  graphidToE_(graphObserver.graphidToE_.size()),
198  NToGraphid_(),
199  EToGraphid_(),
200  indexToN_(graphObserver.indexToN_.size()),
201  indexToE_(graphObserver.indexToE_.size()),
202  NToIndex_(),
203  EToIndex_()
204  {
205  for (const auto& itN:graphObserver.NToGraphid_)
206  {
207  Nref node(AssociationGraphObserver<N, E>::template copy<N2, N>(*itN.first));
208 
209  NToGraphid_[node] = itN.second;
210  graphidToN_[itN.second] = node;
211 
212  const auto& indN = graphObserver.NToIndex_.find(itN.first);
213 
214  if (indN != graphObserver.NToIndex_.end())
215  {
216  NToIndex_[node] = indN->second;
217  indexToN_[indN->second] = node;
218  }
219  }
220 
221  for (const auto& itE:graphObserver.EToGraphid_)
222  {
223  Eref edge(AssociationGraphObserver<N, E>::template copy<E2, E>(*itE.first));
224 
225  EToGraphid_[edge] = itE.second;
226  graphidToE_[itE.second] = edge;
227 
228  const auto& indE = graphObserver.EToIndex_.find(itE.first);
229 
230  if (indE != graphObserver.EToIndex_.end())
231  {
232  EToIndex_[edge] = indE->second;
233  indexToE_[indE->second] = edge;
234  }
235  }
236 
237  getGraph()->registerObserver(this);
238  }
239 
241  subjectGraph_(graphObserver.subjectGraph_),
242  graphidToN_(graphObserver.graphidToN_.size()),
243  graphidToE_(graphObserver.graphidToE_.size()),
244  NToGraphid_(),
245  EToGraphid_(),
246  indexToN_(graphObserver.indexToN_.size()),
247  indexToE_(graphObserver.indexToE_.size()),
248  NToIndex_(),
249  EToIndex_()
250  {
251  for (const auto& itN:graphObserver.NToGraphid_)
252  {
253  Nref node(AssociationGraphObserver<N, E>::template copy<N, N>(*itN.first));
254 
255  NToGraphid_[node] = itN.second;
256  graphidToN_[itN.second] = node;
257 
258  const auto& indN = graphObserver.NToIndex_.find(itN.first);
259 
260  if (indN != graphObserver.NToIndex_.end())
261  {
262  NToIndex_[node] = indN->second;
263  indexToN_[indN->second] = node;
264  }
265  }
266 
267  for (const auto& itE:graphObserver.EToGraphid_)
268  {
269  Eref edge(AssociationGraphObserver<N, E>::template copy<E, E>(*itE.first));
270 
271  EToGraphid_[edge] = itE.second;
272  graphidToE_[itE.second] = edge;
273 
274  const auto& indE = graphObserver.EToIndex_.find(itE.first);
275 
276  if (indE != graphObserver.EToIndex_.end())
277  {
278  EToIndex_[edge] = indE->second;
279  indexToE_[indE->second] = edge;
280  }
281  }
282 
283  getGraph()->registerObserver(this);
284  }
285 
286 
292  {
293  this->graphidToN_.resize(graphObserver.graphidToN_.size());
294  this->graphidToE_.resize(graphObserver.graphidToE_.size());
295  this->indexToN_.resize(graphObserver.indexToN_.size());
296  this->indexToE_.resize(graphObserver.indexToE_.size());
297 
298  for (const auto& itN:graphObserver.NToGraphid_)
299  {
300  Nref node(AssociationGraphObserver<N, E>::template copy<N, N>(*itN.first));
301 
302  NToGraphid_[node] = itN.second;
303  graphidToN_[itN.second] = node;
304 
305  const auto& indN = graphObserver.NToIndex_.find(itN.first);
306 
307  if (indN != graphObserver.NToIndex_.end())
308  {
309  NToIndex_[node] = indN->second;
310  indexToN_[indN->second] = node;
311  }
312  }
313 
314  for (const auto& itE:graphObserver.EToGraphid_)
315  {
316  Eref edge(AssociationGraphObserver<N, E>::template copy<E, E>(*itE.first));
317 
318  EToGraphid_[edge] = itE.second;
319  graphidToE_[itE.second] = edge;
320 
321  const auto& indE = graphObserver.EToIndex_.find(itE.first);
322 
323  if (indE != graphObserver.EToIndex_.end())
324  {
325  EToIndex_[edge] = indE->second;
326  indexToE_[indE->second] = edge;
327  }
328  }
329 
330  this->subjectGraph_ = graphObserver.getGraph();
331 
332  this->getGraph()->registerObserver(this);
333 
334  return *this;
335  }
336 
337 
342  {
343  getGraph()->unregisterObserver(this);
344  }
345 
350 
351  const std::shared_ptr<GraphImpl> getGraph() const
352  {
353  return subjectGraph_;
354  }
355 
356  std::shared_ptr<GraphImpl> getGraph()
357  {
358  return subjectGraph_;
359  }
360 
361 public:
362 /*
363  *@brief Check if has node/edge
364  *
365  */
366  bool hasNode(Nref nodeObject) const
367  {
368  if (nodeObject == 0)
369  return false;
370  return NToGraphid_.find(nodeObject) != NToGraphid_.end();
371  }
372 
373  bool hasEdge(Eref edgeObject) const
374  {
375  if (edgeObject == 0)
376  return false;
377  return EToGraphid_.find(edgeObject) != EToGraphid_.end();
378  }
379 
380  /*
381  * @brief Text description of objects
382  */
383  std::string nodeToString(const Nref nodeObject) const
384  {
385  auto mess = TextTools::toString(nodeObject);
386 
387  if (!hasNode(nodeObject))
388  return mess;
389 
390  mess += ":Id=" + TextTools::toString(NToGraphid_.at(nodeObject));
391  if (hasNodeIndex(nodeObject))
392  mess += ":Index=" + TextTools::toString(getNodeIndex(nodeObject));
393 
394  return mess;
395  }
396 
397  std::string edgeToString(const Eref edgeObject) const
398  {
399  auto mess = TextTools::toString(edgeObject);
400 
401  if (!hasEdge(edgeObject))
402  return mess;
403 
404  mess += ":Id=" + TextTools::toString(EToGraphid_.at(edgeObject));
405  if (hasEdgeIndex(edgeObject))
406  mess += ":Index=" + TextTools::toString(getEdgeIndex(edgeObject));
407 
408  return mess;
409  }
410 
411 private:
416 
420  std::vector<Nref > getNeighbors_(const Nref nodeObject, neighborType type) const
421  {
422  NodeGraphid node = getNodeGraphid(nodeObject);
423 
424  // PHASE 1: getting the right neighbors
425  std::vector<NodeGraphid> neighbors;
426  switch (type)
427  {
428  case OUTGOING:
429  neighbors = getGraph()->getOutgoingNeighbors(node);
430  break;
431  case INCOMING:
432  neighbors = getGraph()->getIncomingNeighbors(node);
433  break;
434  case BOTH:
435  neighbors = getGraph()->getNeighbors(node);
436  }
437  return getNodesFromGraphid(neighbors);
438  }
439 
443  std::vector<Eref > getEdges_(const Nref nodeObject, neighborType type) const
444  {
445  NodeGraphid node = getNodeGraphid(nodeObject);
446 
447  // PHASE 1: getting the right neighbors
448  std::vector<EdgeGraphid> edges;
449  switch (type)
450  {
451  case OUTGOING:
452  edges = getGraph()->getOutgoingEdges(node);
453  break;
454  case INCOMING:
455  edges = getGraph()->getIncomingEdges(node);
456  break;
457  case BOTH:
458  edges = getGraph()->getEdges(node);
459  }
460  return getEdgesFromGraphid(edges);
461  }
462 
466  // /@{
467 
468 public:
474  void createNode(Nref nodeObject)
475  {
476  if (hasNode(nodeObject))
477  throw Exception("AssociationGraphImplObserver::createNode : node already exists: " + nodeToString(nodeObject));
478 
479  unsigned int newGraphNode = getGraph()->createNode();
480  associateNode(nodeObject, newGraphNode);
481  }
482 
491  void createNode(Nref objectOriginNode, Nref newNodeObject, Eref newEdgeObject = 00)
492  {
493  createNode(newNodeObject);
494  link(objectOriginNode, newNodeObject, newEdgeObject);
495  }
496 
497 public:
506  void link(Nref nodeObjectA, Nref nodeObjectB, Eref edgeObject = 00)
507  {
508  // checking the nodes
509  if (!hasNode(nodeObjectA))
510  throw Exception("First node is not in the graph observer: " + nodeToString(nodeObjectA));
511  if (!hasNode(nodeObjectB))
512  throw Exception("Second node is not in the graph observer:" + nodeToString(nodeObjectB));
513 
514  // checking if the edge is not already in the GraphObserver
515  if (edgeObject != 00 && hasEdge(edgeObject))
516  {
517  auto nodes = getNodes(edgeObject);
518  throw Exception("AssociationGraphImplObserver::link: The given edge is already associated to a relation in the subjectGraph: " + edgeToString(edgeObject) + ":" + nodeToString(nodes.first) + " -> " + nodeToString(nodes.second));
519  }
520 
521  EdgeGraphid newGraphEdge = getGraph()->link(NToGraphid_.at(nodeObjectA), NToGraphid_.at(nodeObjectB));
522 
523  if (graphidToE_.size() < newGraphEdge + 1)
524  graphidToE_.resize(newGraphEdge + 1);
525  graphidToE_.at(newGraphEdge) = edgeObject;
526  EToGraphid_[edgeObject] = newGraphEdge;
527  }
528 
529 
533  void unlink(Nref nodeObjectA, Nref nodeObjectB)
534  {
535  // checking the nodes
536  if (!hasNode(nodeObjectA))
537  throw Exception("First node is not in the graph observer: " + nodeToString(nodeObjectA));
538  if (!hasNode(nodeObjectB))
539  throw Exception("Second node is not in the graph observer:" + nodeToString(nodeObjectB));
540 
541  getGraph()->unlink(NToGraphid_.at(nodeObjectA), NToGraphid_.at(nodeObjectB));
542  }
543 
544 public:
549  void deleteNode(Nref nodeObject)
550  {
551  // first deleting the node in the graph
552  getGraph()->deleteNode(getNodeGraphid(nodeObject));
553  // then forgetting
554  dissociateNode(nodeObject);
555  }
556 
557 
558  // /@}
559 
563  // /@{
564 
570  void associateNode(Nref nodeObject, NodeGraphid graphNode)
571  {
572  if (hasNode(nodeObject))
573  throw Exception("AssociationGraphImplObserver::associateNode : node already exists: " + nodeToString(nodeObject));
574 
575  // nodes vector must be the right size. Eg: to store a node with
576  // the ID 3, the vector must be of size 4: {0,1,2,3} (size = 4)
577  if (graphidToN_.size() < graphNode + 1)
578  graphidToN_.resize(graphNode + 1);
579 
580  // now storing the node
581  graphidToN_.at(graphNode) = nodeObject;
582  NToGraphid_[nodeObject] = graphNode;
583  }
584 
590  void associateEdge(Eref edgeObject, EdgeGraphid graphEdge)
591  {
592  if (hasEdge(edgeObject))
593  throw Exception("AssociationGraphImplObserver::associateEdge : edge already exists: " + edgeToString(edgeObject));
594 
595  // edges vector must be the right size. Eg: to store an edge with
596  // the ID 3, the vector must be of size 4: {0,1,2,3} (size = 4)
597  if (graphidToE_.size() < graphEdge + 1)
598  graphidToE_.resize(graphEdge + 1);
599 
600  // now storing the edge
601  graphidToE_.at(graphEdge) = edgeObject;
602  EToGraphid_[edgeObject] = graphEdge;
603  }
604 
609  void dissociateNode(Nref nodeObject)
610  {
611  typename std::map<Nref, NodeGraphid>::iterator nodeToForget = NToGraphid_.find(nodeObject);
612  graphidToN_.at(nodeToForget->second) = 00;
613  NToGraphid_.erase(nodeToForget);
614  }
615 
616 
617  void dissociateEdge(Eref edgeObject)
618  {
619  typename std::map<Eref, EdgeGraphid>::iterator edgeToForget = EToGraphid_.find(edgeObject);
620  graphidToE_.at(edgeToForget->second) = 00;
621  EToGraphid_.erase(edgeToForget);
622  }
623 
624 
630  NodeGraphid getNodeGraphid(const Nref nodeObject) const
631  {
632  typename std::map<Nref, NodeGraphid>::const_iterator found = NToGraphid_.find(nodeObject);
633  if (found == NToGraphid_.end())
634  throw Exception("Unexisting node object: " + TextTools::toString(nodeObject));
635  return found->second;
636  }
637 
638 
644  EdgeGraphid getEdgeGraphid(const Eref edgeObject) const
645  {
646  typename std::map<Eref, EdgeGraphid>::const_iterator found = EToGraphid_.find(edgeObject);
647  if (found == EToGraphid_.end())
648  throw Exception("Unexisting edge object: " + TextTools::toString(edgeObject));
649  return found->second;
650  }
651 
652 
657  {
658  if (node >= graphidToN_.size())
659  return 0;
660  return graphidToN_.at(node);
661  }
662 
664  {
665  if (node >= graphidToN_.size())
666  return 0;
667  return graphidToN_.at(node);
668  }
669 
670  std::vector<Nref > getNodesFromGraphid(std::vector<NodeGraphid> nodes) const
671  {
672  std::vector<Nref > nodeObjects;
673  for (typename std::vector<NodeGraphid>::iterator currNode = nodes.begin(); currNode != nodes.end(); currNode++)
674  {
675  if (*currNode > graphidToN_.size())
676  continue;
677  Nref foundNodeObject = graphidToN_.at(*currNode);
678  if (!foundNodeObject)
679  continue;
680  nodeObjects.push_back(foundNodeObject);
681  }
682  return nodeObjects;
683  }
684 
686  {
687  if (edge >= graphidToE_.size())
688  return 0;
689 
690  return graphidToE_.at(edge);
691  }
692 
694  {
695  if (edge >= graphidToE_.size())
696  return 0;
697 
698  return graphidToE_.at(edge);
699  }
700 
701  std::vector<Eref > getEdgesFromGraphid(std::vector<EdgeGraphid> edges) const
702  {
703  std::vector<Eref > edgeObjects;
704  for (const auto& currEdge:edges)
705  {
706  if (currEdge > graphidToE_.size())
707  continue;
708  Eref foundEdgeObject = graphidToE_.at(currEdge);
709  if (!foundEdgeObject)
710  continue;
711  edgeObjects.push_back(foundEdgeObject);
712  }
713  return edgeObjects;
714  }
715 
716 
720  void setRoot(const Nref newRoot)
721  {
722  return getGraph()->setRoot(getNodeGraphid(newRoot));
723  }
724 
728  Nref getRoot() const
729  {
730  return this->getNodeFromGraphid(this->getGraph()->getRoot());
731  }
732 
733  NodeIndex getRootIndex() const
734  {
735  return this->getNodeIndex(this->getNodeFromGraphid(this->getGraph()->getRoot()));
736  }
737 
738  // /@}
739 
743  // /@{
744 
745  /*
746  * @brief Return if object has an index.
747  *
748  */
749  bool hasNodeIndex(const Nref nodeObject) const
750  {
751  return NToIndex_.find(nodeObject) != NToIndex_.end();
752  }
753 
754  bool hasEdgeIndex(const Eref edgeObject) const
755  {
756  return EToIndex_.find(edgeObject) != EToIndex_.end();
757  }
758 
764  NodeIndex getNodeIndex(const Nref nodeObject) const
765  {
766  const auto found = NToIndex_.find(nodeObject);
767  if (found == NToIndex_.end())
768  throw Exception("getNodeIndex: Node object has no index : " + nodeToString(nodeObject));
769 
770  return found->second;
771  }
772 
773  std::vector<NodeIndex> getNodeIndexes(std::vector<Nref > nodes) const
774  {
775  std::vector<NodeIndex> nodeIndexes(nodes.size());
776 
777  std::transform(nodes.begin(), nodes.end(), nodeIndexes.begin(), [this](const Nref& nodeObject){return this->getNodeIndex(nodeObject);});
778 
779  return nodeIndexes;
780  }
781 
787  EdgeIndex getEdgeIndex(const Eref edgeObject) const
788  {
789  auto found = EToIndex_.find(edgeObject);
790  if (found == EToIndex_.end())
791  throw Exception("getEdgeIndex: Edge object has no index: " + edgeToString(edgeObject));
792  return found->second;
793  }
794 
795  std::vector<EdgeIndex> getEdgeIndexes(std::vector<Eref > edges) const
796  {
797  std::vector<EdgeIndex> edgeIndexes(edges.size());
798 
799  std::transform(edges.begin(), edges.end(), edgeIndexes.begin(), [this](const Eref& edgeObject){return this->getEdgeIndex(edgeObject);});
800 
801  return edgeIndexes;
802  }
803 
810  NodeIndex setNodeIndex(const Nref nodeObject, NodeIndex index)
811  {
812  // nodes vector must be the right size. Eg: to store a node with
813  // the index 3, the vector must be of size 4: {0,1,2,3} (size = 4)
814  if (hasNode(index))
815  throw Exception("AssociationGraphImplObserver::setNodeIndex : index already exists: " + nodeToString(nodeObject));
816  if (NToIndex_.find(nodeObject) != NToIndex_.end())
817  throw Exception("AssociationGraphImplObserver::setNodeIndex : nodeObject has already an index: " + nodeToString(nodeObject));
818 
819  if (index >= indexToN_.size())
820  indexToN_.resize(index + 1);
821 
822  // now storing the node
823  indexToN_.at(index) = nodeObject;
824  NToIndex_[nodeObject] = index;
825  return index;
826  }
827 
834  EdgeIndex setEdgeIndex(const Eref edgeObject, EdgeIndex index)
835  {
836  // nodes vector must be the right size. Eg: to store an edge with
837  // the index 3, the vector must be of size 4: {0,1,2,3} (size = 4)
838  if (hasEdge(index))
839  throw Exception("AssociationGraphImplObserver::setEdgeIndex : index already exists: " + edgeToString(edgeObject));
840  if (EToIndex_.find(edgeObject) != EToIndex_.end())
841  throw Exception("AssociationGraphImplObserver::setEdgeIndex : edgeObject has already an index: " + edgeToString(edgeObject));
842 
843  if (index >= indexToE_.size())
844  indexToE_.resize(index + 1);
845 
846  // now storing the edge
847  indexToE_.at(index) = edgeObject;
848  EToIndex_[edgeObject] = index;
849  return index;
850  }
851 
857  NodeIndex addNodeIndex(const Nref nodeObject)
858  {
859  // nodes vector must be the right size. Eg: to store a node with
860  // the index 3, the vector must be of size 4: {0,1,2,3} (size = 4)
861  if (NToIndex_.find(nodeObject) != NToIndex_.end())
862  throw Exception("AssociationGraphImplObserver::addNodeIndex : nodeObject has already an index: " + nodeToString(nodeObject));
863 
864  NodeIndex index = NodeIndex(indexToN_.size());
865  for (auto i = 0; i < indexToN_.size(); i++)
866  {
867  if (!indexToN_.at(size_t(i)))
868  {
869  index = NodeIndex(i);
870  break;
871  }
872  }
873 
874  if (index >= indexToN_.size())
875  indexToN_.resize(index + 1);
876 
877  // now storing the node
878  indexToN_.at(index) = nodeObject;
879  NToIndex_[nodeObject] = index;
880  return index;
881  }
882 
888  EdgeIndex addEdgeIndex(const Eref edgeObject)
889  {
890  // nodes vector must be the right size. Eg: to store an edge with
891  // the index 3, the vector must be of size 4: {0,1,2,3} (size = 4)
892  if (EToIndex_.find(edgeObject) != EToIndex_.end())
893  throw Exception("AssociationGraphImplObserver::addEdgeIndex : edgeObject has already an index: " + edgeToString(edgeObject));
894 
895  EdgeIndex index = indexToE_.size();
896  for (auto i = 0; i < indexToE_.size(); i++)
897  {
898  if (!indexToE_.at(i))
899  {
900  index = i;
901  break;
902  }
903  }
904 
905  if (index >= indexToE_.size())
906  indexToE_.resize(index + 1);
907 
908  // now storing the edge
909  indexToE_.at(index) = edgeObject;
910  EToIndex_[edgeObject] = index;
911  return index;
912  }
913 
918  bool hasNode(NodeIndex node) const
919  {
920  return node < indexToN_.size() && indexToN_.at(node);
921  }
922 
927  bool hasEdge(EdgeIndex edge) const
928  {
929  return edge < indexToE_.size() && indexToE_.at(edge);
930  }
931 
937  Nref getNode(NodeIndex node) const
938  {
939  return indexToN_.at(node);
940  }
941 
947  Eref getEdge(EdgeIndex edge) const
948  {
949  return indexToE_.at(edge);
950  }
951 
952  // /@}
953 
957  // /@{
958 
959  /*
960  * @brief Output graph in a dot format.
961  *
962  * Nodes are labeled as "n[Index_]Id", and edge are labeled as
963  * "e[Index]_Id".
964  *
965  * Existing edge between nodes are plain, otherwise dotted.
966  *
967  * @param fname the name of the file where the DOT format will be output
968  * @param name a string naming the graph
969  *
970  */
971  void outputToDot(const std::string& fname, const std::string& name) const
972  {
973  std::ofstream out;
974  out.open(fname);
975  outputToDot(out, name);
976  out.close();
977  }
978 
979  void outputToDot(std::ostream& out, const std::string& name) const
980  {
981  out << (getGraph()->isDirected() ? "digraph" : "graph") << " " << name << " {\n ";
982  std::set<std::pair<Nref, Nref> > alreadyFigured;
983  auto allNodes = getAllNodes();
984 
985  for (const auto& node: allNodes)
986  {
987  auto children = getOutgoingNeighbors(node);
988  for (const auto& currChild : children)
989  {
990  if (alreadyFigured.find(std::pair<Nref, Nref>(node, currChild)) != alreadyFigured.end() || (getGraph()->isDirected() && alreadyFigured.find(std::pair<Nref, Nref>(currChild, node)) != alreadyFigured.end()))
991  continue;
992 
993  alreadyFigured.insert(std::pair<Nref, Nref>(node, currChild));
994 
995  out << "n";
996  if (hasNodeIndex(node))
997  out << getNodeIndex(node) << "_";
998  out << NToGraphid_.at(node);
999 
1000  out << (getGraph()->isDirected() ? " -> " : " -- ");
1001 
1002  out << "n";
1003  if (hasNodeIndex(currChild))
1004  out << getNodeIndex(currChild) << "_";
1005  out << NToGraphid_.at(currChild);
1006 
1007  auto edge = getEdgeLinking(node, currChild);
1008  if (!edge)
1009  out << " [style = dotted]";
1010  else
1011  {
1012  out << " [label = e";
1013  if (hasEdgeIndex(edge))
1014  out << getEdgeIndex(edge) << "_";
1015  out << EToGraphid_.at(edge) << "]";
1016  }
1017  out << ";\n ";
1018  }
1019  }
1020  out << "}";
1021  }
1022 
1028  template<class GraphIterator, bool is_const>
1030  virtual public AssociationGraphObserver<N, E>::NodeIterator
1031  {
1032 private:
1035 
1036 public:
1038  agio_(agio) { start(); }
1039 
1041  agio_(agio) { start(); }
1042 
1043  NodeIteratorClass<GraphIterator, is_const>(AssociationGraphImplObserver<N, E, GraphImpl>& agio, Nref n) : it_(*agio.getGraph(), agio.getNodeGraphid(n)),
1044  agio_(agio) {start(); }
1045 
1046  NodeIteratorClass<GraphIterator, is_const>(const AssociationGraphImplObserver<N, E, GraphImpl>& agio, Nref n) : it_(*agio.getGraph(), agio.getNodeGraphid(n)),
1047  agio_(agio) {start(); }
1048 
1049  ~NodeIteratorClass<GraphIterator, is_const>() {}
1050 
1051  void next() {it_.next(); while (!it_.end() && agio_.getNodeFromGraphid(*it_) == 0) it_.next(); }
1052 
1053  bool end() const {return it_.end(); }
1054 
1055  void start() { it_.start(); while (!it_.end() && (agio_.getNodeFromGraphid(*it_) == 0)) it_.next(); }
1056 
1057  Nref operator*() {return agio_.getNodeFromGraphid(*it_); }
1058  };
1059 
1060 
1061  std::unique_ptr<typename AssociationGraphObserver<N, E>::NodeIterator> allNodesIterator()
1062  {
1063  return std::unique_ptr<AssociationGraphImplObserver<N, E, GraphImpl>::NodeIteratorClass<Graph::ALLGRAPHITER, false> >(new AssociationGraphImplObserver<N, E, GraphImpl>::NodeIteratorClass<Graph::ALLGRAPHITER, false>(*this));
1064  }
1065 
1066  std::unique_ptr<typename AssociationGraphObserver<N, E>::NodeIterator> allNodesIterator() const
1067  {
1068  return std::unique_ptr<AssociationGraphImplObserver<N, E, GraphImpl>::NodeIteratorClass<Graph::ALLGRAPHITER, true> >(new AssociationGraphImplObserver<N, E, GraphImpl>::NodeIteratorClass<Graph::ALLGRAPHITER, true>(*this));
1069  }
1070 
1071 
1072  /*
1073  * @brief builds iterator on the neighbor nodes of a Node
1074  *
1075  */
1076  std::unique_ptr<typename AssociationGraphObserver<N, E>::NodeIterator> outgoingNeighborNodesIterator(Nref node)
1077  {
1078  return std::unique_ptr<AssociationGraphImplObserver<N, E, GraphImpl>::NodeIteratorClass<Graph::OUTGOINGNEIGHBORITER, false> >(new AssociationGraphImplObserver<N, E, GraphImpl>::NodeIteratorClass<Graph::OUTGOINGNEIGHBORITER, false>(*this, node));
1079  }
1080 
1081  std::unique_ptr<typename AssociationGraphObserver<N, E>::NodeIterator> outgoingNeighborNodesIterator(Nref node) const
1082  {
1083  return std::unique_ptr<AssociationGraphImplObserver<N, E, GraphImpl>::NodeIteratorClass<Graph::OUTGOINGNEIGHBORITER, true> >(new AssociationGraphImplObserver<N, E, GraphImpl>::NodeIteratorClass<Graph::OUTGOINGNEIGHBORITER, true>(*this, node));
1084  }
1085 
1086 
1087  /*
1088  * @brief builds iterator on the neighbor nodes of a Node
1089  *
1090  */
1091  std::unique_ptr<typename AssociationGraphObserver<N, E>::NodeIterator> incomingNeighborNodesIterator(Nref node)
1092  {
1093  return std::unique_ptr<AssociationGraphImplObserver<N, E, GraphImpl>::NodeIteratorClass<Graph::INCOMINGNEIGHBORITER, false> >(new AssociationGraphImplObserver<N, E, GraphImpl>::NodeIteratorClass<Graph::INCOMINGNEIGHBORITER, false>(*this, node));
1094  }
1095 
1096  std::unique_ptr<typename AssociationGraphObserver<N, E>::NodeIterator> incomingNeighborNodesIterator(Nref node) const
1097  {
1098  return std::unique_ptr<AssociationGraphImplObserver<N, E, GraphImpl>::NodeIteratorClass<Graph::INCOMINGNEIGHBORITER, true> >(new AssociationGraphImplObserver<N, E, GraphImpl>::NodeIteratorClass<Graph::INCOMINGNEIGHBORITER, true>(*this, node));
1099  }
1100 
1101 
1109  std::vector<Nref > getNeighbors(const Nref node) const
1110  {
1112  }
1113 
1121  std::vector<NodeIndex> getNeighbors(NodeIndex node) const
1122  {
1123  return getNodeIndexes(getNeighbors(getNode(node)));
1124  }
1125 
1132  std::vector<Eref > getEdges(const Nref node) const
1133  {
1135  }
1136 
1137  std::vector<EdgeIndex> getEdges(NodeIndex node) const
1138  {
1139  return getEdgeIndexes(getEdges(getNode(node)));
1140  }
1141 
1142 
1149  std::vector<Nref > getOutgoingNeighbors(const Nref node) const
1150  {
1152  }
1153 
1154  std::vector<NodeIndex> getOutgoingNeighbors(NodeIndex node) const
1155  {
1157  }
1158 
1165  std::vector<Eref > getOutgoingEdges(const Nref node) const
1166  {
1168  }
1169 
1170  std::vector<EdgeIndex> getOutgoingEdges(NodeIndex node) const
1171  {
1172  return getEdgeIndexes(getOutgoingEdges(getNode(node)));
1173  }
1174 
1181  std::vector<Nref > getIncomingNeighbors(const Nref node) const
1182  {
1184  }
1185 
1186  std::vector<NodeIndex> getIncomingNeighbors(NodeIndex node) const
1187  {
1189  }
1190 
1191 
1198  std::vector<Eref > getIncomingEdges(const Nref node) const
1199  {
1201  }
1202 
1203  std::vector<EdgeIndex> getIncomingEdges(NodeIndex node) const
1204  {
1205  return getEdgeIndexes(getIncomingEdges(getNode(node)));
1206  }
1207 
1218  std::vector<Nref > getLeavesFromNode(Nref node, unsigned int maxDepth) const
1219  {
1220  return getNodesFromGraphid(getGraph()->getLeavesFromNode(getNodeGraphid(node), maxDepth));
1221  }
1222 
1229  std::vector<Nref > getAllLeaves() const
1230  {
1231  std::vector<Nref > leavesToReturn;
1232  // fetching all the graph Leaves
1233  std::vector<NodeGraphid> graphLeaves = getGraph()->getAllLeaves();
1234  // testing if they are defined in this observer
1235  for (typename std::vector<NodeGraphid>::iterator currGraphLeave = graphLeaves.begin(); currGraphLeave != graphLeaves.end(); currGraphLeave++)
1236  {
1237  Nref foundLeafObject = graphidToN_.at(*currGraphLeave);
1238  if (foundLeafObject != 00)
1239  leavesToReturn.push_back(foundLeafObject);
1240  }
1241  return leavesToReturn;
1242  }
1243 
1250  std::vector<NodeIndex> getAllLeavesIndexes() const
1251  {
1252  std::vector<NodeIndex> leavesToReturn;
1253 
1254  // fetching all the graph Leaves
1255  std::vector<NodeGraphid> graphLeaves = getGraph()->getAllLeaves();
1256  // testing if they are defined in this observer
1257  for (typename std::vector<NodeGraphid>::iterator currGraphLeave = graphLeaves.begin(); currGraphLeave != graphLeaves.end(); currGraphLeave++)
1258  {
1259  Nref foundLeafObject = graphidToN_.at(*currGraphLeave);
1260  if (foundLeafObject != 00)
1261  leavesToReturn.push_back(getNodeIndex(foundLeafObject));
1262  }
1263  return leavesToReturn;
1264  }
1265 
1272  std::vector<Nref > getAllInnerNodes() const
1273  {
1274  std::vector<Nref > nodesToReturn;
1275  // fetching all the graph Leaves
1276  std::vector<NodeGraphid> graphNodes = getGraph()->getAllInnerNodes();
1277  // testing if they are defined in this observer
1278  for (const auto& currGraphNode : graphNodes)
1279  {
1280  Nref foundNodeObject = graphidToN_.at(currGraphNode);
1281  if (foundNodeObject != 00)
1282  nodesToReturn.push_back(foundNodeObject);
1283  }
1284  return nodesToReturn;
1285  }
1286 
1293  std::vector<NodeIndex> getAllInnerNodesIndexes() const
1294  {
1295  std::vector<NodeIndex> nodesToReturn;
1296  // fetching all the graph Leaves
1297  std::vector<NodeGraphid> graphNodes = getGraph()->getAllInnerNodes();
1298  // testing if they are defined in this observer
1299  for (const auto& currGraphNode : graphNodes)
1300  {
1301  Nref foundNodeObject = graphidToN_.at(currGraphNode);
1302  if (foundNodeObject != 00)
1303  nodesToReturn.push_back(getNodeIndex(foundNodeObject));
1304  }
1305  return nodesToReturn;
1306  }
1307 
1314  std::vector<Nref > getAllNodes() const
1315  {
1316  std::vector<Nref > nodesToReturn;
1317  for (typename std::vector<Nref >::const_iterator currNodeObject = graphidToN_.begin(); currNodeObject != graphidToN_.end(); currNodeObject++)
1318  {
1319  if (*currNodeObject != 00)
1320  {
1321  nodesToReturn.push_back(*currNodeObject);
1322  }
1323  }
1324  return nodesToReturn;
1325  }
1326 
1333  std::vector<NodeIndex> getAllNodesIndexes() const
1334  {
1335  std::vector<NodeIndex> indexesToReturn;
1336  for (const auto& currNodeObject : graphidToN_)
1337  {
1338  if (currNodeObject != 00)
1339  {
1340  indexesToReturn.push_back(getNodeIndex(currNodeObject));
1341  }
1342  }
1343  return indexesToReturn;
1344  }
1345 
1352  std::vector<EdgeIndex> getAllEdgesIndexes() const
1353  {
1354  std::vector<typename AssociationGraphObserver<N, E>::EdgeIndex > indexesToReturn;
1355  for (typename std::vector<Eref >::const_iterator currEdgeObject = graphidToE_.begin(); currEdgeObject != graphidToE_.end(); currEdgeObject++)
1356  {
1357  if (*currEdgeObject != 00)
1358  {
1359  indexesToReturn.push_back(getEdgeIndex(*currEdgeObject));
1360  }
1361  }
1362  return indexesToReturn;
1363  }
1364 
1365 
1366  template<class GraphIterator, bool is_const>
1369  {
1370 private:
1373 
1374 public:
1376  agio_(agio) { start(); }
1377 
1379  agio_(agio) { start(); }
1380 
1381  EdgeIteratorClass<GraphIterator, is_const>(const AssociationGraphImplObserver<N, E, GraphImpl>& agio) : it_(*agio.getGraph()),
1382  agio_(agio) { start(); }
1383 
1384  EdgeIteratorClass<GraphIterator, is_const>(const AssociationGraphImplObserver<N, E, GraphImpl>& agio, Nref n) : it_(*agio.getGraph(), agio.getNodeGraphid(n)),
1385  agio_(agio) { start(); }
1386 
1387  ~EdgeIteratorClass<GraphIterator, is_const>() {}
1388 
1389  void next() {it_.next(); while (!it_.end() && (agio_.getEdgeFromGraphid(*it_) == 0)) it_.next(); }
1390 
1391  bool end() const {return it_.end(); }
1392 
1393  void start() { it_.start(); while (!it_.end() && (agio_.getEdgeFromGraphid(*it_) == 0)) it_.next(); }
1394 
1395  Eref operator*() {return agio_.getEdgeFromGraphid(*it_); }
1396  };
1397 
1398 
1399  std::unique_ptr<typename AssociationGraphObserver<N, E>::EdgeIterator> allEdgesIterator()
1400  {
1401  return std::unique_ptr<AssociationGraphImplObserver<N, E, GraphImpl>::EdgeIteratorClass<Graph::ALLGRAPHITER, false> >(new AssociationGraphImplObserver<N, E, GraphImpl>::EdgeIteratorClass<Graph::ALLGRAPHITER, false>(*this));
1402  }
1403 
1404  std::unique_ptr<typename AssociationGraphObserver<N, E>::EdgeIterator> allEdgesIterator() const
1405  {
1406  return std::unique_ptr<AssociationGraphImplObserver<N, E, GraphImpl>::EdgeIteratorClass<Graph::ALLGRAPHITER, true> >(new AssociationGraphImplObserver<N, E, GraphImpl>::EdgeIteratorClass<Graph::ALLGRAPHITER, true>(*this));
1407  }
1408 
1409  /*
1410  * @brief builds iterator on the outgoing neighbor nodes of a Edge
1411  *
1412  */
1413  std::unique_ptr<typename AssociationGraphObserver<N, E>::EdgeIterator> outgoingEdgesIterator(Nref node)
1414  {
1415  return std::unique_ptr<AssociationGraphImplObserver<N, E, GraphImpl>::EdgeIteratorClass<Graph::OUTGOINGNEIGHBORITER, false> >(new AssociationGraphImplObserver<N, E, GraphImpl>::EdgeIteratorClass<Graph::OUTGOINGNEIGHBORITER, false>(*this, node));
1416  }
1417 
1418  std::unique_ptr<typename AssociationGraphObserver<N, E>::EdgeIterator> outgoingEdgesIterator(Nref node) const
1419  {
1420  return std::unique_ptr<AssociationGraphImplObserver<N, E, GraphImpl>::EdgeIteratorClass<Graph::OUTGOINGNEIGHBORITER, true> >(new AssociationGraphImplObserver<N, E, GraphImpl>::EdgeIteratorClass<Graph::OUTGOINGNEIGHBORITER, true>(*this, node));
1421  }
1422 
1423  /*
1424  * @brief builds iterator on the incoming neighbor nodes of a Edge
1425  *
1426  */
1427  std::unique_ptr<typename AssociationGraphObserver<N, E>::EdgeIterator> incomingEdgesIterator(Nref node)
1428  {
1429  return std::unique_ptr<AssociationGraphImplObserver<N, E, GraphImpl>::EdgeIteratorClass<Graph::INCOMINGNEIGHBORITER, false> >(new AssociationGraphImplObserver<N, E, GraphImpl>::EdgeIteratorClass<Graph::INCOMINGNEIGHBORITER, false>(*this, node));
1430  }
1431 
1432  std::unique_ptr<typename AssociationGraphObserver<N, E>::EdgeIterator> incomingEdgesIterator(Nref node) const
1433  {
1434  return std::unique_ptr<AssociationGraphImplObserver<N, E, GraphImpl>::EdgeIteratorClass<Graph::INCOMINGNEIGHBORITER, true> >(new AssociationGraphImplObserver<N, E, GraphImpl>::EdgeIteratorClass<Graph::INCOMINGNEIGHBORITER, true>(*this, node));
1435  }
1436 
1441  std::vector<Eref > getAllEdges() const
1442  {
1443  std::vector<Eref > branchesToReturn;
1444  for (typename std::vector<Eref >::const_iterator currBrObject = graphidToE_.begin(); currBrObject != graphidToE_.end(); currBrObject++)
1445  {
1446  if (*currBrObject != 00)
1447  {
1448  branchesToReturn.push_back(*currBrObject);
1449  }
1450  }
1451  return branchesToReturn;
1452  }
1453 
1457  bool isLeaf(const Nref node) const
1458  {
1459  return getGraph()->isLeaf(this->getNodeGraphid(node));
1460  }
1461 
1462  bool isLeaf(const NodeIndex nodeid) const
1463  {
1464  return getGraph()->isLeaf(this->getNodeGraphid(getNode(nodeid)));
1465  }
1466 
1473  std::pair<Nref, Nref> getNodes(Eref edge) const
1474  {
1475  std::pair<NodeGraphid, NodeGraphid> nodes = getGraph()->getNodes(getEdgeGraphid(edge));
1476  return std::pair<Nref, Nref >(getNodeFromGraphid(nodes.first), getNodeFromGraphid(nodes.second));
1477  }
1478 
1485  Eref getEdgeLinking(Nref nodeA, Nref nodeB) const
1486  {
1488  }
1489 
1496  void setEdgeLinking(Nref nodeA, Nref nodeB, Eref edge)
1497  {
1498  associateEdge(edge, getGraph()->getEdge(getNodeGraphid(nodeA), getNodeGraphid(nodeB)));
1499  }
1500 
1501  // /@}
1502 
1503 
1507  // /@{
1508 
1513  void deletedEdgesUpdate(const std::vector< unsigned int >& edgesToDelete)
1514  {
1515  for (typename std::vector<EdgeGraphid>::const_iterator currEdge = edgesToDelete.begin(); currEdge != edgesToDelete.end(); currEdge++)
1516  {
1517  if (graphidToE_.size() > *currEdge)
1518  {
1519  Eref edgeObject = graphidToE_.at(*currEdge);
1520  graphidToE_.at(*currEdge) = 00;
1521 
1522  EToGraphid_.erase(edgeObject);
1523  }
1524  }
1525  }
1526 
1531  void deletedNodesUpdate(const std::vector< unsigned int >& nodesToDelete)
1532  {
1533  for (typename std::vector<EdgeGraphid>::const_iterator currNode = nodesToDelete.begin(); currNode != nodesToDelete.end(); currNode++)
1534  {
1535  if (graphidToN_.size() > *currNode)
1536  {
1537  Nref nodeObject = graphidToN_.at(*currNode);
1538  graphidToN_.at(*currNode) = 00;
1539 
1540  NToGraphid_.erase(nodeObject);
1541  }
1542  }
1543  }
1544 
1545  // /@}
1546 
1550  // /@{
1551 
1557  size_t getNumberOfNodes() const
1558  {
1559  return NToGraphid_.size();
1560  }
1561 
1567  size_t getNumberOfEdges() const
1568  {
1569  return EToGraphid_.size();
1570  }
1571 
1572 
1578  size_t getNumberOfLeaves() const
1579  {
1580  size_t nb = 0;
1581  for (typename std::vector<Nref >::const_iterator currNodeObject = graphidToN_.begin(); currNodeObject != graphidToN_.end(); currNodeObject++)
1582  {
1583  if ((*currNodeObject != 00) && (isLeaf(*currNodeObject)))
1584  nb++;
1585  }
1586 
1587  return nb;
1588  }
1589 
1595  size_t getDegree(const Nref node) const
1596  {
1597  return getGraph()->getDegree(getNodeGraphid(node));
1598  }
1599 
1600  // /@}
1601 
1602  template<typename N2, typename E2, typename G2> friend class AssociationGraphImplObserver;
1603 };
1604 
1605 /***************/
1606 
1607 template<class N, class E>
1609 }
1610 #endif // BPP_GRAPH_ASSOCIATIONGRAPHIMPLOBSERVER_H
const AssociationGraphImplObserver< N, E, GraphImpl > & agio_
const AssociationGraphImplObserver< N, E, GraphImpl > & agio_
const Eref getEdgeFromGraphid(EdgeGraphid edge) const
void link(Nref nodeObjectA, Nref nodeObjectB, Eref edgeObject=00)
const Nref getNodeFromGraphid(NodeGraphid node) const
const std::shared_ptr< GraphImpl > getGraph() const
std::vector< Nref > getNeighbors(const Nref node) const
std::vector< Nref > getOutgoingNeighbors(const Nref node) const
EdgeIndex setEdgeIndex(const Eref edgeObject, EdgeIndex index)
EdgeIndex addEdgeIndex(const Eref edgeObject)
void deletedEdgesUpdate(const std::vector< unsigned int > &edgesToDelete)
bool hasNodeIndex(const Nref nodeObject) const
return if the object has an index.
std::vector< EdgeIndex > getIncomingEdges(NodeIndex node) const
bool hasEdgeIndex(const Eref edgeObject) const
std::vector< Nref > getIncomingNeighbors(const Nref node) const
bool isLeaf(const Nref node) const
Is the node a leaf?
std::vector< EdgeIndex > getOutgoingEdges(NodeIndex node) const
std::vector< Eref > getEdges(const Nref node) const
EdgeGraphid getEdgeGraphid(const Eref edgeObject) const
std::unique_ptr< typename AssociationGraphObserver< N, E >::EdgeIterator > allEdgesIterator() const
AssociationGraphImplObserver(AssociationGraphImplObserver< N, E, GraphImpl > const &graphObserver)
std::vector< NodeIndex > getAllNodesIndexes() const
void associateNode(Nref nodeObject, NodeGraphid graphNode)
std::vector< NodeIndex > getNeighbors(NodeIndex node) const
std::unique_ptr< typename AssociationGraphObserver< N, E >::EdgeIterator > incomingEdgesIterator(Nref node) const
NodeIndex addNodeIndex(const Nref nodeObject)
std::vector< EdgeIndex > getEdgeIndexes(std::vector< Eref > edges) const
std::vector< NodeIndex > getAllLeavesIndexes() const
AssociationGraphImplObserver(AssociationGraphImplObserver< N2, E2, GraphImpl > const &graphObserver)
void createNode(Nref objectOriginNode, Nref newNodeObject, Eref newEdgeObject=00)
AssociationGraphImplObserver< N, E, GraphImpl > * clone() const
std::vector< Eref > getEdges_(const Nref nodeObject, neighborType type) const
std::unique_ptr< typename AssociationGraphObserver< N, E >::EdgeIterator > allEdgesIterator()
std::vector< EdgeIndex > getAllEdgesIndexes() const
std::vector< Eref > getOutgoingEdges(const Nref node) const
std::unique_ptr< typename AssociationGraphObserver< N, E >::NodeIterator > outgoingNeighborNodesIterator(Nref node)
AssociationGraphObserver< N, E >::EdgeIndex EdgeIndex
std::unique_ptr< typename AssociationGraphObserver< N, E >::EdgeIterator > incomingEdgesIterator(Nref node)
std::unique_ptr< typename AssociationGraphObserver< N, E >::NodeIterator > incomingNeighborNodesIterator(Nref node)
std::vector< NodeIndex > getOutgoingNeighbors(NodeIndex node) const
NodeIndex setNodeIndex(const Nref nodeObject, NodeIndex index)
std::vector< Nref > getNeighbors_(const Nref nodeObject, neighborType type) const
std::unique_ptr< typename AssociationGraphObserver< N, E >::NodeIterator > allNodesIterator() const
void outputToDot(const std::string &fname, const std::string &name) const
void unlink(Nref nodeObjectA, Nref nodeObjectB)
std::vector< Eref > getEdgesFromGraphid(std::vector< EdgeGraphid > edges) const
std::vector< NodeIndex > getAllInnerNodesIndexes() const
std::vector< NodeIndex > getNodeIndexes(std::vector< Nref > nodes) const
std::vector< NodeIndex > getIncomingNeighbors(NodeIndex node) const
std::pair< Nref, Nref > getNodes(Eref edge) const
std::shared_ptr< GraphImpl > subjectGraph_
std::unique_ptr< typename AssociationGraphObserver< N, E >::NodeIterator > incomingNeighborNodesIterator(Nref node) const
std::unique_ptr< typename AssociationGraphObserver< N, E >::NodeIterator > outgoingNeighborNodesIterator(Nref node) const
void associateEdge(Eref edgeObject, EdgeGraphid graphEdge)
Eref getEdgeLinking(Nref nodeA, Nref nodeB) const
std::vector< EdgeIndex > getEdges(NodeIndex node) const
void deletedNodesUpdate(const std::vector< unsigned int > &nodesToDelete)
std::vector< Nref > getNodesFromGraphid(std::vector< NodeGraphid > nodes) const
std::vector< Eref > getIncomingEdges(const Nref node) const
std::unique_ptr< typename AssociationGraphObserver< N, E >::NodeIterator > allNodesIterator()
std::unique_ptr< typename AssociationGraphObserver< N, E >::EdgeIterator > outgoingEdgesIterator(Nref node)
void setEdgeLinking(Nref nodeA, Nref nodeB, Eref edge)
AssociationGraphObserver< N, E >::NodeIndex NodeIndex
std::unique_ptr< typename AssociationGraphObserver< N, E >::EdgeIterator > outgoingEdgesIterator(Nref node) const
NodeIndex getNodeIndex(const Nref nodeObject) const
AssociationGraphImplObserver< N, E, GraphImpl > & operator=(bpp::AssociationGraphImplObserver< N, E, GraphImpl > const &graphObserver)
AssociationGraphImplObserver(std::shared_ptr< GraphImpl > subjectGraph=00)
Constructor.
void outputToDot(std::ostream &out, const std::string &name) const
std::string nodeToString(const Nref nodeObject) const
std::vector< Nref > getLeavesFromNode(Nref node, unsigned int maxDepth) const
EdgeIndex getEdgeIndex(const Eref edgeObject) const
std::string edgeToString(const Eref edgeObject) const
bool isLeaf(const NodeIndex nodeid) const
void setRoot(const Nref newRoot)
set the root (but no checking, to be used at first construction)
NodeGraphid getNodeGraphid(const Nref nodeObject) const
Defines a Graph Associator. It is a template which follows (subscribed to) a Graph.
Exception base class. Overload exception constructor (to control the exceptions mechanism)....
Definition: Exceptions.h:59
virtual void next()=0
virtual void start()=0
virtual bool end() const =0
virtual void next()=0
virtual void start()=0
virtual bool end() const =0
unsigned int NodeId
Definition: Graph.h:66
unsigned int EdgeId
Definition: Graph.h:67
std::string toString(T t)
General template method to convert to a string.
Definition: TextTools.h:153
define categories of iterators
Definition: Graph.h:239