5 #ifndef BPP_GRAPH_TREEGRAPHIMPL_H 6 #define BPP_GRAPH_TREEGRAPHIMPL_H 13 #include "../Exceptions.h" 14 #include "../Numeric/VectorTools.h" 20 template<
class GraphImpl>
184 void unRoot(
bool joinRootSons);
228 template<
class GraphImpl>
235 template<
class GraphImpl>
241 template<
class GraphImpl>
245 if (incomers.size() > 1)
246 throw Exception(
"TreeGraphImpl<GraphImpl>::getFather: more than one father for Node " +
TextTools::toString(node) +
" : " +
VectorTools::paste(incomers,
",") +
". Should never happen since validity has been controlled. Please report this bug.");
247 if (incomers.size() == 0)
249 return *incomers.begin();
252 template<
class GraphImpl>
256 return GraphImpl::getEdge(father, node);
259 template<
class GraphImpl>
262 return GraphImpl::getNumberOfIncomingNeighbors(node) >= 1;
265 template<
class GraphImpl>
268 return (!GraphImpl::isDirected() && GraphImpl::getNumberOfOutgoingNeighbors(node) <= 1)
269 || (GraphImpl::isDirected() && GraphImpl::getNumberOfOutgoingNeighbors(node) == 0);
272 template<
class GraphImpl>
275 const std::vector<Graph::NodeId> sons =
getSons(startingNode);
278 for (std::vector<Graph::NodeId>::const_iterator currNeighbor = sons.begin(); currNeighbor != sons.end(); currNeighbor++)
285 foundLeaves.push_back(startingNode);
289 template<
class GraphImpl>
292 std::vector<Graph::NodeId> foundLeaves;
298 template<
class GraphImpl>
302 throw Exception(
"TreeGraphImpl<GraphImpl>: The tree must be rooted.");
305 template<
class GraphImpl>
309 throw Exception(
"TreeGraphImpl<GraphImpl>: The tree is not valid.");
312 template<
class GraphImpl>
315 return GraphImpl::isDirected();
318 template<
class GraphImpl>
325 template<
class GraphImpl>
331 template<
class GraphImpl>
335 throw Exception(
"TreeGraphImpl::rootAt: Tree is not Valid.");
337 GraphImpl::makeDirected();
339 GraphImpl::setRoot(newRoot);
344 template<
class GraphImpl>
351 GraphImpl::switchNodes(father, node);
355 template<
class GraphImpl>
360 GraphImpl::link(fatherNode, node);
364 template<
class GraphImpl>
369 GraphImpl::link(fatherNode, node, edgeId);
374 template<
class GraphImpl>
377 GraphImpl::link(node, sonNode);
381 template<
class GraphImpl>
384 GraphImpl::link(node, sonNode, edgeId);
388 template<
class GraphImpl>
394 std::vector<Graph::NodeId> sons =
getSons(GraphImpl::getRoot());
395 if (sons.size() != 2)
396 throw Exception(
"The root must have two sons to join them.");
397 GraphImpl::unlink(GraphImpl::getRoot(), sons.at(0));
398 GraphImpl::unlink(GraphImpl::getRoot(), sons.at(1));
399 GraphImpl::link(sons.at(0), sons.at(1));
400 GraphImpl::setRoot(sons.at(0));
402 GraphImpl::makeUndirected();
405 template<
class GraphImpl>
408 return GraphImpl::getOutgoingNeighbors(node);
411 template<
class GraphImpl>
414 return GraphImpl::getOutgoingEdges(node);
417 template<
class GraphImpl>
420 return GraphImpl::outgoingNeighborNodesIterator(node);
423 template<
class GraphImpl>
426 return GraphImpl::outgoingNeighborNodesIterator(node);
429 template<
class GraphImpl>
432 return GraphImpl::outgoingEdgesIterator(node);
435 template<
class GraphImpl>
438 return GraphImpl::outgoingEdgesIterator(node);
441 template<
class GraphImpl>
444 return GraphImpl::getNumberOfOutgoingNeighbors(node);
447 template<
class GraphImpl>
450 std::vector<Graph::NodeId> sons =
getSons(node);
451 for (std::vector<Graph::NodeId>::iterator currSon = sons.begin(); currSon != sons.end(); currSon++)
458 template<
class GraphImpl>
461 GraphImpl::unlink(node, son);
465 template<
class GraphImpl>
475 template<
class GraphImpl>
478 GraphImpl::nodeMustExist_(nodeA);
479 GraphImpl::nodeMustExist_(nodeB);
480 std::vector<Graph::NodeId> path;
481 std::vector<Graph::NodeId> pathMatrix1;
482 std::vector<Graph::NodeId> pathMatrix2;
487 pathMatrix1.push_back(nodeUp);
490 pathMatrix1.push_back(nodeUp);
495 pathMatrix2.push_back(nodeUp);
498 pathMatrix2.push_back(nodeUp);
501 size_t tmp1 = pathMatrix1.size();
502 size_t tmp2 = pathMatrix2.size();
504 while ((tmp1 > 0) && (tmp2 > 0))
506 if (pathMatrix1[tmp1 - 1] != pathMatrix2[tmp2 - 1])
512 for (
size_t y = 0; y < tmp1; ++y)
514 path.push_back(pathMatrix1[y]);
517 path.push_back(pathMatrix1[tmp1]);
518 for (
size_t j = tmp2; j > 0; --j)
520 path.push_back(pathMatrix2[j - 1]);
525 template<
class GraphImpl>
528 std::vector<Graph::EdgeId> path;
530 for (
size_t currNodeNr = 0; currNodeNr + 1 < pathNodes.size(); currNodeNr++)
532 path.push_back(GraphImpl::getAnyEdge(pathNodes.at(currNodeNr), pathNodes.at(currNodeNr + 1)));
537 template<
class GraphImpl>
541 std::vector<Graph::EdgeId> metNodes;
546 template<
class GraphImpl>
550 std::vector<Graph::EdgeId> metEdges;
556 template<
class GraphImpl>
559 metNodes.push_back(localRoot);
560 std::vector<Graph::NodeId> sons = GraphImpl::getOutgoingNeighbors(localRoot);
561 for (std::vector<Graph::NodeId>::iterator currSon = sons.begin(); currSon != sons.end(); currSon++)
567 template<
class GraphImpl>
570 std::vector<Graph::EdgeId> edgesToSons = GraphImpl::getOutgoingEdges(localRoot);
571 for (std::vector<Graph::EdgeId>::iterator currEdgeToSon = edgesToSons.begin(); currEdgeToSon != edgesToSons.end(); currEdgeToSon++)
573 metEdges.push_back(*currEdgeToSon);
578 template<
class GraphImpl>
583 size_t nbnodes = nodes.size();
592 auto fathers = std::make_shared<std::map<Graph::NodeId, unsigned int>>();
593 auto sons = std::make_shared<std::map<Graph::NodeId, unsigned int>>();
595 for (
auto nodeid:nodes)
600 while (sons->size() > 1)
603 for (
auto son:(*sons))
607 if (fathers->find(here) == fathers->end())
608 (*fathers)[here] = son.second;
610 (*fathers)[here] += son.second;
612 if ((*fathers)[here] == nbnodes)
622 throw Exception(
"TreeGraphImpl::MRCA not found");
625 #endif // BPP_GRAPH_TREEGRAPHIMPL_H void setFather(Graph::NodeId node, Graph::NodeId fatherNode)
void removeSon(Graph::NodeId node, Graph::NodeId son)
void mustBeValid_() const
std::unique_ptr< Graph::EdgeIterator > branchesIterator(Graph::NodeId node)
std::vector< Graph::NodeId > getSubtreeNodes(Graph::NodeId localRoot) const
std::vector< Graph::NodeId > getNodePathBetweenTwoNodes(Graph::NodeId nodeA, Graph::NodeId nodeB, bool includeAncestor=true) const
void fillSubtreeMetNodes_(std::vector< Graph::NodeId > &metNodes, Graph::NodeId localRoot) const
bool isLeaf(Graph::NodeId node) const
void unRoot(bool joinRootSons)
void topologyHasChanged_() const
TreeGraphImpl< GlobalGraph > TreeGlobalGraph
std::unique_ptr< Graph::NodeIterator > sonsIterator(Graph::NodeId node)
std::vector< Graph::EdgeId > getBranches(Graph::NodeId node) const
bool hasFather(Graph::NodeId node) const
std::vector< Graph::NodeId > getSons(Graph::NodeId node) const
void setOutGroup(Graph::NodeId newOutGroup)
virtual std::vector< NodeId > getIncomingNeighbors(NodeId node) const =0
std::vector< Graph::EdgeId > getSubtreeEdges(Graph::NodeId localRoot) const
Graph::NodeId MRCA(const std::vector< Graph::NodeId > &nodes) const
Graph::EdgeId getEdgeToFather(Graph::NodeId node) const
size_t getNumberOfSons(Graph::NodeId node) const
Get the number of sons node.
virtual EdgeId getEdge(NodeId nodeA, NodeId nodeB) const =0
void rootAt(Graph::NodeId newRoot)
Graph::NodeId getFatherOfNode(Graph::NodeId nodeid) const
virtual void deleteNode(NodeId node)=0
void propagateDirection_(Graph::NodeId node)
Exception base class. Overload exception constructor (to control the exceptions mechanism). Destructor is already virtual (from std::exception)
std::vector< Graph::NodeId > removeSons(Graph::NodeId node)
void fillListOfLeaves_(Graph::NodeId startingNode, std::vector< Graph::NodeId > &foundLeaves) const
void mustBeRooted_() const
std::string toString(T t)
General template method to convert to a string.
virtual NodeId getRoot() const =0
std::vector< Graph::NodeId > getLeavesUnderNode(Graph::NodeId node) const
void fillSubtreeMetEdges_(std::vector< Graph::EdgeId > &metEdges, Graph::NodeId localRoot) const
std::vector< Graph::EdgeId > getEdgePathBetweenTwoNodes(Graph::NodeId nodeA, Graph::NodeId nodeB) const
void addSon(Graph::NodeId node, Graph::NodeId sonNode)