本文整理汇总了C++中TreeTemplate::rootAt方法的典型用法代码示例。如果您正苦于以下问题:C++ TreeTemplate::rootAt方法的具体用法?C++ TreeTemplate::rootAt怎么用?C++ TreeTemplate::rootAt使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类TreeTemplate
的用法示例。
在下文中一共展示了TreeTemplate::rootAt方法的2个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: getBestRootInSubtree_
void TreeTemplateTools::getBestRootInSubtree_(TreeTemplate<Node>& tree, short criterion, Node* node, pair<Node*, map<string, double> >& bestRoot)
{
const vector<Node*> sons = node->getSons(); // copy
tree.rootAt(node);
// Try to place the root on each branch downward node
for (vector<Node*>::const_iterator son = sons.begin(); son != sons.end(); ++son)
{
// Compute the moment of the subtree on son's side
Moments_ son_moment = getSubtreeMoments_(*son);
// Compute the moment of the subtree on node's side
tree.rootAt(*son);
Moments_ node_moment = getSubtreeMoments_(node);
tree.rootAt(node);
/*
* Get the position of the root on this branch that
* minimizes the root-to-leaves distances variance.
*
* This variance can be written in the form A x^2 + B x + C
*/
double min_criterion_value;
double best_position; // 0 is toward the root, 1 is away from it
const TreeTemplateTools::Moments_& m1 = node_moment;
const TreeTemplateTools::Moments_& m2 = son_moment;
const double d = (**son).getDistanceToFather();
const double n1 = m1.numberOfLeaves;
const double n2 = m2.numberOfLeaves;
double A = 0, B = 0, C = 0;
if (criterion == MIDROOT_SUM_OF_SQUARES)
{
A = (n1 + n2) * d * d;
B = 2 * d * (m1.sum - m2.sum) - 2 * n2 * d * d;
C = m1.squaresSum + m2.squaresSum
+ 2 * m2.sum * d
+ n2 * d * d;
}
else if (criterion == MIDROOT_VARIANCE)
{
A = 4 * n1 * n2 * d * d;
B = 4 * d * ( n2 * m1.sum - n1 * m2.sum - d * n1 * n2);
C = (n1 + n2) * (m1.squaresSum + m2.squaresSum) + n1 * d * n2 * d
+ 2 * n1 * d * m2.sum - 2 * n2 * d * m1.sum
- (m1.sum + m2.sum) * (m1.sum + m2.sum);
}
if (A < 1e-20)
{
min_criterion_value = numeric_limits<double>::max();
best_position = 0.5;
}
else
{
min_criterion_value = C - B * B / (4 * A);
best_position = -B / (2 * A);
if (best_position < 0)
{
best_position = 0;
min_criterion_value = C;
}
else if (best_position > 1)
{
best_position = 1;
min_criterion_value = A + B + C;
}
}
// Is this branch is the best seen, update 'bestRoot'
if (min_criterion_value < bestRoot.second["score"])
{
bestRoot.first = *son;
bestRoot.second["position"] = best_position;
bestRoot.second["score"] = min_criterion_value;
}
// Recurse
TreeTemplateTools::getBestRootInSubtree_(tree, criterion, *son, bestRoot);
}
}
示例2: midRoot
void TreeTemplateTools::midRoot(TreeTemplate<Node>& tree, short criterion, bool forceBranchRoot)
{
if (criterion != MIDROOT_VARIANCE && criterion != MIDROOT_SUM_OF_SQUARES)
throw Exception("TreeTemplateTools::midRoot(). Illegal criterion value '" + TextTools::toString(criterion) + "'");
if (tree.isRooted())
tree.unroot();
Node* ref_root = tree.getRootNode();
//
// The bestRoot object records :
// -- the current best branch : .first
// -- the current best value of the criterion : .second["value"]
// -- the best position of the root on the branch : .second["position"]
// 0 is toward the original root, 1 is away from it
//
pair<Node*, map<string, double> > best_root_branch;
best_root_branch.first = ref_root; // nota: the root does not correspond to a branch as it has no father
best_root_branch.second ["position"] = -1;
best_root_branch.second ["score"] = numeric_limits<double>::max();
// find the best root
getBestRootInSubtree_(tree, criterion, ref_root, best_root_branch);
tree.rootAt(ref_root); // back to the original root
// reroot
const double pos = best_root_branch.second["position"];
if (pos < 1e-6 or pos > 1 - 1e-6)
// The best root position is on a node (this is often the case with the sum of squares criterion)
tree.rootAt(pos < 1e-6 ? best_root_branch.first->getFather() : best_root_branch.first);
else
// The best root position is somewhere on a branch (a new Node is created)
{
Node* new_root = new Node();
new_root->setId( TreeTools::getMPNUId(tree, tree.getRootId()) );
double root_branch_length = best_root_branch.first->getDistanceToFather();
Node* best_root_father = best_root_branch.first->getFather();
best_root_father->removeSon(best_root_branch.first);
best_root_father->addSon(new_root);
new_root->addSon(best_root_branch.first);
new_root->setDistanceToFather(max(pos * root_branch_length, 1e-6));
best_root_branch.first->setDistanceToFather(max((1 - pos) * root_branch_length, 1e-6));
// The two branches leaving the root must have the same branch properties
const vector<string> branch_properties = best_root_branch.first->getBranchPropertyNames();
for (vector<string>::const_iterator p = branch_properties.begin(); p != branch_properties.end(); ++p)
{
new_root->setBranchProperty(*p, *best_root_branch.first->getBranchProperty(*p));
}
tree.rootAt(new_root);
}
if (forceBranchRoot) // if we want the root to be on a branch, not on a node
{
Node* orig_root = tree.getRootNode();
vector<Node*> root_sons = orig_root->getSons();
if (root_sons.size() > 2)
{
Node* nearest = root_sons.at(0);
for (vector<Node*>::iterator n = root_sons.begin(); n !=
root_sons.end(); ++n)
{
if ((**n).getDistanceToFather() < nearest->getDistanceToFather())
nearest = *n;
}
const double d = nearest->getDistanceToFather();
Node* new_root = new Node();
new_root->setId( TreeTools::getMPNUId(tree, tree.getRootId()) );
orig_root->removeSon(nearest);
orig_root->addSon(new_root);
new_root->addSon(nearest);
new_root->setDistanceToFather(d / 2.);
nearest->setDistanceToFather(d / 2.);
const vector<string> branch_properties = nearest->getBranchPropertyNames();
for (vector<string>::const_iterator p = branch_properties.begin(); p != branch_properties.end(); ++p)
{
new_root->setBranchProperty(*p, *nearest->getBranchProperty(*p));
}
tree.rootAt(new_root);
}
}
}