bpp-core3  3.0.0
AssociationGraphImplObserver.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_ASSOCIATIONGRAPHIMPLOBSERVER_H
6 #define BPP_GRAPH_ASSOCIATIONGRAPHIMPLOBSERVER_H
7 
8 #include <algorithm>
9 #include <fstream>
10 #include <iostream>
11 #include <map>
12 #include <memory>
13 #include <ostream>
14 #include <type_traits>
15 #include <vector>
16 
17 #include "../Clonable.h"
18 #include "../Exceptions.h"
19 #include "../Text/TextTools.h"
21 #include "GlobalGraph.h"
22 
23 namespace bpp
24 {
25 template<class N, class E, class GraphImpl>
27 {
28 public:
31 
34 
35  using Eref = std::shared_ptr<E>;
36  using Nref = std::shared_ptr<N>;
37 
38 protected:
44  std::shared_ptr<GraphImpl> subjectGraph_;
45 
46 private:
57  std::vector<Nref > graphidToN_;
58 
63  std::vector<Eref > graphidToE_;
64 
68  std::map<Nref, NodeGraphid> NToGraphid_;
69 
73  std::map<Eref, EdgeGraphid> EToGraphid_;
74 
75  /*
76  * @}
77  */
78 
88  std::vector<Nref > indexToN_;
89 
93  std::vector<Eref > indexToE_;
94 
98  std::map<Nref, NodeIndex> NToIndex_;
99 
103  std::map<Eref, EdgeIndex> EToIndex_;
104 
105  /*
106  * @}
107  */
108 
109 public:
115  AssociationGraphImplObserver(bool directed = false) :
116  subjectGraph_(std::shared_ptr<GraphImpl>(new GraphImpl(directed))),
117  graphidToN_(),
118  graphidToE_(),
119  NToGraphid_(),
120  EToGraphid_(),
121  indexToN_(),
122  indexToE_(),
123  NToIndex_(),
124  EToIndex_()
125  {
126  getGraph()->registerObserver(this);
127  }
128 
138  AssociationGraphImplObserver(std::shared_ptr<GraphImpl> subjectGraph = 00) :
139  subjectGraph_(subjectGraph ? subjectGraph : std::shared_ptr<GraphImpl>(new GraphImpl(true))),
140  graphidToN_(),
141  graphidToE_(),
142  NToGraphid_(),
143  EToGraphid_(),
144  indexToN_(),
145  indexToE_(),
146  NToIndex_(),
147  EToIndex_()
148  {
149  getGraph()->registerObserver(this);
150  }
151 
157  template<class N2, class E2>
159  subjectGraph_(graphObserver.getGraph()),
160  graphidToN_(graphObserver.graphidToN_.size()),
161  graphidToE_(graphObserver.graphidToE_.size()),
162  NToGraphid_(),
163  EToGraphid_(),
164  indexToN_(graphObserver.indexToN_.size()),
165  indexToE_(graphObserver.indexToE_.size()),
166  NToIndex_(),
167  EToIndex_()
168  {
169  for (const auto& itN:graphObserver.NToGraphid_)
170  {
171  Nref node(AssociationGraphObserver<N, E>::template copy<N2, N>(*itN.first));
172 
173  NToGraphid_[node] = itN.second;
174  graphidToN_[itN.second] = node;
175 
176  const auto& indN = graphObserver.NToIndex_.find(itN.first);
177 
178  if (indN != graphObserver.NToIndex_.end())
179  {
180  NToIndex_[node] = indN->second;
181  indexToN_[indN->second] = node;
182  }
183  }
184 
185  for (const auto& itE:graphObserver.EToGraphid_)
186  {
187  Eref edge(AssociationGraphObserver<N, E>::template copy<E2, E>(*itE.first));
188 
189  EToGraphid_[edge] = itE.second;
190  graphidToE_[itE.second] = edge;
191 
192  const auto& indE = graphObserver.EToIndex_.find(itE.first);
193 
194  if (indE != graphObserver.EToIndex_.end())
195  {
196  EToIndex_[edge] = indE->second;
197  indexToE_[indE->second] = edge;
198  }
199  }
200 
201  getGraph()->registerObserver(this);
202  }
203 
205  subjectGraph_(graphObserver.subjectGraph_),
206  graphidToN_(graphObserver.graphidToN_.size()),
207  graphidToE_(graphObserver.graphidToE_.size()),
208  NToGraphid_(),
209  EToGraphid_(),
210  indexToN_(graphObserver.indexToN_.size()),
211  indexToE_(graphObserver.indexToE_.size()),
212  NToIndex_(),
213  EToIndex_()
214  {
215  for (const auto& itN:graphObserver.NToGraphid_)
216  {
217  Nref node(AssociationGraphObserver<N, E>::template copy<N, N>(*itN.first));
218 
219  NToGraphid_[node] = itN.second;
220  graphidToN_[itN.second] = node;
221 
222  const auto& indN = graphObserver.NToIndex_.find(itN.first);
223 
224  if (indN != graphObserver.NToIndex_.end())
225  {
226  NToIndex_[node] = indN->second;
227  indexToN_[indN->second] = node;
228  }
229  }
230 
231  for (const auto& itE:graphObserver.EToGraphid_)
232  {
233  Eref edge(AssociationGraphObserver<N, E>::template copy<E, E>(*itE.first));
234 
235  EToGraphid_[edge] = itE.second;
236  graphidToE_[itE.second] = edge;
237 
238  const auto& indE = graphObserver.EToIndex_.find(itE.first);
239 
240  if (indE != graphObserver.EToIndex_.end())
241  {
242  EToIndex_[edge] = indE->second;
243  indexToE_[indE->second] = edge;
244  }
245  }
246 
247  getGraph()->registerObserver(this);
248  }
249 
250 
256  {
257  this->graphidToN_.resize(graphObserver.graphidToN_.size());
258  this->graphidToE_.resize(graphObserver.graphidToE_.size());
259  this->indexToN_.resize(graphObserver.indexToN_.size());
260  this->indexToE_.resize(graphObserver.indexToE_.size());
261 
262  for (const auto& itN:graphObserver.NToGraphid_)
263  {
264  Nref node(AssociationGraphObserver<N, E>::template copy<N, N>(*itN.first));
265 
266  NToGraphid_[node] = itN.second;
267  graphidToN_[itN.second] = node;
268 
269  const auto& indN = graphObserver.NToIndex_.find(itN.first);
270 
271  if (indN != graphObserver.NToIndex_.end())
272  {
273  NToIndex_[node] = indN->second;
274  indexToN_[indN->second] = node;
275  }
276  }
277 
278  for (const auto& itE:graphObserver.EToGraphid_)
279  {
280  Eref edge(AssociationGraphObserver<N, E>::template copy<E, E>(*itE.first));
281 
282  EToGraphid_[edge] = itE.second;
283  graphidToE_[itE.second] = edge;
284 
285  const auto& indE = graphObserver.EToIndex_.find(itE.first);
286 
287  if (indE != graphObserver.EToIndex_.end())
288  {
289  EToIndex_[edge] = indE->second;
290  indexToE_[indE->second] = edge;
291  }
292  }
293 
294  this->subjectGraph_ = graphObserver.getGraph();
295 
296  this->getGraph()->registerObserver(this);
297 
298  return *this;
299  }
300 
301 
306  {
307  getGraph()->unregisterObserver(this);
308  }
309 
314 
315  const std::shared_ptr<GraphImpl> getGraph() const
316  {
317  return subjectGraph_;
318  }
319 
320  std::shared_ptr<GraphImpl> getGraph()
321  {
322  return subjectGraph_;
323  }
324 
325 public:
326 /*
327  *@brief Check if has node/edge
328  *
329  */
330  bool hasNode(Nref nodeObject) const
331  {
332  if (nodeObject == 0)
333  return false;
334  return NToGraphid_.find(nodeObject) != NToGraphid_.end();
335  }
336 
337  bool hasEdge(Eref edgeObject) const
338  {
339  if (edgeObject == 0)
340  return false;
341  return EToGraphid_.find(edgeObject) != EToGraphid_.end();
342  }
343 
344  /*
345  * @brief Text description of objects
346  */
347  std::string nodeToString(const Nref nodeObject) const
348  {
349  auto mess = TextTools::toString(nodeObject);
350 
351  if (!hasNode(nodeObject))
352  return mess;
353 
354  mess += ":Id=" + TextTools::toString(NToGraphid_.at(nodeObject));
355  if (hasNodeIndex(nodeObject))
356  mess += ":Index=" + TextTools::toString(getNodeIndex(nodeObject));
357 
358  return mess;
359  }
360 
361  std::string edgeToString(const Eref edgeObject) const
362  {
363  auto mess = TextTools::toString(edgeObject);
364 
365  if (!hasEdge(edgeObject))
366  return mess;
367 
368  mess += ":Id=" + TextTools::toString(EToGraphid_.at(edgeObject));
369  if (hasEdgeIndex(edgeObject))
370  mess += ":Index=" + TextTools::toString(getEdgeIndex(edgeObject));
371 
372  return mess;
373  }
374 
375 private:
380 
384  std::vector<Nref > getNeighbors_(const Nref nodeObject, neighborType type) const
385  {
386  NodeGraphid node = getNodeGraphid(nodeObject);
387 
388  // PHASE 1: getting the right neighbors
389  std::vector<NodeGraphid> neighbors;
390  switch (type)
391  {
392  case OUTGOING:
393  neighbors = getGraph()->getOutgoingNeighbors(node);
394  break;
395  case INCOMING:
396  neighbors = getGraph()->getIncomingNeighbors(node);
397  break;
398  case BOTH:
399  neighbors = getGraph()->getNeighbors(node);
400  }
401  return getNodesFromGraphid(neighbors);
402  }
403 
407  std::vector<Eref > getEdges_(const Nref nodeObject, neighborType type) const
408  {
409  NodeGraphid node = getNodeGraphid(nodeObject);
410 
411  // PHASE 1: getting the right neighbors
412  std::vector<EdgeGraphid> edges;
413  switch (type)
414  {
415  case OUTGOING:
416  edges = getGraph()->getOutgoingEdges(node);
417  break;
418  case INCOMING:
419  edges = getGraph()->getIncomingEdges(node);
420  break;
421  case BOTH:
422  edges = getGraph()->getEdges(node);
423  }
424  return getEdgesFromGraphid(edges);
425  }
426 
430  // /@{
431 
432 public:
438  void createNode(Nref nodeObject)
439  {
440  if (hasNode(nodeObject))
441  throw Exception("AssociationGraphImplObserver::createNode : node already exists: " + nodeToString(nodeObject));
442 
443  unsigned int newGraphNode = getGraph()->createNode();
444  associateNode(nodeObject, newGraphNode);
445  }
446 
455  void createNode(Nref objectOriginNode, Nref newNodeObject, Eref newEdgeObject = 00)
456  {
457  createNode(newNodeObject);
458  link(objectOriginNode, newNodeObject, newEdgeObject);
459  }
460 
461 public:
470  void link(Nref nodeObjectA, Nref nodeObjectB, Eref edgeObject = 00)
471  {
472  // checking the nodes
473  if (!hasNode(nodeObjectA))
474  throw Exception("First node is not in the graph observer: " + nodeToString(nodeObjectA));
475  if (!hasNode(nodeObjectB))
476  throw Exception("Second node is not in the graph observer:" + nodeToString(nodeObjectB));
477 
478  // checking if the edge is not already in the GraphObserver
479  if (edgeObject != 00 && hasEdge(edgeObject))
480  {
481  auto nodes = getNodes(edgeObject);
482  throw Exception("AssociationGraphImplObserver::link: The given edge is already associated to a relation in the subjectGraph: " + edgeToString(edgeObject) + ":" + nodeToString(nodes.first) + " -> " + nodeToString(nodes.second));
483  }
484 
485  EdgeGraphid newGraphEdge = getGraph()->link(NToGraphid_.at(nodeObjectA), NToGraphid_.at(nodeObjectB));
486 
487  if (graphidToE_.size() < newGraphEdge + 1)
488  graphidToE_.resize(newGraphEdge + 1);
489  graphidToE_.at(newGraphEdge) = edgeObject;
490  EToGraphid_[edgeObject] = newGraphEdge;
491  }
492 
493 
497  void unlink(Nref nodeObjectA, Nref nodeObjectB)
498  {
499  // checking the nodes
500  if (!hasNode(nodeObjectA))
501  throw Exception("First node is not in the graph observer: " + nodeToString(nodeObjectA));
502  if (!hasNode(nodeObjectB))
503  throw Exception("Second node is not in the graph observer:" + nodeToString(nodeObjectB));
504 
505  getGraph()->unlink(NToGraphid_.at(nodeObjectA), NToGraphid_.at(nodeObjectB));
506  }
507 
508 public:
513  void deleteNode(Nref nodeObject)
514  {
515  // first deleting the node in the graph
516  getGraph()->deleteNode(getNodeGraphid(nodeObject));
517  // then forgetting
518  dissociateNode(nodeObject);
519  }
520 
521 
522  // /@}
523 
527  // /@{
528 
534  void associateNode(Nref nodeObject, NodeGraphid graphNode)
535  {
536  if (hasNode(nodeObject))
537  throw Exception("AssociationGraphImplObserver::associateNode : node already exists: " + nodeToString(nodeObject));
538 
539  // nodes vector must be the right size. Eg: to store a node with
540  // the ID 3, the vector must be of size 4: {0,1,2,3} (size = 4)
541  if (graphidToN_.size() < graphNode + 1)
542  graphidToN_.resize(graphNode + 1);
543 
544  // now storing the node
545  graphidToN_.at(graphNode) = nodeObject;
546  NToGraphid_[nodeObject] = graphNode;
547  }
548 
554  void associateEdge(Eref edgeObject, EdgeGraphid graphEdge)
555  {
556  if (hasEdge(edgeObject))
557  throw Exception("AssociationGraphImplObserver::associateEdge : edge already exists: " + edgeToString(edgeObject));
558 
559  // edges vector must be the right size. Eg: to store an edge with
560  // the ID 3, the vector must be of size 4: {0,1,2,3} (size = 4)
561  if (graphidToE_.size() < graphEdge + 1)
562  graphidToE_.resize(graphEdge + 1);
563 
564  // now storing the edge
565  graphidToE_.at(graphEdge) = edgeObject;
566  EToGraphid_[edgeObject] = graphEdge;
567  }
568 
573  void dissociateNode(Nref nodeObject)
574  {
575  typename std::map<Nref, NodeGraphid>::iterator nodeToForget = NToGraphid_.find(nodeObject);
576  graphidToN_.at(nodeToForget->second) = 00;
577  NToGraphid_.erase(nodeToForget);
578  }
579 
580 
581  void dissociateEdge(Eref edgeObject)
582  {
583  typename std::map<Eref, EdgeGraphid>::iterator edgeToForget = EToGraphid_.find(edgeObject);
584  graphidToE_.at(edgeToForget->second) = 00;
585  EToGraphid_.erase(edgeToForget);
586  }
587 
588 
594  NodeGraphid getNodeGraphid(const Nref nodeObject) const
595  {
596  typename std::map<Nref, NodeGraphid>::const_iterator found = NToGraphid_.find(nodeObject);
597  if (found == NToGraphid_.end())
598  throw Exception("Unexisting node object: " + TextTools::toString(nodeObject));
599  return found->second;
600  }
601 
602 
608  EdgeGraphid getEdgeGraphid(const Eref edgeObject) const
609  {
610  typename std::map<Eref, EdgeGraphid>::const_iterator found = EToGraphid_.find(edgeObject);
611  if (found == EToGraphid_.end())
612  throw Exception("Unexisting edge object: " + TextTools::toString(edgeObject));
613  return found->second;
614  }
615 
616 
620  Nref getNodeFromGraphid(NodeGraphid node)
621  {
622  if (node >= graphidToN_.size())
623  return 0;
624  return graphidToN_.at(node);
625  }
626 
627  const Nref getNodeFromGraphid(NodeGraphid node) const
628  {
629  if (node >= graphidToN_.size())
630  return 0;
631  return graphidToN_.at(node);
632  }
633 
634  std::vector<Nref > getNodesFromGraphid(std::vector<NodeGraphid> nodes) const
635  {
636  std::vector<Nref > nodeObjects;
637  for (typename std::vector<NodeGraphid>::iterator currNode = nodes.begin(); currNode != nodes.end(); currNode++)
638  {
639  if (*currNode > graphidToN_.size())
640  continue;
641  Nref foundNodeObject = graphidToN_.at(*currNode);
642  if (!foundNodeObject)
643  continue;
644  nodeObjects.push_back(foundNodeObject);
645  }
646  return nodeObjects;
647  }
648 
649  Eref getEdgeFromGraphid(EdgeGraphid edge)
650  {
651  if (edge >= graphidToE_.size())
652  return 0;
653 
654  return graphidToE_.at(edge);
655  }
656 
657  const Eref getEdgeFromGraphid(EdgeGraphid edge) const
658  {
659  if (edge >= graphidToE_.size())
660  return 0;
661 
662  return graphidToE_.at(edge);
663  }
664 
665  std::vector<Eref > getEdgesFromGraphid(std::vector<EdgeGraphid> edges) const
666  {
667  std::vector<Eref > edgeObjects;
668  for (const auto& currEdge:edges)
669  {
670  if (currEdge > graphidToE_.size())
671  continue;
672  Eref foundEdgeObject = graphidToE_.at(currEdge);
673  if (!foundEdgeObject)
674  continue;
675  edgeObjects.push_back(foundEdgeObject);
676  }
677  return edgeObjects;
678  }
679 
680 
684  void setRoot(const Nref newRoot)
685  {
686  return getGraph()->setRoot(getNodeGraphid(newRoot));
687  }
688 
692  Nref getRoot() const
693  {
694  return this->getNodeFromGraphid(this->getGraph()->getRoot());
695  }
696 
697  NodeIndex getRootIndex() const
698  {
699  return this->getNodeIndex(this->getNodeFromGraphid(this->getGraph()->getRoot()));
700  }
701 
702  // /@}
703 
707  // /@{
708 
709  /*
710  * @brief Return if object has an index.
711  *
712  */
713  bool hasNodeIndex(const Nref nodeObject) const
714  {
715  return NToIndex_.find(nodeObject) != NToIndex_.end();
716  }
717 
718  bool hasEdgeIndex(const Eref edgeObject) const
719  {
720  return EToIndex_.find(edgeObject) != EToIndex_.end();
721  }
722 
728  NodeIndex getNodeIndex(const Nref nodeObject) const
729  {
730  const auto found = NToIndex_.find(nodeObject);
731  if (found == NToIndex_.end())
732  throw Exception("getNodeIndex: Node object has no index : " + nodeToString(nodeObject));
733 
734  return found->second;
735  }
736 
737  std::vector<NodeIndex> getNodeIndexes(std::vector<Nref > nodes) const
738  {
739  std::vector<NodeIndex> nodeIndexes(nodes.size());
740 
741  std::transform(nodes.begin(), nodes.end(), nodeIndexes.begin(), [this](const Nref& nodeObject){return this->getNodeIndex(nodeObject);});
742 
743  return nodeIndexes;
744  }
745 
751  EdgeIndex getEdgeIndex(const Eref edgeObject) const
752  {
753  auto found = EToIndex_.find(edgeObject);
754  if (found == EToIndex_.end())
755  throw Exception("getEdgeIndex: Edge object has no index: " + edgeToString(edgeObject));
756  return found->second;
757  }
758 
759  std::vector<EdgeIndex> getEdgeIndexes(std::vector<Eref > edges) const
760  {
761  std::vector<EdgeIndex> edgeIndexes(edges.size());
762 
763  std::transform(edges.begin(), edges.end(), edgeIndexes.begin(), [this](const Eref& edgeObject){return this->getEdgeIndex(edgeObject);});
764 
765  return edgeIndexes;
766  }
767 
774  NodeIndex setNodeIndex(const Nref nodeObject, NodeIndex index)
775  {
776  // nodes vector must be the right size. Eg: to store a node with
777  // the index 3, the vector must be of size 4: {0,1,2,3} (size = 4)
778  if (hasNode(index))
779  throw Exception("AssociationGraphImplObserver::setNodeIndex : index already exists: " + nodeToString(nodeObject));
780  if (NToIndex_.find(nodeObject) != NToIndex_.end())
781  throw Exception("AssociationGraphImplObserver::setNodeIndex : nodeObject has already an index: " + nodeToString(nodeObject));
782 
783  if (index >= indexToN_.size())
784  indexToN_.resize(index + 1);
785 
786  // now storing the node
787  indexToN_.at(index) = nodeObject;
788  NToIndex_[nodeObject] = index;
789  return index;
790  }
791 
798  EdgeIndex setEdgeIndex(const Eref edgeObject, EdgeIndex index)
799  {
800  // nodes vector must be the right size. Eg: to store an edge with
801  // the index 3, the vector must be of size 4: {0,1,2,3} (size = 4)
802  if (hasEdge(index))
803  throw Exception("AssociationGraphImplObserver::setEdgeIndex : index already exists: " + edgeToString(edgeObject));
804  if (EToIndex_.find(edgeObject) != EToIndex_.end())
805  throw Exception("AssociationGraphImplObserver::setEdgeIndex : edgeObject has already an index: " + edgeToString(edgeObject));
806 
807  if (index >= indexToE_.size())
808  indexToE_.resize(index + 1);
809 
810  // now storing the edge
811  indexToE_.at(index) = edgeObject;
812  EToIndex_[edgeObject] = index;
813  return index;
814  }
815 
821  NodeIndex addNodeIndex(const Nref nodeObject)
822  {
823  // nodes vector must be the right size. Eg: to store a node with
824  // the index 3, the vector must be of size 4: {0,1,2,3} (size = 4)
825  if (NToIndex_.find(nodeObject) != NToIndex_.end())
826  throw Exception("AssociationGraphImplObserver::addNodeIndex : nodeObject has already an index: " + nodeToString(nodeObject));
827 
828  NodeIndex index = NodeIndex(indexToN_.size());
829  for (auto i = 0; i < indexToN_.size(); i++)
830  {
831  if (!indexToN_.at(size_t(i)))
832  {
833  index = NodeIndex(i);
834  break;
835  }
836  }
837 
838  if (index >= indexToN_.size())
839  indexToN_.resize(index + 1);
840 
841  // now storing the node
842  indexToN_.at(index) = nodeObject;
843  NToIndex_[nodeObject] = index;
844  return index;
845  }
846 
852  EdgeIndex addEdgeIndex(const Eref edgeObject)
853  {
854  // nodes vector must be the right size. Eg: to store an edge with
855  // the index 3, the vector must be of size 4: {0,1,2,3} (size = 4)
856  if (EToIndex_.find(edgeObject) != EToIndex_.end())
857  throw Exception("AssociationGraphImplObserver::addEdgeIndex : edgeObject has already an index: " + edgeToString(edgeObject));
858 
859  EdgeIndex index = indexToE_.size();
860  for (auto i = 0; i < indexToE_.size(); i++)
861  {
862  if (!indexToE_.at(i))
863  {
864  index = i;
865  break;
866  }
867  }
868 
869  if (index >= indexToE_.size())
870  indexToE_.resize(index + 1);
871 
872  // now storing the edge
873  indexToE_.at(index) = edgeObject;
874  EToIndex_[edgeObject] = index;
875  return index;
876  }
877 
882  bool hasNode(NodeIndex node) const
883  {
884  return node < indexToN_.size() && indexToN_.at(node);
885  }
886 
891  bool hasEdge(EdgeIndex edge) const
892  {
893  return edge < indexToE_.size() && indexToE_.at(edge);
894  }
895 
901  Nref getNode(NodeIndex node) const
902  {
903  return indexToN_.at(node);
904  }
905 
911  Eref getEdge(EdgeIndex edge) const
912  {
913  return indexToE_.at(edge);
914  }
915 
916  // /@}
917 
921  // /@{
922 
923  /*
924  * @brief Output graph in a dot format.
925  *
926  * Nodes are labeled as "n[Index_]Id", and edge are labeled as
927  * "e[Index]_Id".
928  *
929  * Existing edge between nodes are plain, otherwise dotted.
930  *
931  * @param fname the name of the file where the DOT format will be output
932  * @param name a string naming the graph
933  *
934  */
935  void outputToDot(const std::string& fname, const std::string& name) const
936  {
937  std::ofstream out;
938  out.open(fname);
939  outputToDot(out, name);
940  out.close();
941  }
942 
943  void outputToDot(std::ostream& out, const std::string& name) const
944  {
945  out << (getGraph()->isDirected() ? "digraph" : "graph") << " " << name << " {\n ";
946  std::set<std::pair<Nref, Nref>> alreadyFigured;
947  auto allNodes = getAllNodes();
948 
949  for (const auto& node: allNodes)
950  {
951  auto children = getOutgoingNeighbors(node);
952  for (const auto& currChild : children)
953  {
954  if (alreadyFigured.find(std::pair<Nref, Nref>(node, currChild)) != alreadyFigured.end() || (getGraph()->isDirected() && alreadyFigured.find(std::pair<Nref, Nref>(currChild, node)) != alreadyFigured.end()))
955  continue;
956 
957  alreadyFigured.insert(std::pair<Nref, Nref>(node, currChild));
958 
959  out << "n";
960  if (hasNodeIndex(node))
961  out << getNodeIndex(node) << "_";
962  out << NToGraphid_.at(node);
963 
964  out << (getGraph()->isDirected() ? " -> " : " -- ");
965 
966  out << "n";
967  if (hasNodeIndex(currChild))
968  out << getNodeIndex(currChild) << "_";
969  out << NToGraphid_.at(currChild);
970 
971  auto edge = getEdgeLinking(node, currChild);
972  if (!edge)
973  out << " [style = dotted]";
974  else
975  {
976  out << " [label = e";
977  if (hasEdgeIndex(edge))
978  out << getEdgeIndex(edge) << "_";
979  out << EToGraphid_.at(edge) << "]";
980  }
981  out << ";\n ";
982  }
983  }
984  out << "}";
985  }
986 
992  template<class GraphIterator, bool is_const>
994  virtual public AssociationGraphObserver<N, E>::NodeIterator
995  {
996 private:
999 
1000 public:
1002  agio_(agio) { start(); }
1003 
1005  agio_(agio) { start(); }
1006 
1008  agio_(agio) {start(); }
1009 
1010  NodeIteratorClass<GraphIterator, is_const>(const AssociationGraphImplObserver<N, E, GraphImpl>& agio, Nref n) : it_(*agio.getGraph(), agio.getNodeGraphid(n)),
1011  agio_(agio) {start(); }
1012 
1014 
1015  void next() {it_.next(); while (!it_.end() && agio_.getNodeFromGraphid(*it_) == 0) it_.next(); }
1016 
1017  bool end() const {return it_.end(); }
1018 
1019  void start() { it_.start(); while (!it_.end() && (agio_.getNodeFromGraphid(*it_) == 0)) it_.next(); }
1020 
1021  Nref operator*() {return agio_.getNodeFromGraphid(*it_); }
1022  };
1023 
1024 
1025  std::unique_ptr<typename AssociationGraphObserver<N, E>::NodeIterator> allNodesIterator()
1026  {
1027  return std::unique_ptr<AssociationGraphImplObserver<N, E, GraphImpl>::NodeIteratorClass<Graph::ALLGRAPHITER, false>>(new AssociationGraphImplObserver<N, E, GraphImpl>::NodeIteratorClass<Graph::ALLGRAPHITER, false>(*this));
1028  }
1029 
1030  std::unique_ptr<typename AssociationGraphObserver<N, E>::NodeIterator> allNodesIterator() const
1031  {
1032  return std::unique_ptr<AssociationGraphImplObserver<N, E, GraphImpl>::NodeIteratorClass<Graph::ALLGRAPHITER, true>>(new AssociationGraphImplObserver<N, E, GraphImpl>::NodeIteratorClass<Graph::ALLGRAPHITER, true>(*this));
1033  }
1034 
1035 
1036  /*
1037  * @brief builds iterator on the neighbor nodes of a Node
1038  *
1039  */
1040  std::unique_ptr<typename AssociationGraphObserver<N, E>::NodeIterator> outgoingNeighborNodesIterator(Nref node)
1041  {
1042  return std::unique_ptr<AssociationGraphImplObserver<N, E, GraphImpl>::NodeIteratorClass<Graph::OUTGOINGNEIGHBORITER, false>>(new AssociationGraphImplObserver<N, E, GraphImpl>::NodeIteratorClass<Graph::OUTGOINGNEIGHBORITER, false>(*this, node));
1043  }
1044 
1045  std::unique_ptr<typename AssociationGraphObserver<N, E>::NodeIterator> outgoingNeighborNodesIterator(Nref node) const
1046  {
1047  return std::unique_ptr<AssociationGraphImplObserver<N, E, GraphImpl>::NodeIteratorClass<Graph::OUTGOINGNEIGHBORITER, true>>(new AssociationGraphImplObserver<N, E, GraphImpl>::NodeIteratorClass<Graph::OUTGOINGNEIGHBORITER, true>(*this, node));
1048  }
1049 
1050 
1051  /*
1052  * @brief builds iterator on the neighbor nodes of a Node
1053  *
1054  */
1055  std::unique_ptr<typename AssociationGraphObserver<N, E>::NodeIterator> incomingNeighborNodesIterator(Nref node)
1056  {
1057  return std::unique_ptr<AssociationGraphImplObserver<N, E, GraphImpl>::NodeIteratorClass<Graph::INCOMINGNEIGHBORITER, false>>(new AssociationGraphImplObserver<N, E, GraphImpl>::NodeIteratorClass<Graph::INCOMINGNEIGHBORITER, false>(*this, node));
1058  }
1059 
1060  std::unique_ptr<typename AssociationGraphObserver<N, E>::NodeIterator> incomingNeighborNodesIterator(Nref node) const
1061  {
1062  return std::unique_ptr<AssociationGraphImplObserver<N, E, GraphImpl>::NodeIteratorClass<Graph::INCOMINGNEIGHBORITER, true>>(new AssociationGraphImplObserver<N, E, GraphImpl>::NodeIteratorClass<Graph::INCOMINGNEIGHBORITER, true>(*this, node));
1063  }
1064 
1065 
1073  std::vector<Nref > getNeighbors(const Nref node) const
1074  {
1076  }
1077 
1085  std::vector<NodeIndex> getNeighbors(NodeIndex node) const
1086  {
1087  return getNodeIndexes(getNeighbors(getNode(node)));
1088  }
1089 
1096  std::vector<Eref > getEdges(const Nref node) const
1097  {
1099  }
1100 
1101  std::vector<EdgeIndex> getEdges(NodeIndex node) const
1102  {
1103  return getEdgeIndexes(getEdges(getNode(node)));
1104  }
1105 
1106 
1113  std::vector<Nref > getOutgoingNeighbors(const Nref node) const
1114  {
1116  }
1117 
1118  std::vector<NodeIndex> getOutgoingNeighbors(NodeIndex node) const
1119  {
1121  }
1122 
1129  std::vector<Eref > getOutgoingEdges(const Nref node) const
1130  {
1132  }
1133 
1134  std::vector<EdgeIndex> getOutgoingEdges(NodeIndex node) const
1135  {
1136  return getEdgeIndexes(getOutgoingEdges(getNode(node)));
1137  }
1138 
1145  std::vector<Nref > getIncomingNeighbors(const Nref node) const
1146  {
1148  }
1149 
1150  std::vector<NodeIndex> getIncomingNeighbors(NodeIndex node) const
1151  {
1153  }
1154 
1155 
1162  std::vector<Eref > getIncomingEdges(const Nref node) const
1163  {
1165  }
1166 
1167  std::vector<EdgeIndex> getIncomingEdges(NodeIndex node) const
1168  {
1169  return getEdgeIndexes(getIncomingEdges(getNode(node)));
1170  }
1171 
1182  std::vector<Nref > getLeavesFromNode(Nref node, unsigned int maxDepth) const
1183  {
1184  return getNodesFromGraphid(getGraph()->getLeavesFromNode(getNodeGraphid(node), maxDepth));
1185  }
1186 
1193  std::vector<Nref > getAllLeaves() const
1194  {
1195  std::vector<Nref > leavesToReturn;
1196  // fetching all the graph Leaves
1197  std::vector<NodeGraphid> graphLeaves = getGraph()->getAllLeaves();
1198  // testing if they are defined in this observer
1199  for (typename std::vector<NodeGraphid>::iterator currGraphLeave = graphLeaves.begin(); currGraphLeave != graphLeaves.end(); currGraphLeave++)
1200  {
1201  Nref foundLeafObject = graphidToN_.at(*currGraphLeave);
1202  if (foundLeafObject != 00)
1203  leavesToReturn.push_back(foundLeafObject);
1204  }
1205  return leavesToReturn;
1206  }
1207 
1214  std::vector<NodeIndex> getAllLeavesIndexes() const
1215  {
1216  std::vector<NodeIndex> leavesToReturn;
1217 
1218  // fetching all the graph Leaves
1219  std::vector<NodeGraphid> graphLeaves = getGraph()->getAllLeaves();
1220  // testing if they are defined in this observer
1221  for (typename std::vector<NodeGraphid>::iterator currGraphLeave = graphLeaves.begin(); currGraphLeave != graphLeaves.end(); currGraphLeave++)
1222  {
1223  Nref foundLeafObject = graphidToN_.at(*currGraphLeave);
1224  if (foundLeafObject != 00)
1225  leavesToReturn.push_back(getNodeIndex(foundLeafObject));
1226  }
1227  return leavesToReturn;
1228  }
1229 
1236  std::vector<Nref > getAllInnerNodes() const
1237  {
1238  std::vector<Nref > nodesToReturn;
1239  // fetching all the graph Leaves
1240  std::vector<NodeGraphid> graphNodes = getGraph()->getAllInnerNodes();
1241  // testing if they are defined in this observer
1242  for (const auto& currGraphNode : graphNodes)
1243  {
1244  Nref foundNodeObject = graphidToN_.at(currGraphNode);
1245  if (foundNodeObject != 00)
1246  nodesToReturn.push_back(foundNodeObject);
1247  }
1248  return nodesToReturn;
1249  }
1250 
1257  std::vector<NodeIndex> getAllInnerNodesIndexes() const
1258  {
1259  std::vector<NodeIndex> nodesToReturn;
1260  // fetching all the graph Leaves
1261  std::vector<NodeGraphid> graphNodes = getGraph()->getAllInnerNodes();
1262  // testing if they are defined in this observer
1263  for (const auto& currGraphNode : graphNodes)
1264  {
1265  Nref foundNodeObject = graphidToN_.at(currGraphNode);
1266  if (foundNodeObject != 00)
1267  nodesToReturn.push_back(getNodeIndex(foundNodeObject));
1268  }
1269  return nodesToReturn;
1270  }
1271 
1278  std::vector<Nref > getAllNodes() const
1279  {
1280  std::vector<Nref > nodesToReturn;
1281  for (typename std::vector<Nref >::const_iterator currNodeObject = graphidToN_.begin(); currNodeObject != graphidToN_.end(); currNodeObject++)
1282  {
1283  if (*currNodeObject != 00)
1284  {
1285  nodesToReturn.push_back(*currNodeObject);
1286  }
1287  }
1288  return nodesToReturn;
1289  }
1290 
1297  std::vector<NodeIndex> getAllNodesIndexes() const
1298  {
1299  std::vector<NodeIndex> indexesToReturn;
1300  for (const auto& currNodeObject : graphidToN_)
1301  {
1302  if (currNodeObject != 00)
1303  {
1304  indexesToReturn.push_back(getNodeIndex(currNodeObject));
1305  }
1306  }
1307  return indexesToReturn;
1308  }
1309 
1316  std::vector<EdgeIndex> getAllEdgesIndexes() const
1317  {
1318  std::vector<typename AssociationGraphObserver<N, E>::EdgeIndex > indexesToReturn;
1319  for (typename std::vector<Eref >::const_iterator currEdgeObject = graphidToE_.begin(); currEdgeObject != graphidToE_.end(); currEdgeObject++)
1320  {
1321  if (*currEdgeObject != 00)
1322  {
1323  indexesToReturn.push_back(getEdgeIndex(*currEdgeObject));
1324  }
1325  }
1326  return indexesToReturn;
1327  }
1328 
1329 
1330  template<class GraphIterator, bool is_const>
1333  {
1334 private:
1337 
1338 public:
1340  agio_(agio) { start(); }
1341 
1343  agio_(agio) { start(); }
1344 
1346  agio_(agio) { start(); }
1347 
1348  EdgeIteratorClass<GraphIterator, is_const>(const AssociationGraphImplObserver<N, E, GraphImpl>& agio, Nref n) : it_(*agio.getGraph(), agio.getNodeGraphid(n)),
1349  agio_(agio) { start(); }
1350 
1352 
1353  void next() {it_.next(); while (!it_.end() && (agio_.getEdgeFromGraphid(*it_) == 0)) it_.next(); }
1354 
1355  bool end() const {return it_.end(); }
1356 
1357  void start() { it_.start(); while (!it_.end() && (agio_.getEdgeFromGraphid(*it_) == 0)) it_.next(); }
1358 
1359  Eref operator*() {return agio_.getEdgeFromGraphid(*it_); }
1360  };
1361 
1362 
1363  std::unique_ptr<typename AssociationGraphObserver<N, E>::EdgeIterator> allEdgesIterator()
1364  {
1365  return std::unique_ptr<AssociationGraphImplObserver<N, E, GraphImpl>::EdgeIteratorClass<Graph::ALLGRAPHITER, false>>(new AssociationGraphImplObserver<N, E, GraphImpl>::EdgeIteratorClass<Graph::ALLGRAPHITER, false>(*this));
1366  }
1367 
1368  std::unique_ptr<typename AssociationGraphObserver<N, E>::EdgeIterator> allEdgesIterator() const
1369  {
1370  return std::unique_ptr<AssociationGraphImplObserver<N, E, GraphImpl>::EdgeIteratorClass<Graph::ALLGRAPHITER, true>>(new AssociationGraphImplObserver<N, E, GraphImpl>::EdgeIteratorClass<Graph::ALLGRAPHITER, true>(*this));
1371  }
1372 
1373  /*
1374  * @brief builds iterator on the outgoing neighbor nodes of a Edge
1375  *
1376  */
1377  std::unique_ptr<typename AssociationGraphObserver<N, E>::EdgeIterator> outgoingEdgesIterator(Nref node)
1378  {
1379  return std::unique_ptr<AssociationGraphImplObserver<N, E, GraphImpl>::EdgeIteratorClass<Graph::OUTGOINGNEIGHBORITER, false>>(new AssociationGraphImplObserver<N, E, GraphImpl>::EdgeIteratorClass<Graph::OUTGOINGNEIGHBORITER, false>(*this, node));
1380  }
1381 
1382  std::unique_ptr<typename AssociationGraphObserver<N, E>::EdgeIterator> outgoingEdgesIterator(Nref node) const
1383  {
1384  return std::unique_ptr<AssociationGraphImplObserver<N, E, GraphImpl>::EdgeIteratorClass<Graph::OUTGOINGNEIGHBORITER, true>>(new AssociationGraphImplObserver<N, E, GraphImpl>::EdgeIteratorClass<Graph::OUTGOINGNEIGHBORITER, true>(*this, node));
1385  }
1386 
1387  /*
1388  * @brief builds iterator on the incoming neighbor nodes of a Edge
1389  *
1390  */
1391  std::unique_ptr<typename AssociationGraphObserver<N, E>::EdgeIterator> incomingEdgesIterator(Nref node)
1392  {
1393  return std::unique_ptr<AssociationGraphImplObserver<N, E, GraphImpl>::EdgeIteratorClass<Graph::INCOMINGNEIGHBORITER, false>>(new AssociationGraphImplObserver<N, E, GraphImpl>::EdgeIteratorClass<Graph::INCOMINGNEIGHBORITER, false>(*this, node));
1394  }
1395 
1396  std::unique_ptr<typename AssociationGraphObserver<N, E>::EdgeIterator> incomingEdgesIterator(Nref node) const
1397  {
1398  return std::unique_ptr<AssociationGraphImplObserver<N, E, GraphImpl>::EdgeIteratorClass<Graph::INCOMINGNEIGHBORITER, true>>(new AssociationGraphImplObserver<N, E, GraphImpl>::EdgeIteratorClass<Graph::INCOMINGNEIGHBORITER, true>(*this, node));
1399  }
1400 
1405  std::vector<Eref > getAllEdges() const
1406  {
1407  std::vector<Eref > branchesToReturn;
1408  for (typename std::vector<Eref >::const_iterator currBrObject = graphidToE_.begin(); currBrObject != graphidToE_.end(); currBrObject++)
1409  {
1410  if (*currBrObject != 00)
1411  {
1412  branchesToReturn.push_back(*currBrObject);
1413  }
1414  }
1415  return branchesToReturn;
1416  }
1417 
1421  bool isLeaf(const Nref node) const
1422  {
1423  return getGraph()->isLeaf(this->getNodeGraphid(node));
1424  }
1425 
1426  bool isLeaf(const NodeIndex nodeid) const
1427  {
1428  return getGraph()->isLeaf(this->getNodeGraphid(getNode(nodeid)));
1429  }
1430 
1437  std::pair<Nref, Nref> getNodes(Eref edge) const
1438  {
1439  std::pair<NodeGraphid, NodeGraphid> nodes = getGraph()->getNodes(getEdgeGraphid(edge));
1440  return std::pair<Nref, Nref >(getNodeFromGraphid(nodes.first), getNodeFromGraphid(nodes.second));
1441  }
1442 
1449  Eref getEdgeLinking(Nref nodeA, Nref nodeB) const
1450  {
1452  }
1453 
1460  void setEdgeLinking(Nref nodeA, Nref nodeB, Eref edge)
1461  {
1462  associateEdge(edge, getGraph()->getEdge(getNodeGraphid(nodeA), getNodeGraphid(nodeB)));
1463  }
1464 
1465  // /@}
1466 
1467 
1471  // /@{
1472 
1477  void deletedEdgesUpdate(const std::vector< unsigned int >& edgesToDelete)
1478  {
1479  for (typename std::vector<EdgeGraphid>::const_iterator currEdge = edgesToDelete.begin(); currEdge != edgesToDelete.end(); currEdge++)
1480  {
1481  if (graphidToE_.size() > *currEdge)
1482  {
1483  Eref edgeObject = graphidToE_.at(*currEdge);
1484  graphidToE_.at(*currEdge) = 00;
1485 
1486  EToGraphid_.erase(edgeObject);
1487  }
1488  }
1489  }
1490 
1495  void deletedNodesUpdate(const std::vector< unsigned int >& nodesToDelete)
1496  {
1497  for (typename std::vector<EdgeGraphid>::const_iterator currNode = nodesToDelete.begin(); currNode != nodesToDelete.end(); currNode++)
1498  {
1499  if (graphidToN_.size() > *currNode)
1500  {
1501  Nref nodeObject = graphidToN_.at(*currNode);
1502  graphidToN_.at(*currNode) = 00;
1503 
1504  NToGraphid_.erase(nodeObject);
1505  }
1506  }
1507  }
1508 
1509  // /@}
1510 
1514  // /@{
1515 
1521  size_t getNumberOfNodes() const
1522  {
1523  return NToGraphid_.size();
1524  }
1525 
1531  size_t getNumberOfEdges() const
1532  {
1533  return EToGraphid_.size();
1534  }
1535 
1536 
1542  size_t getNumberOfLeaves() const
1543  {
1544  size_t nb = 0;
1545  for (typename std::vector<Nref >::const_iterator currNodeObject = graphidToN_.begin(); currNodeObject != graphidToN_.end(); currNodeObject++)
1546  {
1547  if ((*currNodeObject != 00) && (isLeaf(*currNodeObject)))
1548  nb++;
1549  }
1550 
1551  return nb;
1552  }
1553 
1559  size_t getDegree(const Nref node) const
1560  {
1561  return getGraph()->getDegree(getNodeGraphid(node));
1562  }
1563 
1564  // /@}
1565 
1566  template<typename N2, typename E2, typename G2> friend class AssociationGraphImplObserver;
1567 };
1568 
1569 /***************/
1570 
1571 template<class N, class E>
1573 }
1574 #endif // BPP_GRAPH_ASSOCIATIONGRAPHIMPLOBSERVER_H
std::vector< NodeIndex > getAllLeavesIndexes() const
std::unique_ptr< typename AssociationGraphObserver< N, E >::EdgeIterator > allEdgesIterator()
std::vector< EdgeIndex > getIncomingEdges(NodeIndex node) const
std::vector< Nref > getOutgoingNeighbors(const Nref node) const
void link(Nref nodeObjectA, Nref nodeObjectB, Eref edgeObject=00)
const AssociationGraphImplObserver< N, E, GraphImpl > & agio_
std::vector< Eref > getIncomingEdges(const Nref node) const
NodeIndex setNodeIndex(const Nref nodeObject, NodeIndex index)
std::vector< Nref > getLeavesFromNode(Nref node, unsigned int maxDepth) const
Defines a Graph Associator. It is a template which follows (subscribed to) a Graph.
std::vector< Eref > getOutgoingEdges(const Nref node) const
void setEdgeLinking(Nref nodeA, Nref nodeB, Eref edge)
NodeGraphid getNodeGraphid(const Nref nodeObject) const
virtual bool end() const =0
void outputToDot(std::ostream &out, const std::string &name) const
std::unique_ptr< typename AssociationGraphObserver< N, E >::NodeIterator > allNodesIterator() const
std::vector< EdgeIndex > getEdgeIndexes(std::vector< Eref > edges) const
bool isLeaf(const Nref node) const
Is the node a leaf?
AssociationGraphImplObserver(AssociationGraphImplObserver< N2, E2, GraphImpl > const &graphObserver)
NodesIteratorClass< GraphIterator, is_const > it_
std::unique_ptr< typename AssociationGraphObserver< N, E >::EdgeIterator > allEdgesIterator() const
std::string edgeToString(const Eref edgeObject) const
std::shared_ptr< GraphImpl > subjectGraph_
std::vector< NodeIndex > getAllInnerNodesIndexes() const
std::vector< Nref > getNodesFromGraphid(std::vector< NodeGraphid > nodes) const
STL namespace.
void deletedNodesUpdate(const std::vector< unsigned int > &nodesToDelete)
void associateNode(Nref nodeObject, NodeGraphid graphNode)
std::vector< Nref > getNeighbors(const Nref node) const
define categories of iterators
Definition: Graph.h:203
AssociationGraphImplObserver< N, E, GraphImpl > * clone() const
EdgeGraphid getEdgeGraphid(const Eref edgeObject) const
unsigned int NodeId
Definition: Graph.h:30
AssociationGraphObserver< N, E >::EdgeIndex EdgeIndex
std::map< Nref, NodeGraphid > NToGraphid_
NodeIndex addNodeIndex(const Nref nodeObject)
virtual void next()=0
const std::shared_ptr< GraphImpl > getGraph() const
std::vector< Eref > getEdgesFromGraphid(std::vector< EdgeGraphid > edges) const
AssociationGraphImplObserver< N, E, GraphImpl > & operator=(bpp::AssociationGraphImplObserver< N, E, GraphImpl > const &graphObserver)
void outputToDot(const std::string &fname, const std::string &name) const
NodeIndex getNodeIndex(const Nref nodeObject) const
virtual void next()=0
std::vector< EdgeIndex > getEdges(NodeIndex node) const
std::unique_ptr< typename AssociationGraphObserver< N, E >::NodeIterator > incomingNeighborNodesIterator(Nref node) const
virtual bool end() const =0
std::map< Eref, EdgeGraphid > EToGraphid_
void setRoot(const Nref newRoot)
set the root (but no checking, to be used at first construction)
std::vector< NodeIndex > getNodeIndexes(std::vector< Nref > nodes) const
std::vector< EdgeIndex > getOutgoingEdges(NodeIndex node) const
std::vector< NodeIndex > getIncomingNeighbors(NodeIndex node) const
std::unique_ptr< typename AssociationGraphObserver< N, E >::EdgeIterator > outgoingEdgesIterator(Nref node) const
std::pair< Nref, Nref > getNodes(Eref edge) const
EdgeIndex setEdgeIndex(const Eref edgeObject, EdgeIndex index)
std::vector< NodeIndex > getOutgoingNeighbors(NodeIndex node) const
std::vector< NodeIndex > getNeighbors(NodeIndex node) const
std::unique_ptr< typename AssociationGraphObserver< N, E >::NodeIterator > allNodesIterator()
std::unique_ptr< typename AssociationGraphObserver< N, E >::EdgeIterator > incomingEdgesIterator(Nref node) const
std::vector< Nref > getIncomingNeighbors(const Nref node) const
std::string nodeToString(const Nref nodeObject) const
std::vector< Eref > getEdges_(const Nref nodeObject, neighborType type) const
bool isLeaf(const NodeIndex nodeid) const
std::unique_ptr< typename AssociationGraphObserver< N, E >::NodeIterator > outgoingNeighborNodesIterator(Nref node) const
Exception base class. Overload exception constructor (to control the exceptions mechanism). Destructor is already virtual (from std::exception)
Definition: Exceptions.h:20
EdgeIndex getEdgeIndex(const Eref edgeObject) const
std::vector< EdgeIndex > getAllEdgesIndexes() const
const Nref getNodeFromGraphid(NodeGraphid node) const
const Eref getEdgeFromGraphid(EdgeGraphid edge) const
void associateEdge(Eref edgeObject, EdgeGraphid graphEdge)
std::vector< Eref > getEdges(const Nref node) const
void unlink(Nref nodeObjectA, Nref nodeObjectB)
const AssociationGraphImplObserver< N, E, GraphImpl > & agio_
AssociationGraphObserver< N, E >::NodeIndex NodeIndex
bool hasNodeIndex(const Nref nodeObject) const
return if the object has an index.
bool hasEdgeIndex(const Eref edgeObject) const
std::unique_ptr< typename AssociationGraphObserver< N, E >::NodeIterator > outgoingNeighborNodesIterator(Nref node)
std::string toString(T t)
General template method to convert to a string.
Definition: TextTools.h:115
AssociationGraphImplObserver(AssociationGraphImplObserver< N, E, GraphImpl > const &graphObserver)
std::vector< Nref > getNeighbors_(const Nref nodeObject, neighborType type) const
EdgeIndex addEdgeIndex(const Eref edgeObject)
std::unique_ptr< typename AssociationGraphObserver< N, E >::NodeIterator > incomingNeighborNodesIterator(Nref node)
std::vector< NodeIndex > getAllNodesIndexes() const
virtual void start()=0
Eref getEdgeLinking(Nref nodeA, Nref nodeB) const
std::unique_ptr< typename AssociationGraphObserver< N, E >::EdgeIterator > incomingEdgesIterator(Nref node)
unsigned int EdgeId
Definition: Graph.h:31
virtual void start()=0
void createNode(Nref objectOriginNode, Nref newNodeObject, Eref newEdgeObject=00)
std::unique_ptr< typename AssociationGraphObserver< N, E >::EdgeIterator > outgoingEdgesIterator(Nref node)
void deletedEdgesUpdate(const std::vector< unsigned int > &edgesToDelete)
AssociationGraphImplObserver(std::shared_ptr< GraphImpl > subjectGraph=00)
Constructor.