void TreeNodeTest::test_constructor() { // 1. the node is null GUI_CHECK_THROW( TreeNode(CNode::Ptr(), nullptr, 0), FailedAssertion ); // 2. the row number is below 0 NGeneric::Ptr node(new NGeneric("MyNode", "MyType")); GUI_CHECK_THROW( TreeNode(node, nullptr, -1), FailedAssertion); // 3. everything is OK GUI_CHECK_NO_THROW( TreeNode(node, nullptr, 0) ); }
Result AVLTree::TreeInsert(char key, Arch* data) { TreeNode* y = NULL; TreeNode* x = root; while (x != NULL) { y = x; //если узел уже существует if (key == x->key) { //free(key); return EXIST; } // если новый ключ меньше текущего, то идем влево if (key != SuffixTree::LAST_CHARACTER && key < x->key) { x = x->left; } else { x = x->right; } } //нашли место для вставки,родителя TreeNode* z = (TreeNode*)malloc(sizeof(TreeNode)); //если память не выделена if (z == NULL) { //delete data; return MEMORY_ERROR; } *z = TreeNode(key, data); z->parent = y; //если дерево пустое if (y == NULL) { root = z; } else { // если новый ключ меньше родительского, то добавляем узел в левое поддерево if (key != SuffixTree::LAST_CHARACTER && key < y->key) { y->left = z; y->balance++; } // иначе в правое else { y->right = z; y->balance--; } //корректируем показатели сбалансированности в каждом узле CorrectInsertBalance(y); } count++; return OK; }
void ModelContainer::fillContainer(const AABSPTree<SubModel *>::Node& pNode, int &pSubModelPos, int &pTreeNodePos, int &pTrianglePos, Vector3& pLo, Vector3& pHi, Vector3& pFinalLo, Vector3& pFinalHi) { // TreeNode for the SubModel TreeNode treeNode = TreeNode(pNode.valueArray.size(), pSubModelPos); treeNode.setSplitAxis(pNode.splitAxis); treeNode.setSplitLocation(pNode.splitLocation); int currentTreeNodePos = pTreeNodePos++; Vector3 lo = Vector3(inf(),inf(),inf()); Vector3 hi = Vector3(-inf(),-inf(),-inf()); for (int i=0; i<pNode.valueArray.size(); i++) { G3D::_AABSPTree::Handle<SubModel*>* h= pNode.valueArray[i]; SubModel *m = h->value; memcpy(&getTreeNodes()[pTreeNodePos], &m->getTreeNode(0), sizeof(TreeNode) * m->getNNodes()); memcpy(&getTriangles()[pTrianglePos], &m->getTriangle(0), sizeof(TriangleBox) * m->getNTriangles()); SubModel newModel = SubModel(m->getNTriangles(), getTriangles(), pTrianglePos, m->getNNodes(), getTreeNodes(), pTreeNodePos); newModel.setReletiveBounds(m->getReletiveBounds().getLo(), m->getReletiveBounds().getHi()); newModel.setBasePosition(m->getBasePosition()); iSubModel[pSubModelPos++] = newModel; pTreeNodePos += m->getNNodes(); pTrianglePos += m->getNTriangles(); AABox box = m->getAABoxBounds(); lo = lo.min(box.low()); hi = hi.max(box.high()); pFinalLo = pFinalLo.min(lo); pFinalHi = pFinalHi.max(hi); } /* if(pNode.valueArray.size() == 0) { int xxx = 0; // just for the breakpoint } */ // get absolute bounds if(pNode.child[0] != 0) { treeNode.setChildPos(0, pTreeNodePos); fillContainer(*pNode.child[0], pSubModelPos, pTreeNodePos, pTrianglePos, lo, hi,pFinalLo,pFinalHi); } if(pNode.child[1] != 0) { treeNode.setChildPos(1, pTreeNodePos); fillContainer(*pNode.child[1], pSubModelPos, pTreeNodePos, pTrianglePos, lo, hi,pFinalLo,pFinalHi); } pLo = pLo.min(lo); pHi = pHi.max(hi); treeNode.setBounds(lo,hi); setTreeNode(treeNode, currentTreeNodePos); }
void TreeViewWidget::mouseMoveEvent(QMouseEvent *e) { double dx = e->x() - mousepos[0]; double dy = e->y() - mousepos[1]; mousepos[0] = e->x(); mousepos[1] = e->y(); ActionNode x; if (!onmove && (mode == Mode::MOVE || mode == Mode::ROTATE || mode == Mode::ZOOM)) { x.operation = ActionNode::ALTER; for (int i = 0; i < selectedList.size(); i++) { QString path = DBManager::Instance()->FindPathByTreeName(selectedList[i]->GetModelName()); TreeInfo info(selectedList[i]->GetModelName(), path); x.changedTrees.push_back(TreeNode(selectedList[i]->GetName(), info, selectedList[i]->GetPosition(), selectedList[i]->GetEulerAngles(), selectedList[i]->GetScale())); } thestack.PushToUndo(x); emit Pushed(); onmove = true; } switch(mode) { case Mode::MOVE: for(int i = 0;i<selectedList.size();i++) { selectedList[i]->Translate2D(QVector2D(dx, dy), -kx, ky); } break; case Mode::ROTATE: for(int i = 0;i<selectedList.size();i++) { selectedList[i]->Rotate(dy*0.5, QVector3D(1,0,0)); selectedList[i]->Rotate(dx*0.5, QVector3D(0,1,0)); } break; case Mode::ZOOM: if(shiftdown) { for(int i = 0;i<selectedList.size();i++) { selectedList[i]->Scale(QVector2D(selectedList[i]->GetScale().x() + dx*0.01, selectedList[i]->GetScale().y() + dx*0.01)); } } else { for(int i = 0;i<selectedList.size();i++) { selectedList[i]->Scale(QVector2D(selectedList[i]->GetScale().x() + dx*0.01, selectedList[i]->GetScale().y() - dy*0.01)); } } break; } update(); }
TreeNode *TreeDocument::AllocNode() { mNodeHeap.push_back(TreeNode()); TreeNode *t = &mNodeHeap.back(); t->mpDocument = this; return t; }
TreeNode* TreeNode::makeChild(std::string name, std::string value){ //TreeNode *node = getNode(name,value); //if (node != NULL) // return node; elements.push_back(TreeNode(this,name,value)); return &(elements[elements.size()-1]); }
int main(int argc, char const *argv[]) { TreeNode nodes[] = { TreeNode(1), // 0 TreeNode(2), TreeNode(2), // 1, 2 TreeNode(3), TreeNode(3), // 3, 4 TreeNode(4), TreeNode(4), // 5, 6 }; nodes[0].left = &nodes[1]; nodes[0].right = &nodes[2]; nodes[1].left = &nodes[3]; nodes[1].right = &nodes[5]; nodes[2].left = &nodes[6]; nodes[2].right = &nodes[4]; TreeNode *root = &nodes[0]; preorder_cout(root); serialize_tree("tmp.txt", root); TreeNode *read = deserialize_tree("tmp.txt"); preorder_cout(read); read = deserialize_tree(string("1 2 # # 3 4 # 5 # #")); preorder_cout(read); inorder_cout(read); return 0; }
int main(){ Solution sol; TreeNode root = TreeNode(1); TreeNode lft = TreeNode(2); TreeNode rgt = TreeNode(3); TreeNode llft = TreeNode(4); TreeNode lrgt = TreeNode(5); root.left = &lft; root.right = &rgt; lft.left = &llft; lft.right = &lrgt; vector<int> result; int NumArray[] = {4,5,2,3,1}; result =sol.postorderTraversal(&root); std::vector<int> exact (NumArray,NumArray + sizeof(NumArray)/ sizeof(int)) ; leettest(comp_vec(result,exact)==0); return 0; }
void SubModel::fillContainer(const AABSPTree<Triangle>::Node& pNode, int &pTreeNodePos, int &pTrianglePos, Vector3& pLo, Vector3& pHi) { TreeNode treeNode = TreeNode(pNode.valueArray.size(), pTrianglePos); treeNode.setSplitAxis(pNode.splitAxis); treeNode.setSplitLocation(pNode.splitLocation); int currentTreeNodePos = pTreeNodePos++; Vector3 lo = Vector3(inf(),inf(),inf()); Vector3 hi = Vector3(-inf(),-inf(),-inf()); for(int i=0;i<pNode.valueArray.size(); i++) { G3D::_AABSPTree::Handle<Triangle>* h= pNode.valueArray[i]; Triangle t = h->value; TriangleBox triangleBox = TriangleBox(t.vertex(0),t.vertex(1), t.vertex(2)); lo = lo.min(triangleBox.getBounds().getLo().getVector3()); hi = hi.max(triangleBox.getBounds().getHi().getVector3()); getTriangles()[pTrianglePos++] = triangleBox; } if(pNode.child[0] != 0) { treeNode.setChildPos(0, pTreeNodePos); fillContainer(*pNode.child[0], pTreeNodePos, pTrianglePos, lo, hi); } if(pNode.child[1] != 0) { treeNode.setChildPos(1, pTreeNodePos); fillContainer(*pNode.child[1], pTreeNodePos, pTrianglePos, lo, hi); } treeNode.setBounds(lo,hi); // get absolute bounds pLo = pLo.min(lo); pHi = pHi.max(hi); getTreeNodes()[currentTreeNodePos] = treeNode; }
Tree Transformer::getTree(const vector<string> tokens) { Tree tr; // create tree representation int tree_index = -1; string token; Tree::pre_order_iterator it = tr.begin(); string strippedToken; string prevSeen = ""; // previously seen token // in Radu's format, there are 4 token types to handle: // 1. (TOP~1~1 // 2. ) // 3. risk) // 4. -115.21142 for (unsigned int i = 0; i < tokens.size(); i++) { token = tokens[i]; if (token[0] == '(' && token != "()") // type 1: first char is open paren; ignore special case of (-LRB- () { if (prevSeen != "") return tr; prevSeen = token; } else if (token == ")") // type 2: close paren { if (prevSeen != "") return tr; it = tr.parent(it); // set it to its parent prevSeen = ""; } else if (token[token.length() - 1] == ')') // type 3: last char is close paren { if (prevSeen == "") return tr; prevSeen = prevSeen.substr(1); it = tr.append_child(it, TreeNode(prevSeen, tree_index--)); // append previously seen as parent strippedToken = token.substr(0, token.length() - 1); tr.append_child(it, TreeNode(strippedToken, tree_index--)); // append child but don't move it down it = tr.parent(it); // set it to its parent prevSeen = ""; } else { if (prevSeen != "") // type 4: number { prevSeen = prevSeen.substr(1); prevSeen = prevSeen.substr(0, prevSeen.find("~")); if (tr.empty()) { it = tr.set_head(TreeNode(prevSeen, tree_index--)); // set head if tree is empty } else { it = tr.append_child(it, TreeNode(prevSeen, tree_index--)); // append child and move it down } prevSeen = ""; } else { printWarning("unexpected token `" + token + "' encountered"); return tr; } } } return tr; }
void TreeViewWidget::keyPressEvent(QKeyEvent *e) { ActionNode x; switch (e->key()) { case Qt::Key_Left: if (!onmove && (mode == Mode::MOVE || mode == Mode::ROTATE || mode == Mode::ZOOM)) { x.operation = ActionNode::ALTER; for (int i = 0; i < selectedList.size(); i++) { QString path = DBManager::Instance()->FindPathByTreeName(selectedList[i]->GetModelName()); TreeInfo info(selectedList[i]->GetModelName(), path); x.changedTrees.push_back(TreeNode(selectedList[i]->GetName(), info, selectedList[i]->GetPosition(), selectedList[i]->GetEulerAngles(), selectedList[i]->GetScale())); } thestack.PushToUndo(x); emit Pushed(); onmove = true; } if (mode == Mode::MOVE) { for (int i = 0; i < selectedList.size(); i++) selectedList[i]->Translate(QVector3D(-0.5, 0.0, 0.0)); } else if (mode == Mode::ROTATE) { for (int i = 0; i < selectedList.size(); i++) selectedList[i]->Rotate(-15, QVector3D(0.0, 1.0, 0.0)); } else if (mode == Mode::ZOOM) { for (int i = 0; i < selectedList.size(); i++) selectedList[i]->Scale(QVector2D(0.9, 1.0)); } break; case Qt::Key_Right: if (!onmove && (mode == Mode::MOVE || mode == Mode::ROTATE || mode == Mode::ZOOM)) { x.operation = ActionNode::ALTER; for (int i = 0; i < selectedList.size(); i++) { QString path = DBManager::Instance()->FindPathByTreeName(selectedList[i]->GetModelName()); TreeInfo info(selectedList[i]->GetModelName(), path); x.changedTrees.push_back(TreeNode(selectedList[i]->GetName(), info, selectedList[i]->GetPosition(), selectedList[i]->GetEulerAngles(), selectedList[i]->GetScale())); } thestack.PushToUndo(x); emit Pushed(); onmove = true; } if (mode == Mode::MOVE) { for (int i = 0; i < selectedList.size(); i++) selectedList[i]->Translate(QVector3D(0.5, 0.0, 0.0)); } else if (mode == Mode::ROTATE) { for (int i = 0; i < selectedList.size(); i++) selectedList[i]->Rotate(15, QVector3D(0.0, 1.0, 0.0)); } else if (mode == Mode::ZOOM) { for (int i = 0; i < selectedList.size(); i++) selectedList[i]->Scale(QVector2D(1.1, 1.0)); } break; case Qt::Key_Up: if (!onmove && (mode == Mode::MOVE || mode == Mode::ROTATE || mode == Mode::ZOOM)) { x.operation = ActionNode::ALTER; for (int i = 0; i < selectedList.size(); i++) { QString path = DBManager::Instance()->FindPathByTreeName(selectedList[i]->GetModelName()); TreeInfo info(selectedList[i]->GetModelName(), path); x.changedTrees.push_back(TreeNode(selectedList[i]->GetName(), info, selectedList[i]->GetPosition(), selectedList[i]->GetEulerAngles(), selectedList[i]->GetScale())); } thestack.PushToUndo(x); emit Pushed(); onmove = true; } if (mode == Mode::MOVE) { for (int i = 0; i < selectedList.size(); i++) selectedList[i]->Translate(QVector3D(0.0, 0.5, 0.0)); } else if (mode == Mode::ROTATE) { for (int i = 0; i < selectedList.size(); i++) selectedList[i]->Rotate(-15, QVector3D(1.0, 0.0, 0.0)); } else if (mode == Mode::ZOOM) { for (int i = 0; i < selectedList.size(); i++) selectedList[i]->Scale(QVector2D(1.0, 0.9)); } break; case Qt::Key_Down: if (!onmove && (mode == Mode::MOVE || mode == Mode::ROTATE || mode == Mode::ZOOM)) { x.operation = ActionNode::ALTER; for (int i = 0; i < selectedList.size(); i++) { QString path = DBManager::Instance()->FindPathByTreeName(selectedList[i]->GetModelName()); TreeInfo info(selectedList[i]->GetModelName(), path); x.changedTrees.push_back(TreeNode(selectedList[i]->GetName(), info, selectedList[i]->GetPosition(), selectedList[i]->GetEulerAngles(), selectedList[i]->GetScale())); } thestack.PushToUndo(x); emit Pushed(); onmove = true; } if (mode == Mode::MOVE) { for (int i = 0; i < selectedList.size(); i++) selectedList[i]->Translate(QVector3D(0.0, -0.5, 0.0)); } else if (mode == Mode::ROTATE) { for (int i = 0; i < selectedList.size(); i++) selectedList[i]->Rotate(15, QVector3D(1.0, 0.0, 0.0)); } else if (mode == Mode::ZOOM) { for (int i = 0; i < selectedList.size(); i++) selectedList[i]->Scale(QVector2D(1.0, 1.1)); } break; case Qt::Key_Comma: if (!onmove && (mode == Mode::MOVE || mode == Mode::ROTATE || mode == Mode::ZOOM)) { x.operation = ActionNode::ALTER; for (int i = 0; i < selectedList.size(); i++) { QString path = DBManager::Instance()->FindPathByTreeName(selectedList[i]->GetModelName()); TreeInfo info(selectedList[i]->GetModelName(), path); x.changedTrees.push_back(TreeNode(selectedList[i]->GetName(), info, selectedList[i]->GetPosition(), selectedList[i]->GetEulerAngles(), selectedList[i]->GetScale())); } thestack.PushToUndo(x); emit Pushed(); onmove = true; } for (int i = 0; i < selectedList.size(); i++) selectedList[i]->Translate(QVector3D(0.0, 0.0, -0.5)); break; case Qt::Key_Period: if (!onmove && (mode == Mode::MOVE || mode == Mode::ROTATE || mode == Mode::ZOOM)) { x.operation = ActionNode::ALTER; for (int i = 0; i < selectedList.size(); i++) { QString path = DBManager::Instance()->FindPathByTreeName(selectedList[i]->GetModelName()); TreeInfo info(selectedList[i]->GetModelName(), path); x.changedTrees.push_back(TreeNode(selectedList[i]->GetName(), info, selectedList[i]->GetPosition(), selectedList[i]->GetEulerAngles(), selectedList[i]->GetScale())); } thestack.PushToUndo(x); emit Pushed(); onmove = true; } for (int i = 0; i < selectedList.size(); i++) selectedList[i]->Translate(QVector3D(0.0, 0.0, 0.5)); break; case Qt::Key_G: LoadBGImage("bg2.jpg"); break; case Qt::Key_Control: groupSelecting = true; break; case Qt::Key_Shift: shiftdown = true; break; case Qt::Key_Delete: x.operation = ActionNode::REMOVE; for(int i=0;i<selectedList.size();i++) { QString path = DBManager::Instance()->FindPathByTreeName(selectedList[i]->GetModelName()); TreeInfo info(selectedList[i]->GetModelName(), path); x.changedTrees.push_back(TreeNode(selectedList[i]->GetName(), info, selectedList[i]->GetPosition(), selectedList[i]->GetEulerAngles(), selectedList[i]->GetScale())); RemoveTree(selectedList[i]->Name()); } thestack.PushToUndo(x); emit Pushed(); selectedList.clear(); break; case Qt::Key_X: /*debug*/ ClearAllTrees(); /*debug*/ break; } update(); }
}; std::pair<bool, int> process(Ptr head) { if (!head) return { true, 0 }; auto leftData = process(head->left); if (!leftData.first) return { false, 0 }; auto rightData = process(head->right); if (!rightData.first) return { false, 0 }; if (std::abs(rightData.first - leftData.first) > 1) return { false, 0 }; return { true, std::max(leftData.second, rightData.second) + 1 }; } int main(){ typename Ptr head(new TreeNode(5)); //不加typename,编译器会推断为函数声明 head->left = std::make_shared<TreeNode>(TreeNode(3)); head->right = std::make_shared<TreeNode>(TreeNode(8)); head->left->left = std::make_shared<TreeNode>(TreeNode(2)); head->left->right = std::make_shared<TreeNode>(TreeNode(4)); head->left->left->left = std::make_shared<TreeNode>(TreeNode(3)); head->right->left = std::make_shared<TreeNode>(TreeNode(7)); head->right->left->left = std::make_shared<TreeNode>(TreeNode(6)); head->right->right = std::make_shared<TreeNode>(TreeNode(10)); head->right->right->left = std::make_shared<TreeNode>(TreeNode(9)); head->right->right->right = std::make_shared<TreeNode>(TreeNode(11)); std::cout << process(head).first << std::endl; }
void Tree::Update() { //NOTE: chosen_index cannot be 0, because 0 denotes 'no-one here' in the grid const int chosen_index { 1 + m_rnd.GetRandomInt(m_active.size() - 1 - 1) }; assert(IsValid(chosen_index,m_active)); TreeDataPoint& chosen = m_active[chosen_index]; //Remove active indidual from old spot { const int x = chosen.GetXpos(); const int y = chosen.GetYpos(); m_grid[x][y] = nullptr; } //? m_richness += m_min_speciation_rate*(chosen.GetProbability()); //Do the move, also tracks that the lineage did not speciate const std::pair<int,int> move{GetMove(m_dispersal_kernel,m_rnd,m_dispersal_distance)}; chosen.Move( move.first,move.second, m_min_speciation_rate ); //? //assert(IsValid(chosen.GetMpos(),m_nodes)); chosen.GetNode()->IncreaseBranchLength(); const int to_x = chosen.GetXpos(); const int to_y = chosen.GetYpos(); assert(IsValid(to_x,to_y,m_grid)); GridType& grid_spot_to{m_grid[to_x][to_y]}; //If there an individual at the dispersed-to spot? if (grid_spot_to == nullptr) { //Just move the individual grid_spot_to = &chosen; //Nope, this timestep is done return; } //Remove active indidual from old spot //m_grid[from_x][from_y] = nullptr; //There is an individual at the dispersed-to-spot //Let these two coalesce //Create a new node to celebrate this event m_nodes.push_back( TreeNode( chosen.GetNode(), grid_spot_to->GetNode() ) ); TreeNode * const new_node { &m_nodes.back() }; chosen.GetNode()->SetParent(new_node); grid_spot_to->GetNode()->SetParent(new_node); grid_spot_to->SetNode(new_node); const double probability{ chosen.GetProbability() + grid_spot_to->GetProbability() * (1.0-chosen.GetProbability()) }; grid_spot_to->SetProbability(probability); //Overwrite chosen by last TreeDataPoint& last = m_active.back(); chosen = last; const int last_x = last.GetXpos(); const int last_y = last.GetYpos(); assert(IsValid(last_x,last_y,m_grid)); GridType& last_active_spot = m_grid[last_x][last_y]; if (last_active_spot == &last) { last_active_spot = &chosen; } m_active.pop_back(); }
void Tree::buildByUPGMA (const vguard<string>& nodeName, const vguard<vguard<TreeBranchLength> >& distanceMatrix) { // check that there are more than 2 nodes Assert (nodeName.size() >= 2, "Fewer than 2 nodes; can't make a binary tree"); // clear the existing tree node.clear(); // copy distance matrix vguard<vguard<TreeBranchLength> > dist = distanceMatrix; // estimate tree by UPGMA // first, initialise the list of active nodes set<TreeNodeIndex> activeNodes; for (TreeNodeIndex n = 0; n < (int) nodeName.size(); ++n) { activeNodes.insert (n); node.push_back (TreeNode()); node.back().name = nodeName[n]; node.back().parent = -1; } // main loop vguard<TreeBranchLength> nodeHeight (nodeName.size(), 0); while (true) { // get number of active nodes const int nActiveNodes = activeNodes.size(); // loop exit test if (nActiveNodes == 2) break; Assert (nActiveNodes > 2, "Fewer than 2 nodes left -- should never get here"); // find closest two nodes bool isFirstPair = true; TreeBranchLength minDist = 0; TreeNodeIndex min_i = -1, min_j = -1; set<TreeNodeIndex>::const_iterator node_i_p, node_j_p, activeNodes_end_p; activeNodes_end_p = activeNodes.end(); for (node_i_p = activeNodes.begin(); node_i_p != activeNodes_end_p; ++node_i_p) for (node_j_p = node_i_p, ++node_j_p; node_j_p != activeNodes_end_p; ++node_j_p) { const TreeBranchLength d = dist [*node_i_p] [*node_j_p]; if (isFirstPair || d < minDist) { min_i = *node_i_p; min_j = *node_j_p; minDist = d; isFirstPair = false; } } // nodes min_i and min_j are neighbors -- join them with new index k // first, calculate new distances const TreeNodeIndex k = nodes(); dist.push_back (vguard<TreeBranchLength> (k + 1)); dist[k][k] = 0; const TreeBranchLength d_ij = dist[min_i][min_j]; nodeHeight.push_back (max (nodeHeight[min_i] + minBranchLength, max (nodeHeight[min_j] + minBranchLength, (nodeHeight[min_i] + nodeHeight[min_j] + d_ij) / 2))); const TreeBranchLength d_ik = nodeHeight[k] - nodeHeight[min_i]; const TreeBranchLength d_jk = nodeHeight[k] - nodeHeight[min_j]; for (TreeNodeIndex m = 0; m < k; ++m) dist[m].push_back (dist[k][m] = (dist[min_i][m] + dist[min_j][m]) / 2); dist[min_i][k] = dist[k][min_i] = d_ik; dist[min_j][k] = dist[k][min_j] = d_jk; // now update the Tree node.push_back (TreeNode()); node[k].child.push_back (min_i); node[k].child.push_back (min_j); node[min_i].parent = k; node[min_i].d = max (0., d_ik); node[min_j].parent = k; node[min_j].d = max (0., d_jk); LogThisAt(7,"Joining nodes " << min_i << " and " << min_j << " to common ancestor " << k << " (branch lengths: " << k << "->" << min_i << " = " << d_ik << ", " << k << "->" << min_j << " = " << d_jk << ")" << endl); activeNodes.erase (min_i); activeNodes.erase (min_j); activeNodes.insert (k); } // make the root node set<TreeNodeIndex>::iterator iter = activeNodes.begin(); const TreeNodeIndex i = *iter; const TreeNodeIndex j = *++iter; const TreeNodeIndex k = node.size(); nodeHeight.push_back (max (nodeHeight[i] + minBranchLength, max (nodeHeight[j] + minBranchLength, (nodeHeight[i] + nodeHeight[j] + dist[i][j]) / 2))); node.push_back (TreeNode()); node[k].parent = -1; node[k].child.push_back (i); node[k].child.push_back (j); node[i].parent = k; node[i].d = max (0., nodeHeight[k] - nodeHeight[i]); node[j].parent = k; node[j].d = max (0., nodeHeight[k] - nodeHeight[j]); const string s = toString(); LogThisAt(5,"UPGMA tree: " << s << endl); parse (s); // to ensure consistency (i.e. serializing & deserializing will not change node indices) assertUltrametric(); }
void Tree::buildByNeighborJoining (const vguard<string>& nodeName, const vguard<vguard<TreeBranchLength> >& distanceMatrix) { // check that there are more than 2 nodes Assert (nodeName.size() >= 2, "Fewer than 2 nodes; can't make a binary tree"); // clear the existing tree node.clear(); // copy distance matrix vguard<vguard<TreeBranchLength> > dist = distanceMatrix; // estimate tree by neighbor-joining // algorithm follows description in Durbin et al, pp170-171 // first, initialise the list of active nodes set<TreeNodeIndex> activeNodes; for (TreeNodeIndex n = 0; n < (int) nodeName.size(); ++n) { activeNodes.insert (n); node.push_back (TreeNode()); node.back().name = nodeName[n]; node.back().parent = -1; } // main loop vguard<TreeBranchLength> avgDist; while (true) { // get number of active nodes const int nActiveNodes = activeNodes.size(); // loop exit test if (nActiveNodes == 2) break; Assert (nActiveNodes > 2, "Fewer than 2 nodes left -- should never get here"); // calculate average distances from each node avgDist = vguard<TreeBranchLength> (nodes(), (double) 0); for (auto ni : activeNodes) { double a_i = 0; for (auto nj : activeNodes) if (nj != ni) a_i += dist[ni][nj]; avgDist[ni] = a_i / (double) (nActiveNodes - 2); LogThisAt(7,"Distance correction for node " << ni << " is " << avgDist[ni] << endl); } // find minimal compensated distance (with avg distances subtracted off) bool isFirstPair = true; TreeBranchLength minDist = 0; TreeNodeIndex min_i = -1, min_j = -1; set<TreeNodeIndex>::const_iterator node_i_p, node_j_p, activeNodes_end_p; activeNodes_end_p = activeNodes.end(); for (node_i_p = activeNodes.begin(); node_i_p != activeNodes_end_p; ++node_i_p) for (node_j_p = node_i_p, ++node_j_p; node_j_p != activeNodes_end_p; ++node_j_p) { const double compensatedDist = dist [*node_i_p] [*node_j_p] - avgDist [*node_i_p] - avgDist [*node_j_p]; LogThisAt(7,"Compensated distance from node " << *node_i_p << " to node " << *node_j_p << " is " << compensatedDist << endl); if (isFirstPair || compensatedDist < minDist) { min_i = *node_i_p; min_j = *node_j_p; minDist = compensatedDist; isFirstPair = false; } } // nodes min_i and min_j are neighbors -- join them with new index k // first, calculate new distances as per NJ algorithm const TreeNodeIndex k = nodes(); dist.push_back (vguard<TreeBranchLength> (k + 1)); dist[k][k] = 0; const TreeBranchLength d_ij = dist[min_i][min_j]; for (TreeNodeIndex m = 0; m < k; ++m) dist[m].push_back (dist[k][m] = 0.5 * (dist[min_i][m] + dist[min_j][m] - d_ij)); TreeBranchLength d_ik = 0.5 * (d_ij + avgDist[min_i] - avgDist[min_j]); TreeBranchLength d_jk = d_ij - d_ik; LogThisAt(8,"Before Kuhner-Felsenstein:\ni=" << min_i << ", j=" << min_j << ", k=" << k << ", d_ij=" << d_ij << ", d_ik=" << d_ik << ", d_jk=" << d_jk << "\nDistances from k to other nodes: " << to_string_join(dist[k]) << endl); // apply Kuhner-Felsenstein correction to prevent negative branch lengths // also enforce minimum branch lengths here if (d_ik < minBranchLength) { d_jk -= d_ik - minBranchLength; d_ik = minBranchLength; } if (d_jk < 0) { d_ik -= d_jk - minBranchLength; d_jk = minBranchLength; } dist[min_i][k] = dist[k][min_i] = d_ik; dist[min_j][k] = dist[k][min_j] = d_jk; // now update the Tree node.push_back (TreeNode()); node[k].child.push_back (min_i); node[k].child.push_back (min_j); node[min_i].parent = k; node[min_i].d = max (0., d_ik); node[min_j].parent = k; node[min_j].d = max (0., d_jk); LogThisAt(7,"Joining nodes " << min_i << " and " << min_j << " to common ancestor " << k << " (branch lengths: " << k << "->" << min_i << " = " << d_ik << ", " << k << "->" << min_j << " = " << d_jk << ")" << endl); activeNodes.erase (min_i); activeNodes.erase (min_j); activeNodes.insert (k); } // make the root node set<TreeNodeIndex>::iterator iter = activeNodes.begin(); const TreeNodeIndex i = *iter; const TreeNodeIndex j = *++iter; const double d = max (dist[i][j], 0.); // don't correct the last node, just keep branch length non-negative const TreeNodeIndex k = node.size(); node.push_back (TreeNode()); node[k].parent = -1; node[k].child.push_back (i); node[k].child.push_back (j); node[i].parent = k; node[i].d = max (0., d/2); node[j].parent = k; node[j].d = max (0., d/2); const string s = toString(); LogThisAt(5,"Neighbor-joining tree: " << s << endl); parse (s); // to ensure consistency (i.e. serializing & deserializing will not change node indices) }
void Pdb::TreeExpand(int node) { if(tree.GetChildCount(node)) return; Value v = tree.Get(node); if(!v.Is<NamedVal>()) return; const NamedVal& nv = ValueTo<NamedVal>(tree.Get(node)); Val val = nv.val; if(nv.val.ref > 0) { val = DeRef(val); if(val.type < 0 || val.ref > 0) { TreeNode(node, '*' + nv.name, val); SaveTree(); return; } } if(val.type < 0) { SaveTree(); return; } const Type& t = GetType(val.type); if(t.vtbl_typeindex == -2) { int count = GetSymInfo(t.modbase, type.GetKey(val.type), TI_GET_COUNT); Val prtti; prtti.ref = 1; prtti.type = UINT4; prtti.address = val.address - 4; Val rtti = GetRVal(prtti); FnInfo rtf = GetFnInfo(rtti.address); TreeNode(node, rtf.name, prtti); for(int i = 0; i < count; i++) { Val ventry; ventry.type = PFUNC; ventry.address = val.address + 4 * i; TreeNode(node, NFormat("[%d]", i), ventry); } return; } if(t.vtbl_typeindex >= 0) { Val vtbl; vtbl.ref = 1; vtbl.address = val.address + t.vtbl_offset; vtbl.type = t.vtbl_typeindex; TreeNode(node, "virtual", vtbl); /* Val vloc = GetRVal(vtbl); FnInfo vtbl_type = GetFnInfo(vloc.address); const char *p = vtbl_type.name, *e = p; while(*e && !(*e == ':' && e[1] == ':')) e++; String fullsym(p, e); FnInfo ffs = GetFnInfo(fullsym); if(ffs.pdbtype) { Val typeval; typeval.address = val.address; TypeVal(typeval, ffs.pdbtype, t.modbase); TreeNode(node, String().Cat() << '[' << ffs.name << ']', typeval); } */ } for(int i = 0; i < t.base.GetCount(); i++) { Val r = t.base[i]; r.address += val.address; if(r.type >= 0) { const Type& bt = GetType(r.type); TreeNode(node, bt.name, r); } } for(int i = 0; i < t.member.GetCount(); i++) { Val r = t.member[i]; r.address += val.address; TreeNode(node, t.member.GetKey(i), r); } for(int i = 0; i < t.static_member.GetCount(); i++) { Val r = t.static_member[i]; TreeNode(node, t.static_member.GetKey(i), r); } }
static TreeNode make (Args&& ... args) { return TreeNode (T (std::forward <Args> (args) ... )); }
Tree Transformer::getTTETree(const vector<string> tokens) { Tree tr; unsigned int i = 0; int tree_index = -1; Tree::pre_order_iterator it = tr.begin(); string strippedToken = tokens[i].substr(1); it = tr.insert(it, TreeNode(strippedToken, tree_index--)); // TODO: check if tokens index 0 exists i++; bool justCreated = false; // flag to signal blank labels string token; string label; int sibling_index; unsigned int div_index; for (; i < tokens.size(); i++) { token = tokens[i]; if (token[0] == '(') { strippedToken = token.substr(1); it = tr.append_child(it, TreeNode(strippedToken, tree_index--)); // append child and move it down justCreated = true; } else if (token == ")") { if (justCreated) { tr.append_child(it, TreeNode(blankLabel, tree_index--)); // insert blank label justCreated = false; } else { it = tr.parent(it); // set it to its parent } } else { // append child but don't move it down div_index = token.find(":"); if (div_index != string::npos) // has label (e.g., "x0:NN") { if (token[0] == 'x') { sibling_index = atoi(token.substr(1, div_index - 1).c_str()); label = token.substr(div_index + 1); tr.append_child(it, TreeNode(label, tree_index--, sibling_index)); } else { printWarning("token found with label but with no state"); continue; } } else // does not have label (e.g., "x0") { if (token[0] == 'x') // has state (e.g., "x0") { sibling_index = atoi(token.substr(1, div_index).c_str()); tr.append_child(it, TreeNode("", tree_index--, sibling_index)); } else // does not have state (e.g., "John") { tr.append_child(it, TreeNode(token, tree_index--)); } } justCreated = false; } } return tr; }
int main(int argc, const char * argv[]) { //Create the root node of the tree: KeyValuePair root_pair = KeyValuePair(8, "Node H"); TreeNode root = TreeNode(root_pair); //add some nodes to our tree TreeNode* node_a = new TreeNode(1, "Node A"); TreeNode* node_i = new TreeNode(9, "Node I"); TreeNode* node_b = new TreeNode(2, "Node B"); TreeNode* node_j = new TreeNode(10, "Node J"); root.setLeftChild(node_a); root.setRightChild(node_i); node_a->setRightChild(node_b); node_i->setRightChild(node_j); //------------------------------------------ // 1) Test the tree traversals: std::cout << "-------------------" << std::endl; std::cout << "Inorder Traversal:" << std::endl; root.printInOrder(); std::cout << std::endl; std::cout << "-------------------" << std::endl; std::cout << std::endl; std::cout << "-------------------" << std::endl; std::cout << "Preorder Traversal:" << std::endl; root.printPreOrder(); std::cout << std::endl; std::cout << "-------------------" << std::endl; std::cout << std::endl; std::cout << "-------------------" << std::endl; std::cout << "Postorder Traversal:" << std::endl; root.printPostOrder(); std::cout << std::endl; std::cout << "-------------------" << std::endl; std::cout << std::endl; //------------------------------------------ // 2) Test the searchkey function by searching for keys std::cout << "Searching: " << std::endl; std::cout << "-------------------" << std::endl; TreeNode* my_node_pntr = root.searchKey(10); std::cout << "Search for key 10 found: " << my_node_pntr->getPair()->getValue() << std::endl; //output should be Node J my_node_pntr = root.searchKey(3); std::cout << "Search for key 3 found: " << my_node_pntr->getPair()->getValue() << std::endl; // output should be Node B (because 3 isnt in the tree) //------------------------------------------ // 3) Test the add method by creating new keyvaluepairs and adding them to the tree // and after that, print again the inorder traversal, to see if the new nodes were added std::cout << std::endl; KeyValuePair* my_pair_pointer = new KeyValuePair(12, "Node L"); KeyValuePair* my_scnd_pair_pntr = new KeyValuePair(0, "Node 0"); root.add(my_pair_pointer); root.add(my_scnd_pair_pntr); std::cout << "updated Tree in inorder traversal:" << std::endl; std::cout << "-------------------" << std::endl; root.printInOrder(); //------------------------------------------ return 0; }
TreeNode::TreeNode(HTTPCSTR lpTreeNodeName) { TreeNode(lpTreeNodeName, NULL); }
// ----------------------------------------------------------------------------- TreeNode::TreeNode() { TreeNode(NULL, NULL); }