41 #ifndef BPP_GRAPH_ASSOCIATIONGRAPHIMPLOBSERVER_H
42 #define BPP_GRAPH_ASSOCIATIONGRAPHIMPLOBSERVER_H
50 #include <type_traits>
53 #include "../Clonable.h"
54 #include "../Exceptions.h"
55 #include "../Text/TextTools.h"
61 template<
class N,
class E,
class GraphImpl>
71 using Eref = std::shared_ptr<E>;
72 using Nref = std::shared_ptr<N>;
152 subjectGraph_(std::shared_ptr<GraphImpl>(new GraphImpl(directed))),
175 subjectGraph_(subjectGraph ? subjectGraph : std::shared_ptr<GraphImpl>(new GraphImpl(true))),
193 template<
class N2,
class E2>
212 const auto& indN = graphObserver.
NToIndex_.find(itN.first);
214 if (indN != graphObserver.
NToIndex_.end())
228 const auto& indE = graphObserver.
EToIndex_.find(itE.first);
230 if (indE != graphObserver.
EToIndex_.end())
258 const auto& indN = graphObserver.
NToIndex_.find(itN.first);
260 if (indN != graphObserver.
NToIndex_.end())
274 const auto& indE = graphObserver.
EToIndex_.find(itE.first);
276 if (indE != graphObserver.
EToIndex_.end())
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());
305 const auto& indN = graphObserver.
NToIndex_.find(itN.first);
307 if (indN != graphObserver.
NToIndex_.end())
321 const auto& indE = graphObserver.
EToIndex_.find(itE.first);
323 if (indE != graphObserver.
EToIndex_.end())
330 this->subjectGraph_ = graphObserver.
getGraph();
332 this->
getGraph()->registerObserver(
this);
343 getGraph()->unregisterObserver(
this);
425 std::vector<NodeGraphid> neighbors;
429 neighbors =
getGraph()->getOutgoingNeighbors(node);
432 neighbors =
getGraph()->getIncomingNeighbors(node);
435 neighbors =
getGraph()->getNeighbors(node);
448 std::vector<EdgeGraphid> edges;
452 edges =
getGraph()->getOutgoingEdges(node);
455 edges =
getGraph()->getIncomingEdges(node);
477 throw Exception(
"AssociationGraphImplObserver::createNode : node already exists: " +
nodeToString(nodeObject));
479 unsigned int newGraphNode =
getGraph()->createNode();
494 link(objectOriginNode, newNodeObject, newEdgeObject);
515 if (edgeObject != 00 &&
hasEdge(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));
573 throw Exception(
"AssociationGraphImplObserver::associateNode : node already exists: " +
nodeToString(nodeObject));
593 throw Exception(
"AssociationGraphImplObserver::associateEdge : edge already exists: " +
edgeToString(edgeObject));
611 typename std::map<Nref, NodeGraphid>::iterator nodeToForget =
NToGraphid_.find(nodeObject);
619 typename std::map<Eref, EdgeGraphid>::iterator edgeToForget =
EToGraphid_.find(edgeObject);
632 typename std::map<Nref, NodeGraphid>::const_iterator found =
NToGraphid_.find(nodeObject);
635 return found->second;
646 typename std::map<Eref, EdgeGraphid>::const_iterator found =
EToGraphid_.find(edgeObject);
649 return found->second;
672 std::vector<Nref > nodeObjects;
673 for (
typename std::vector<NodeGraphid>::iterator currNode = nodes.begin(); currNode != nodes.end(); currNode++)
678 if (!foundNodeObject)
680 nodeObjects.push_back(foundNodeObject);
703 std::vector<Eref > edgeObjects;
704 for (
const auto& currEdge:edges)
709 if (!foundEdgeObject)
711 edgeObjects.push_back(foundEdgeObject);
766 const auto found =
NToIndex_.find(nodeObject);
770 return found->second;
775 std::vector<NodeIndex> nodeIndexes(nodes.size());
777 std::transform(nodes.begin(), nodes.end(), nodeIndexes.begin(), [
this](
const Nref& nodeObject){return this->getNodeIndex(nodeObject);});
792 return found->second;
797 std::vector<EdgeIndex> edgeIndexes(edges.size());
799 std::transform(edges.begin(), edges.end(), edgeIndexes.begin(), [
this](
const Eref& edgeObject){return this->getEdgeIndex(edgeObject);});
815 throw Exception(
"AssociationGraphImplObserver::setNodeIndex : index already exists: " +
nodeToString(nodeObject));
817 throw Exception(
"AssociationGraphImplObserver::setNodeIndex : nodeObject has already an index: " +
nodeToString(nodeObject));
839 throw Exception(
"AssociationGraphImplObserver::setEdgeIndex : index already exists: " +
edgeToString(edgeObject));
841 throw Exception(
"AssociationGraphImplObserver::setEdgeIndex : edgeObject has already an index: " +
edgeToString(edgeObject));
862 throw Exception(
"AssociationGraphImplObserver::addNodeIndex : nodeObject has already an index: " +
nodeToString(nodeObject));
865 for (
auto i = 0; i <
indexToN_.size(); i++)
893 throw Exception(
"AssociationGraphImplObserver::addEdgeIndex : edgeObject has already an index: " +
edgeToString(edgeObject));
896 for (
auto i = 0; i <
indexToE_.size(); i++)
971 void outputToDot(
const std::string& fname,
const std::string& name)
const
979 void outputToDot(std::ostream& out,
const std::string& name)
const
981 out << (
getGraph()->isDirected() ?
"digraph" :
"graph") <<
" " << name <<
" {\n ";
982 std::set<std::pair<Nref, Nref> > alreadyFigured;
985 for (
const auto& node: allNodes)
988 for (
const auto& currChild : children)
990 if (alreadyFigured.find(std::pair<Nref, Nref>(node, currChild)) != alreadyFigured.end() || (
getGraph()->isDirected() && alreadyFigured.find(std::pair<Nref, Nref>(currChild, node)) != alreadyFigured.end()))
993 alreadyFigured.insert(std::pair<Nref, Nref>(node, currChild));
1000 out << (
getGraph()->isDirected() ?
" -> " :
" -- ");
1009 out <<
" [style = dotted]";
1012 out <<
" [label = e";
1028 template<
class GraphIterator,
bool is_const>
1046 NodeIteratorClass<GraphIterator, is_const>(
const AssociationGraphImplObserver<N, E, GraphImpl>& agio,
Nref n) :
it_(*agio.
getGraph(), agio.
getNodeGraphid(n)),
1049 ~NodeIteratorClass<GraphIterator, is_const>() {}
1066 std::unique_ptr<typename AssociationGraphObserver<N, E>::NodeIterator>
allNodesIterator()
const
1231 std::vector<Nref > leavesToReturn;
1233 std::vector<NodeGraphid> graphLeaves =
getGraph()->getAllLeaves();
1235 for (
typename std::vector<NodeGraphid>::iterator currGraphLeave = graphLeaves.begin(); currGraphLeave != graphLeaves.end(); currGraphLeave++)
1238 if (foundLeafObject != 00)
1239 leavesToReturn.push_back(foundLeafObject);
1241 return leavesToReturn;
1252 std::vector<NodeIndex> leavesToReturn;
1255 std::vector<NodeGraphid> graphLeaves =
getGraph()->getAllLeaves();
1257 for (
typename std::vector<NodeGraphid>::iterator currGraphLeave = graphLeaves.begin(); currGraphLeave != graphLeaves.end(); currGraphLeave++)
1260 if (foundLeafObject != 00)
1261 leavesToReturn.push_back(
getNodeIndex(foundLeafObject));
1263 return leavesToReturn;
1274 std::vector<Nref > nodesToReturn;
1276 std::vector<NodeGraphid> graphNodes =
getGraph()->getAllInnerNodes();
1278 for (
const auto& currGraphNode : graphNodes)
1281 if (foundNodeObject != 00)
1282 nodesToReturn.push_back(foundNodeObject);
1284 return nodesToReturn;
1295 std::vector<NodeIndex> nodesToReturn;
1297 std::vector<NodeGraphid> graphNodes =
getGraph()->getAllInnerNodes();
1299 for (
const auto& currGraphNode : graphNodes)
1302 if (foundNodeObject != 00)
1303 nodesToReturn.push_back(
getNodeIndex(foundNodeObject));
1305 return nodesToReturn;
1316 std::vector<Nref > nodesToReturn;
1317 for (
typename std::vector<Nref >::const_iterator currNodeObject =
graphidToN_.begin(); currNodeObject !=
graphidToN_.end(); currNodeObject++)
1319 if (*currNodeObject != 00)
1321 nodesToReturn.push_back(*currNodeObject);
1324 return nodesToReturn;
1335 std::vector<NodeIndex> indexesToReturn;
1338 if (currNodeObject != 00)
1340 indexesToReturn.push_back(
getNodeIndex(currNodeObject));
1343 return indexesToReturn;
1354 std::vector<typename AssociationGraphObserver<N, E>::EdgeIndex > indexesToReturn;
1355 for (
typename std::vector<Eref >::const_iterator currEdgeObject =
graphidToE_.begin(); currEdgeObject !=
graphidToE_.end(); currEdgeObject++)
1357 if (*currEdgeObject != 00)
1359 indexesToReturn.push_back(
getEdgeIndex(*currEdgeObject));
1362 return indexesToReturn;
1366 template<
class GraphIterator,
bool is_const>
1384 EdgeIteratorClass<GraphIterator, is_const>(
const AssociationGraphImplObserver<N, E, GraphImpl>& agio,
Nref n) :
it_(*agio.
getGraph(), agio.
getNodeGraphid(n)),
1387 ~EdgeIteratorClass<GraphIterator, is_const>() {}
1404 std::unique_ptr<typename AssociationGraphObserver<N, E>::EdgeIterator>
allEdgesIterator()
const
1443 std::vector<Eref > branchesToReturn;
1444 for (
typename std::vector<Eref >::const_iterator currBrObject =
graphidToE_.begin(); currBrObject !=
graphidToE_.end(); currBrObject++)
1446 if (*currBrObject != 00)
1448 branchesToReturn.push_back(*currBrObject);
1451 return branchesToReturn;
1515 for (
typename std::vector<EdgeGraphid>::const_iterator currEdge = edgesToDelete.begin(); currEdge != edgesToDelete.end(); currEdge++)
1533 for (
typename std::vector<EdgeGraphid>::const_iterator currNode = nodesToDelete.begin(); currNode != nodesToDelete.end(); currNode++)
1581 for (
typename std::vector<Nref >::const_iterator currNodeObject =
graphidToN_.begin(); currNodeObject !=
graphidToN_.end(); currNodeObject++)
1583 if ((*currNodeObject != 00) && (
isLeaf(*currNodeObject)))
1607 template<
class N,
class E>
EdgesIteratorClass< GraphIterator, is_const > it_
const AssociationGraphImplObserver< N, E, GraphImpl > & agio_
NodesIteratorClass< GraphIterator, is_const > it_
const AssociationGraphImplObserver< N, E, GraphImpl > & agio_
void deleteNode(Nref nodeObject)
const Eref getEdgeFromGraphid(EdgeGraphid edge) const
std::map< Eref, EdgeIndex > EToIndex_
std::vector< Nref > getAllLeaves() const
std::shared_ptr< GraphImpl > getGraph()
void link(Nref nodeObjectA, Nref nodeObjectB, Eref edgeObject=00)
const Nref getNodeFromGraphid(NodeGraphid node) const
bool hasEdge(Eref edgeObject) 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)
std::vector< Eref > getAllEdges() const
EdgeIndex addEdgeIndex(const Eref edgeObject)
void deletedEdgesUpdate(const std::vector< unsigned int > &edgesToDelete)
std::map< Eref, EdgeGraphid > EToGraphid_
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?
Nref getNodeFromGraphid(NodeGraphid node)
std::vector< EdgeIndex > getOutgoingEdges(NodeIndex node) const
std::vector< Eref > getEdges(const Nref node) const
EdgeGraphid getEdgeGraphid(const Eref edgeObject) const
std::shared_ptr< E > Eref
std::vector< Nref > indexToN_
bool hasEdge(EdgeIndex edge) const
bool hasNode(Nref nodeObject) 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
AssociationGraphImplObserver(bool directed=false)
std::unique_ptr< typename AssociationGraphObserver< N, E >::EdgeIterator > incomingEdgesIterator(Nref node) const
void dissociateEdge(Eref edgeObject)
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
size_t getDegree(const Nref node) const
std::unique_ptr< typename AssociationGraphObserver< N, E >::EdgeIterator > allEdgesIterator()
std::vector< EdgeIndex > getAllEdgesIndexes() const
std::vector< Nref > graphidToN_
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)
void createNode(Nref nodeObject)
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::vector< Eref > indexToE_
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::shared_ptr< N > Nref
size_t getNumberOfNodes() const
std::vector< NodeIndex > getAllInnerNodesIndexes() const
std::vector< NodeIndex > getNodeIndexes(std::vector< Nref > nodes) const
void dissociateNode(Nref nodeObject)
std::map< Nref, NodeGraphid > NToGraphid_
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
Graph::EdgeId EdgeGraphid
std::vector< EdgeIndex > getEdges(NodeIndex node) const
void deletedNodesUpdate(const std::vector< unsigned int > &nodesToDelete)
std::vector< Eref > graphidToE_
std::vector< Nref > getNodesFromGraphid(std::vector< NodeGraphid > nodes) const
size_t getNumberOfEdges() 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)
Eref getEdge(EdgeIndex edge) const
std::vector< Nref > getAllNodes() const
size_t getNumberOfLeaves() const
std::map< Nref, NodeIndex > NToIndex_
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
Nref getNode(NodeIndex node) const
NodeIndex getNodeIndex(const Nref nodeObject) const
AssociationGraphImplObserver< N, E, GraphImpl > & operator=(bpp::AssociationGraphImplObserver< N, E, GraphImpl > const &graphObserver)
~AssociationGraphImplObserver()
AssociationGraphImplObserver(std::shared_ptr< GraphImpl > subjectGraph=00)
Constructor.
void outputToDot(std::ostream &out, const std::string &name) const
NodeIndex getRootIndex() const
std::string nodeToString(const Nref nodeObject) const
std::vector< Nref > getAllInnerNodes() const
std::vector< Nref > getLeavesFromNode(Nref node, unsigned int maxDepth) const
Graph::NodeId NodeGraphid
bool hasNode(NodeIndex node) const
EdgeIndex getEdgeIndex(const Eref edgeObject) const
std::string edgeToString(const Eref edgeObject) const
bool isLeaf(const NodeIndex nodeid) const
Eref getEdgeFromGraphid(EdgeGraphid edge)
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)....
virtual bool end() const =0
virtual bool end() const =0
std::string toString(T t)
General template method to convert to a string.
define categories of iterators