11 #include "../Exceptions.h" 12 #include "../Text/TextTools.h" 20 directed_(directed_p),
99 vector<GlobalGraph::Edge> deletedEdges;
102 for (
auto& currEdgeToDelete : deletedEdges)
117 nodeStructureType::iterator nodeARow =
nodeStructure_.find(nodeA);
118 nodeStructureType::iterator nodeBRow =
nodeStructure_.find(nodeB);
119 nodeStructureType::iterator nodeSonRow, nodeFatherRow;
122 map<GlobalGraph::Node, GlobalGraph::Edge>::iterator foundForwardRelation = nodeARow->second.first.find(nodeB);
123 if (foundForwardRelation == nodeARow->second.first.end())
125 foundForwardRelation = nodeBRow->second.first.find(nodeA);
126 if (foundForwardRelation == nodeBRow->second.first.end())
130 nodeFatherRow = nodeBRow;
131 nodeSonRow = nodeARow;
137 nodeFatherRow = nodeARow;
138 nodeSonRow = nodeBRow;
145 map<GlobalGraph::Node, GlobalGraph::Edge>::iterator foundBackwardsRelation = nodeSonRow->second.second.find(father);
149 nodeFatherRow->second.first.erase(foundForwardRelation);
150 nodeSonRow->second.second.erase(foundBackwardsRelation);
153 nodeSonRow->second.first[father] = foundEdge;
155 nodeFatherRow->second.second[son] = foundEdge;
168 edgeStructureType::iterator foundEdge =
edgeStructure_.find(edge);
186 nodeStructureType::iterator nodeARow =
nodeStructure_.find(nodeA);
187 map<GlobalGraph::Node, GlobalGraph::Edge>::iterator foundForwardRelation = nodeARow->second.first.find(nodeB);
188 if (foundForwardRelation == nodeARow->second.first.end())
192 nodeARow->second.first.erase(foundForwardRelation);
195 nodeStructureType::iterator nodeBRow =
nodeStructure_.find(nodeB);
196 map<GlobalGraph::Node, GlobalGraph::Edge>::iterator foundBackwardsRelation = nodeBRow->second.second.find(nodeA);
197 if (foundBackwardsRelation == nodeBRow->second.first.end())
200 nodeBRow->second.second.erase(foundBackwardsRelation);
210 ita->second.first.insert( pair<GlobalGraph::Node, GlobalGraph::Edge>(nodeB, edge));
214 nodeStructure_.find(nodeB)->second.second.insert( pair<GlobalGraph::Node, GlobalGraph::Edge>(nodeA, edge));
222 nodeStructure_[newNode] = std::pair<std::map<GlobalGraph::Node, GlobalGraph::Edge>, std::map<GlobalGraph::Node, GlobalGraph::Edge>>();
231 link(origin, newNode);
244 pair<GlobalGraph::Node, GlobalGraph::Node> nodes =
edgeStructure_[edge];
249 link(nodeA, newNode);
250 link(newNode, nodeB);
274 throw (
Exception(
"This GraphObserver was already an observer of this Graph"));
281 throw (
Exception(
"This GraphObserver was not an observer of this Graph"));
289 nodeStructureType::const_iterator foundNode =
nodeStructure_.find(node);
291 throw (
Exception(
"The requested node is not in the structure."));
292 const std::map<GlobalGraph::Node, GlobalGraph::Edge>& forOrBack = (outgoing ? foundNode->second.first : foundNode->second.second);
293 vector<GlobalGraph::Node> result;
294 for (
auto& currNeighbor : forOrBack)
296 result.push_back(currNeighbor.first);
304 nodeStructureType::const_iterator foundNode =
nodeStructure_.find(node);
306 throw (
Exception(
"The requested node is not in the structure."));
307 const std::map<GlobalGraph::Node, GlobalGraph::Edge>& forOrBack = (outgoing ? foundNode->second.first : foundNode->second.second);
309 vector<GlobalGraph::Edge> result;
310 for (
const auto& currNeighbor : forOrBack)
312 result.push_back(currNeighbor.second);
386 nodeStructureType::const_iterator foundNode =
nodeStructure_.find(node);
390 return isDirected() ? foundNode->second.first.size() + foundNode->second.second.size() : foundNode->second.first.size();
396 nodeStructureType::const_iterator foundNode =
nodeStructure_.find(node);
400 const auto& assoc = foundNode->second;
401 return (!
isDirected() && (assoc.first.size() <= 1))
403 (assoc.first.size() + assoc.second.size() <= 1)
404 || (assoc.first.size() == 1 && assoc.second.size() == 1 &&
405 assoc.first.begin()->first == assoc.second.begin()->first)));
411 nodeStructureType::const_iterator foundNode =
nodeStructure_.find(node);
413 throw (
Exception(
"The requested node is not in the structure."));
416 return foundNode->second.first.size() + foundNode->second.second.size();
418 return foundNode->second.first.size();
423 nodeStructureType::const_iterator foundNode =
nodeStructure_.find(node);
425 throw (
Exception(
"The requested node is not in the structure."));
426 return foundNode->second.first.size();
431 nodeStructureType::const_iterator foundNode =
nodeStructure_.find(node);
433 throw (
Exception(
"The requested node is not in the structure."));
434 return foundNode->second.second.size();
439 vector<Graph::NodeId> result;
440 vector<Graph::NodeId> neighborsToInsert;
442 result.insert(result.end(), neighborsToInsert.begin(), neighborsToInsert.end());
444 result.insert(result.end(), neighborsToInsert.begin(), neighborsToInsert.end());
451 edgeStructureType::const_iterator found =
edgeStructure_.find(edge);
452 return found->second;
483 for (
auto& currNeighbor : oneighbors)
485 unlink(node, currNeighbor);
489 for (
auto& currNeighbor : ineighbors)
491 unlink(currNeighbor, node);
497 vector<Graph::EdgeId> listOfEdges;
500 listOfEdges.push_back(it.first);
522 vector<Graph::NodeId> listOfLeaves;
525 if (this->
isLeaf(it.first))
526 listOfLeaves.push_back(it.first);
534 set<Graph::NodeId> listOfLeaves;
537 if (this->
isLeaf(it.first))
538 listOfLeaves.insert(it.first);
546 vector<Graph::NodeId> listOfNodes;
549 listOfNodes.push_back(it.first);
557 vector<Graph::NodeId> listOfInNodes;
561 listOfInNodes.push_back(it.first);
563 return listOfInNodes;
569 const vector<Graph::NodeId> neighbors =
getNeighbors(startingNode);
570 if (neighbors.size() > 1)
572 if (maxRecursions > 0)
573 for (
const auto& currNeighbor : neighbors)
575 if (currNeighbor != originNode)
580 foundLeaves.push_back(startingNode);
586 vector<Graph::NodeId> listOfLeaves;
594 const std::map<Node, Edge>& children =
nodeStructure_.at(node).first;
596 for (
const auto& currChild : children)
598 if (alreadyFigured.find(pair<Node, Node>(node, currChild.first)) != alreadyFigured.end() || (!
directed_ && alreadyFigured.find(pair<Node, Node>(currChild.first, node)) != alreadyFigured.end()))
600 alreadyFigured.insert(pair<Node, Node>(node, currChild.first));
604 nodeToDot_(currChild.first, out, alreadyFigured);
613 set<GlobalGraph::Node> metNodes;
616 if (!nodesAreMetOnlyOnce)
622 if (metNodes.find(currNode.first) == metNodes.end())
633 if (!metNodes.insert(node).second)
637 for (
auto currNeighbor:neighbors)
639 if (currNeighbor == originNode)
654 std::vector<Graph::NodeId> vL;
657 for ( ; !it->
end(); it->
next())
663 while (vL.size() != 0)
676 for ( ; !it->
end(); it->
next())
699 std::set<Graph::NodeId> nextNodes;
700 nextNodes.insert(node);
709 std::set<Graph::NodeId>::iterator it = nextNodes.begin();
710 for ( ; it != nextNodes.end(); it++)
717 if (it == nextNodes.end())
719 size_t nbF = numeric_limits<size_t>::infinity();
720 it = nextNodes.begin();
722 for ( ; it != nextNodes.end(); it++)
748 nextNodes.insert(it2);
754 nextNodes.insert(it2);
758 nextNodes.erase(nbgg);
786 it.second = std::pair<std::map<Node, Edge>, std::map<Node, Edge>>();
793 std::set<pair<Node, Node>> alreadyConvertedRelations;
794 for (
auto& currNodeRow : undirectedStructure)
796 Node nodeA = currNodeRow.first;
798 for (
auto& currRelation : currNodeRow.second.first)
800 Node nodeB = currRelation.first;
801 Edge edge = currRelation.second;
802 if (alreadyConvertedRelations.insert(pair<Node, Node>(min(nodeA, nodeB), max(nodeA, nodeB))).second)
815 throw Exception(
"Cannot make an undirected graph from a directed one containing reciprocal relations.");
820 it.second = std::pair<std::map<Node, Edge>, std::map<Node, Edge>>();
826 for (
auto& currNodeRow : directedStructure)
828 Node nodeA = currNodeRow.first;
829 for (
auto currRelation : currNodeRow.second.first)
831 Node nodeB = currRelation.first;
832 Edge edge = currRelation.second;
844 throw Exception(
"Cannot state reciprocal link in an undirected graph.");
845 std::set<pair<Node, Node>> alreadyMetRelations;
848 Node nodeA = currNodeRow.first;
849 for (
const auto& currRelation : currNodeRow.second.first)
851 Node nodeB = currRelation.first;
852 if (!alreadyMetRelations.insert(pair<Node, Node>(min(nodeA, nodeB), max(nodeA, nodeB))).second)
891 nodeStructureType::const_iterator firstNodeFound =
nodeStructure_.find(nodeA);
893 throw (
Exception(
"The fist node was not the origin of an edge."));
894 map<Node, Edge>::const_iterator secondNodeFound = firstNodeFound->second.first.find(nodeB);
895 if (secondNodeFound == firstNodeFound->second.first.end())
896 throw (
Exception(
"The second node was not in a relation with the first one."));
897 return secondNodeFound->second;
902 vector<Graph::EdgeId> result;
903 vector<Graph::EdgeId> edgesToInsert;
905 result.insert(result.end(), edgesToInsert.begin(), edgesToInsert.end());
907 result.insert(result.end(), edgesToInsert.begin(), edgesToInsert.end());
913 out << (
directed_ ?
"digraph" :
"graph") <<
" " << name <<
" {\n ";
914 set<pair<Node, Node>> alreadyFigured;
918 if (node.first !=
root_)
921 out <<
"\r}" << endl;
928 currObserver->deletedEdgesUpdate(edgesToDelete);
936 currObserver->deletedNodesUpdate(nodesToDelete);
virtual void topologyHasChanged_() const
std::vector< Graph::EdgeId > getOutgoingEdges(Graph::NodeId node) const
size_t getNumberOfEdges() const
std::unique_ptr< EdgeIterator > allEdgesIterator()
size_t getNumberOfOutgoingNeighbors(Graph::NodeId node) const
void unregisterObserver(GraphObserver *observer)
void notifyDeletedEdges(const std::vector< Graph::EdgeId > &edgesToDelete) const
Graph::NodeId getBottom(Graph::EdgeId edge) const
void switchNodes(Graph::NodeId nodeA, Graph::NodeId nodeB)
void outputToDot(std::ostream &out, const std::string &name) const
void edgeMustExist_(const Edge &edge, std::string name="") const
Graph::EdgeId getEdge(Graph::NodeId nodeA, Graph::NodeId nodeB) const
Graph::EdgeId getAnyEdge(Graph::NodeId nodeA, Graph::NodeId nodeB) const
std::map< Edge, std::pair< Node, Node > > edgeStructureType
void deleteNode(Graph::NodeId node)
std::vector< Graph::NodeId > getIncomingNeighbors(Graph::NodeId node) const
std::vector< Graph::EdgeId > getIncomingEdges(Graph::NodeId node) const
Graph::NodeId createNodeOnEdge(Graph::EdgeId edge)
void nodeMustExist_(const Node &node, std::string name="") const
bool containsReciprocalRelations() const
Graph::NodeId createNode()
bool nodesAreMetOnlyOnce_(const Node &node, std::set< Node > &metNodes, const Node &originNode) const
std::vector< Node > getNeighbors_(const Node &node, bool outgoing=true) const
std::set< GraphObserver * > observers_
void setRoot(Graph::NodeId newRoot)
std::vector< Graph::NodeId > getAllLeaves() const
Edge unlinkInNodeStructure_(const Node &nodeA, const Node &nodeB)
void linkInEdgeStructure_(const Node &nodeA, const Node &nodeB, const Edge &edge)
std::vector< Graph::NodeId > getLeavesFromNode(Graph::NodeId node, unsigned int maxDepth) const
std::vector< Edge > getEdges_(const Node &node, bool outgoing=true) const
Graph::NodeId createNodeFromEdge(Graph::NodeId origin)
Graph::EdgeId link(Graph::NodeId nodeA, Graph::NodeId nodeB)
virtual bool end() const =0
std::unique_ptr< Graph::NodeIterator > incomingNeighborNodesIterator(NodeId node)
GlobalGraph(bool directed=false)
std::map< Node, std::pair< std::map< Node, Edge >, std::map< Node, Edge > > > nodeStructureType
size_t getNumberOfNodes() const
Graph::NodeId getTop(Graph::EdgeId edge) const
size_t getNumberOfIncomingNeighbors(Graph::NodeId node) const
void unlinkInEdgeStructure_(const Edge &edge)
std::unique_ptr< Graph::NodeIterator > allNodesIterator()
GlobalGraph & operator=(const GlobalGraph &gg)
std::unique_ptr< EdgeIterator > outgoingEdgesIterator(NodeId node)
bool isLeaf(Graph::NodeId node) const
std::vector< Graph::EdgeId > unlink(Graph::NodeId nodeA, Graph::NodeId nodeB)
void fillListOfLeaves_(const Node &startingNode, std::vector< Node > &foundLeaves, const Node &originNode, unsigned int maxRecursions) const
std::vector< Graph::NodeId > getOutgoingNeighbors(Graph::NodeId node) const
std::unique_ptr< Graph::NodeIterator > outgoingNeighborNodesIterator(NodeId node)
Exception base class. Overload exception constructor (to control the exceptions mechanism). Destructor is already virtual (from std::exception)
void linkInNodeStructure_(const Node &nodeA, const Node &nodeB, const Edge &edge)
std::unique_ptr< EdgeIterator > incomingEdgesIterator(NodeId node)
std::vector< Graph::NodeId > getAllInnerNodes() const
std::vector< Graph::NodeId > getNeighbors(Graph::NodeId node) const
std::vector< Graph::EdgeId > getAllEdges() const
nodeStructureType nodeStructure_
Graph::NodeId createNodeFromNode(Graph::NodeId origin)
size_t getDegree(Graph::NodeId node) const
void registerObserver(GraphObserver *observer)
std::string toString(T t)
General template method to convert to a string.
Defines a Graph Observer. It is a template which follows (subscribed to) a Graph. The graph and the g...
void notifyDeletedNodes(const std::vector< Graph::NodeId > &nodesToDelete) const
std::vector< Graph::NodeId > getAllNodes() const
std::set< NodeId > getSetOfAllLeaves() const
size_t getNumberOfNeighbors(Graph::NodeId node) const
std::pair< Graph::NodeId, Graph::NodeId > getNodes(Graph::EdgeId edge) const
void nodeToDot_(const Node &node, std::ostream &out, std::set< std::pair< Node, Node >> &alreadyFigured) const
edgeStructureType edgeStructure_
Graph::NodeId getRoot() const
std::vector< Graph::EdgeId > getEdges(Graph::NodeId node) const
void isolate_(Node &node)