41 #ifndef BPP_GRAPH_TREEGRAPHIMPL_H
42 #define BPP_GRAPH_TREEGRAPHIMPL_H
49 #include "../Exceptions.h"
50 #include "../Numeric/VectorTools.h"
56 template<
class GraphImpl>
220 void unRoot(
bool joinRootSons);
264 template<
class GraphImpl>
271 template<
class GraphImpl>
274 return isValid_ || validate_();
277 template<
class GraphImpl>
280 std::vector<Graph::NodeId> incomers = getIncomingNeighbors(node);
281 if (incomers.size() > 1)
282 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.");
283 if (incomers.size() == 0)
285 return *incomers.begin();
288 template<
class GraphImpl>
292 return GraphImpl::getEdge(father, node);
295 template<
class GraphImpl>
298 return GraphImpl::getNumberOfIncomingNeighbors(node) >= 1;
301 template<
class GraphImpl>
304 return (!GraphImpl::isDirected() && GraphImpl::getNumberOfOutgoingNeighbors(node) <= 1)
305 || (GraphImpl::isDirected() && GraphImpl::getNumberOfOutgoingNeighbors(node) == 0);
308 template<
class GraphImpl>
311 const std::vector<Graph::NodeId> sons = getSons(startingNode);
314 for (std::vector<Graph::NodeId>::const_iterator currNeighbor = sons.begin(); currNeighbor != sons.end(); currNeighbor++)
316 fillListOfLeaves_(*currNeighbor, foundLeaves);
321 foundLeaves.push_back(startingNode);
325 template<
class GraphImpl>
328 std::vector<Graph::NodeId> foundLeaves;
329 fillListOfLeaves_(node, foundLeaves);
334 template<
class GraphImpl>
338 throw Exception(
"TreeGraphImpl<GraphImpl>: The tree must be rooted.");
341 template<
class GraphImpl>
345 throw Exception(
"TreeGraphImpl<GraphImpl>: The tree is not valid.");
348 template<
class GraphImpl>
351 return GraphImpl::isDirected();
354 template<
class GraphImpl>
357 isValid_ = GraphImpl::isTree();
361 template<
class GraphImpl>
367 template<
class GraphImpl>
371 throw Exception(
"TreeGraphImpl::rootAt: Tree is not Valid.");
373 GraphImpl::makeDirected();
375 GraphImpl::setRoot(newRoot);
377 propagateDirection_(newRoot);
380 template<
class GraphImpl>
385 NodeId father = getFatherOfNode(node);
386 propagateDirection_(father);
387 GraphImpl::switchNodes(father, node);
391 template<
class GraphImpl>
395 GraphImpl::unlink(getFatherOfNode(node), node);
396 GraphImpl::link(fatherNode, node);
397 topologyHasChanged_();
400 template<
class GraphImpl>
404 GraphImpl::unlink(getFatherOfNode(node), node);
405 GraphImpl::link(fatherNode, node, edgeId);
406 topologyHasChanged_();
410 template<
class GraphImpl>
413 GraphImpl::link(node, sonNode);
414 topologyHasChanged_();
417 template<
class GraphImpl>
420 GraphImpl::link(node, sonNode, edgeId);
421 topologyHasChanged_();
424 template<
class GraphImpl>
430 std::vector<Graph::NodeId> sons = getSons(GraphImpl::getRoot());
431 if (sons.size() != 2)
432 throw Exception(
"The root must have two sons to join them.");
433 GraphImpl::unlink(GraphImpl::getRoot(), sons.at(0));
434 GraphImpl::unlink(GraphImpl::getRoot(), sons.at(1));
435 GraphImpl::link(sons.at(0), sons.at(1));
436 GraphImpl::setRoot(sons.at(0));
438 GraphImpl::makeUndirected();
441 template<
class GraphImpl>
444 return GraphImpl::getOutgoingNeighbors(node);
447 template<
class GraphImpl>
450 return GraphImpl::getOutgoingEdges(node);
453 template<
class GraphImpl>
456 return GraphImpl::outgoingNeighborNodesIterator(node);
459 template<
class GraphImpl>
462 return GraphImpl::outgoingNeighborNodesIterator(node);
465 template<
class GraphImpl>
468 return GraphImpl::outgoingEdgesIterator(node);
471 template<
class GraphImpl>
474 return GraphImpl::outgoingEdgesIterator(node);
477 template<
class GraphImpl>
480 return GraphImpl::getNumberOfOutgoingNeighbors(node);
483 template<
class GraphImpl>
486 std::vector<Graph::NodeId> sons = getSons(node);
487 for (std::vector<Graph::NodeId>::iterator currSon = sons.begin(); currSon != sons.end(); currSon++)
489 removeSon(node, *currSon);
494 template<
class GraphImpl>
497 GraphImpl::unlink(node, son);
498 topologyHasChanged_();
501 template<
class GraphImpl>
505 deleteNode(GraphImpl::getRoot());
507 Graph::NodeId newRoot = GraphImpl::createNodeFromEdge(getEdge(getFatherOfNode(newOutGroup), newOutGroup));
511 template<
class GraphImpl>
514 GraphImpl::nodeMustExist_(nodeA);
515 GraphImpl::nodeMustExist_(nodeB);
516 std::vector<Graph::NodeId> path;
517 std::vector<Graph::NodeId> pathMatrix1;
518 std::vector<Graph::NodeId> pathMatrix2;
521 while (hasFather(nodeUp))
523 pathMatrix1.push_back(nodeUp);
524 nodeUp = getFatherOfNode(nodeUp);
526 pathMatrix1.push_back(nodeUp);
529 while (hasFather(nodeUp))
531 pathMatrix2.push_back(nodeUp);
532 nodeUp = getFatherOfNode(nodeUp);
534 pathMatrix2.push_back(nodeUp);
537 size_t tmp1 = pathMatrix1.size();
538 size_t tmp2 = pathMatrix2.size();
540 while ((tmp1 > 0) && (tmp2 > 0))
542 if (pathMatrix1[tmp1 - 1] != pathMatrix2[tmp2 - 1])
548 for (
size_t y = 0; y < tmp1; ++y)
550 path.push_back(pathMatrix1[y]);
553 path.push_back(pathMatrix1[tmp1]);
554 for (
size_t j = tmp2; j > 0; --j)
556 path.push_back(pathMatrix2[j - 1]);
561 template<
class GraphImpl>
564 std::vector<Graph::EdgeId> path;
565 std::vector<Graph::NodeId> pathNodes = getNodePathBetweenTwoNodes(nodeA, nodeB,
true);
566 for (
size_t currNodeNr = 0; currNodeNr + 1 < pathNodes.size(); currNodeNr++)
568 path.push_back(GraphImpl::getAnyEdge(pathNodes.at(currNodeNr), pathNodes.at(currNodeNr + 1)));
573 template<
class GraphImpl>
577 std::vector<Graph::EdgeId> metNodes;
578 fillSubtreeMetNodes_(metNodes, localRoot);
582 template<
class GraphImpl>
586 std::vector<Graph::EdgeId> metEdges;
587 fillSubtreeMetEdges_(metEdges, localRoot);
592 template<
class GraphImpl>
595 metNodes.push_back(localRoot);
596 std::vector<Graph::NodeId> sons = GraphImpl::getOutgoingNeighbors(localRoot);
597 for (std::vector<Graph::NodeId>::iterator currSon = sons.begin(); currSon != sons.end(); currSon++)
599 fillSubtreeMetNodes_(metNodes, *currSon);
603 template<
class GraphImpl>
606 std::vector<Graph::EdgeId> edgesToSons = GraphImpl::getOutgoingEdges(localRoot);
607 for (std::vector<Graph::EdgeId>::iterator currEdgeToSon = edgesToSons.begin(); currEdgeToSon != edgesToSons.end(); currEdgeToSon++)
609 metEdges.push_back(*currEdgeToSon);
610 fillSubtreeMetEdges_(metEdges, GraphImpl::getBottom(*currEdgeToSon));
614 template<
class GraphImpl>
619 size_t nbnodes = nodes.size();
628 auto fathers = std::make_shared<std::map<Graph::NodeId, uint> >();
629 auto sons = std::make_shared<std::map<Graph::NodeId, uint> >();
631 for (
auto nodeid:nodes)
634 while (sons->size() > 1)
637 for (
auto son:(*sons))
639 Graph::NodeId here=(!hasFather(son.first))?son.first:getFatherOfNode(son.first);
641 if (fathers->find(here) == fathers->end())
642 (*fathers)[here] = son.second;
644 (*fathers)[here] += son.second;
646 if ((*fathers)[here] == nbnodes)
656 throw Exception(
"TreeGraphImpl::MRCA not found");
Exception base class. Overload exception constructor (to control the exceptions mechanism)....
std::unique_ptr< Graph::NodeIterator > sonsIterator(Graph::NodeId node)
void unRoot(bool joinRootSons)
void removeSon(Graph::NodeId node, Graph::NodeId son)
void rootAt(Graph::NodeId newRoot)
void addSon(Graph::NodeId node, Graph::NodeId sonNode)
void propagateDirection_(Graph::NodeId node)
Graph::EdgeId getEdgeToFather(Graph::NodeId node) const
std::unique_ptr< Graph::EdgeIterator > branchesIterator(Graph::NodeId node)
bool isLeaf(Graph::NodeId node) const
std::vector< Graph::NodeId > getSons(Graph::NodeId node) const
void fillListOfLeaves_(Graph::NodeId startingNode, std::vector< Graph::NodeId > &foundLeaves) const
std::vector< Graph::NodeId > getLeavesUnderNode(Graph::NodeId node) const
bool hasFather(Graph::NodeId node) const
std::vector< Graph::NodeId > getSubtreeNodes(Graph::NodeId localRoot) const
std::vector< Graph::NodeId > removeSons(Graph::NodeId node)
void topologyHasChanged_() const
void fillSubtreeMetNodes_(std::vector< Graph::NodeId > &metNodes, Graph::NodeId localRoot) const
std::vector< Graph::EdgeId > getSubtreeEdges(Graph::NodeId localRoot) const
void fillSubtreeMetEdges_(std::vector< Graph::EdgeId > &metEdges, Graph::NodeId localRoot) const
void mustBeRooted_() const
void setOutGroup(Graph::NodeId newOutGroup)
size_t getNumberOfSons(Graph::NodeId node) const
Get the number of sons node.
Graph::NodeId MRCA(const std::vector< Graph::NodeId > &nodes) const
void mustBeValid_() const
Graph::NodeId getFatherOfNode(Graph::NodeId nodeid) const
std::vector< Graph::EdgeId > getEdgePathBetweenTwoNodes(Graph::NodeId nodeA, Graph::NodeId nodeB) const
std::vector< Graph::NodeId > getNodePathBetweenTwoNodes(Graph::NodeId nodeA, Graph::NodeId nodeB, bool includeAncestor=true) const
void setFather(Graph::NodeId node, Graph::NodeId fatherNode)
std::vector< Graph::EdgeId > getBranches(Graph::NodeId node) const
std::string toString(T t)
General template method to convert to a string.
TreeGraphImpl< GlobalGraph > TreeGlobalGraph