//------------------------------------------------------------------------------ // This code needs Tree to be a friend of Node void Tree::copyTraverse (NodePtr p1, NodePtr &p2) const { if (p1) { p2 = NewNode (); p1->Copy (p2); // Note the call to p2->child, not p2->GetChild(). Calling the field // is essential because calling GetChild merely passes a temporary // copy of the child, hence we are not actually creating a child of p2. // We can access child directly by making Tree a friend of Node (see // TreeLib.h). copyTraverse (p1->GetChild(), p2->Child); if (p2->GetChild()) p2->GetChild()->SetAnc (p2); // Ensure we don't copy RootedAt sibling. If the sibling is NULL then // we won't anyway, but this line ensures this for all cases. if (p1 != CurNode) copyTraverse (p1->GetSibling(), p2->Sib); // note sib if (p2->GetChild ()) { NodePtr q = p2->GetChild()->GetSibling(); while (q) { q->SetAnc (p2); q = q->GetSibling(); } } } }
//------------------------------------------------------------------------------ // Add Node below Below. Doesn't update any clusters, weights, etc. void Tree::AddNodeBelow (NodePtr Node, NodePtr Below) { NodePtr Ancestor = NewNode (); Ancestor->SetChild (Node); Node->SetAnc (Ancestor); NodePtr q = Below->GetAnc (); Internals++; if (Node->IsLeaf()) Leaves++; if (q == NULL || Below == q->GetChild()) { Node->SetSibling (Below); Ancestor->SetAnc (q); Ancestor->SetSibling (Below->GetSibling()); Below->SetSibling (NULL); Below->SetAnc (Ancestor); if (q == NULL) Root = Ancestor; else q->SetChild (Ancestor); } else { // Get left sibling of Below NodePtr r = Below->LeftSiblingOf(); while (Below != r->GetSibling()) r = r->GetSibling(); Node->SetSibling (Below); Ancestor->SetAnc (q); Ancestor->SetSibling (Below->GetSibling()); Below->SetSibling (NULL); Below->SetAnc (Ancestor); r->SetSibling (Ancestor); } }
//------------------------------------------------------------------------------ void Tree::drawAsTextTraverse (NodePtr p) { if (p) { drawAsTextTraverse (p->GetChild ()); if (p->IsLeaf ()) drawPendantEdge (p); if (p->GetSibling ()) drawInteriorEdge (p); drawAsTextTraverse (p->GetSibling ()); } }
//Added by BCO //------------------------------------------------------------------------------ void Tree::traversenoquote (NodePtr p) { if (p) { if (p->IsLeaf()) { for (int i=0; i<(NEXUSString (p->GetLabel())).length(); i++) { if ((NEXUSString (p->GetLabel()))[i]!= '\'') { *treeStream <<(NEXUSString (p->GetLabel()))[i]; } } //*treeStream<<NEXUSString (p->GetLabel()); if (EdgeLengths) { *treeStream << ':' << p->GetEdgeLength (); } } else { *treeStream << "("; } traversenoquote (p->GetChild()); if (p->GetSibling()) { *treeStream << ","; } else { if (p != Root) { *treeStream << ")"; // 29/3/96 if ((p->GetAnc()->GetLabel() != "") && InternalLabels) { *treeStream << NEXUSString (p->GetAnc()->GetLabel ()) ; //here's the change from traverse } if (EdgeLengths && (p->GetAnc () != Root)) { *treeStream << ':' << p->GetAnc()->GetEdgeLength (); } } } traversenoquote (p->GetSibling()); } }
//------------------------------------------------------------------------------ void Tree::makeNodeList (NodePtr p) { if (p) { makeNodeList (p->GetChild ()); makeNodeList (p->GetSibling ()); if (p->IsLeaf()) { int leafnumberposition=p->GetLeafNumber()-1;//modified by BCO string plabel=p->GetLabel(); //modified by BCO LeafList[plabel] = leafnumberposition; //modified by BCO assert((Leaves+Internals)>leafnumberposition); Nodes[leafnumberposition] = p; //modified by BCO p->SetIndex (leafnumberposition); //modified by BCO } else { Nodes[count] = p; p->SetIndex (count); count++; } if (p != Root) { } } }
//------------------------------------------------------------------------------ // Fill in weight, degree, etc. void Tree::buildtraverse (NodePtr p) { if (p) { p->SetWeight (0); /*p->SetModelCategory(vector<double>(1,1.0)); //added by BCO p->SetStateOrder(vector<int>(1,0)); //Added by BCO p->SetStateTimes(vector<double>(1,0.0)); //Added by BCO*/ p->SetDegree (0); buildtraverse (p->GetChild ()); buildtraverse (p->GetSibling ()); if (p->IsLeaf()) { Leaves++; p->SetWeight (1); /*p->SetModelCategory(vector<double>(1,1.0)); //Added by BCO p->SetStateOrder(vector<int>(1,0)); //Added by BCO p->SetStateTimes(vector<double>(1,0.0)); //Added by BCO*/ } else { Internals++; } if (p != Root) { p->GetAnc()->AddWeight (p->GetWeight()); p->GetAnc()->IncrementDegree(); } } }
//------------------------------------------------------------------------------ void Tree::markNodes(NodePtr p, bool on) { if (p) { p->SetMarked (on); markNodes (p->GetChild(), on); markNodes (p->GetSibling(), on); } }
//------------------------------------------------------------------------------ void Tree::deletetraverse (NodePtr p) { if (p) { deletetraverse (p->GetChild()); deletetraverse (p->GetSibling()); delete p; } }
//------------------------------------------------------------------------------ void Tree::traverse (NodePtr p) { if (p) { if (p->IsLeaf()) { *treeStream << NEXUSString (p->GetLabel()); if (EdgeLengths) { *treeStream << ':' << p->GetEdgeLength (); } } else { *treeStream << "("; } traverse (p->GetChild()); if (p->GetSibling()) { *treeStream << ","; } else { if (p != Root) { *treeStream << ")"; // 29/3/96 if ((p->GetAnc()->GetLabel() != "") && InternalLabels) { *treeStream << '\'' << NEXUSString (p->GetAnc()->GetLabel ()) << '\''; } if (EdgeLengths && (p->GetAnc () != Root)) { *treeStream << ':' << p->GetAnc()->GetEdgeLength (); } } } traverse (p->GetSibling()); } }
//------------------------------------------------------------------------------ void Tree::getNodeHeights(NodePtr p) { if (p) { p->SetHeight (Leaves - p->GetWeight ()); if (p->GetHeight() > MaxHeight) MaxHeight = p->GetHeight(); getNodeHeights (p->GetChild()); getNodeHeights (p->GetSibling()); } }
//------------------------------------------------------------------------------ void Tree::drawPendantEdge (NodePtr p) { NodePtr q = p->GetAnc(); if (q == NULL) { // Handle the degenerate case of a tree with a single leaf Line = (char) HBAR; drawLine (p); } else { int start = q->GetHeight(); int stop = p->GetHeight(); char symbol; // Draw line between p and its ancestor int i; for (i = start + 1; i <= stop; i++) Line[i] = (char)HBAR; // € // Find appropriate symbol for link to ancestor if (p == q->GetChild()) { symbol = (char)LEFT; // ò } else { // p is a sibling if (p->GetSibling()) symbol = (char)SIB; // Ì else symbol = (char)RIGHT; // Ë } Line[start] = symbol; // Fill in ancestors fillInAncestors (p); // Terminate line Line[stop + 1] = '\0'; drawLine (p); /* // Output line and taxon name *treeStream << Line.c_str() << " " << p->GetLabel () // << "h=" << p->GetHeight() << " w= " // << p->GetWeight() <<endl; */ // Clear the line for the next pass for (i = 0; i < (Leaves + 2); i++) // to do: get a better limit for this Line[i] = ' '; } }
//------------------------------------------------------------------------------ // Compute node depth (i.e, height above root). Based on COMPONENT 2.0 code, // assumes count is set to 0 prior to calling code void Tree::getNodeDepth(NodePtr p) { if (p) { p->SetDepth (count); count++; getNodeDepth (p->GetChild()); count--; getNodeDepth (p->GetSibling()); } }
//------------------------------------------------------------------------------ void TreeOrder::SortDescendants (NodePtr node) { NodePtr head = node->GetChild (); NodePtr tail = head; while (tail->GetSibling () != NULL) { NodePtr p = tail->GetSibling (); if (MustSwap (head, p)) { tail->SetSibling (p->GetSibling ()); p->SetSibling (head); head = p; p->GetAnc()->SetChild (p); } else { NodePtr q = head; NodePtr r = q->GetSibling (); while (MustSwap (p, r)) { q = r; r = q->GetSibling (); } if (p == r) tail = p; else { tail->SetSibling (p->GetSibling ()); p->SetSibling (r); q->SetSibling (p); } } } }
//------------------------------------------------------------------------------ // Compute nodal heights based on path length from root, and store maximum // value in plot.maxheight. Used by drawing routines. void Tree::getPathLengths (NodePtr p) { if (p) { if (p != Root) { float l = p->GetEdgeLength(); if (l < 0.000001) // suppress negative branch lengths l = 0.0; p->SetPathLength (p->GetAnc()->GetPathLength() + l); } if (p->GetPathLength() > MaxPathLength) MaxPathLength = p->GetPathLength(); getPathLengths (p->GetChild()); getPathLengths (p->GetSibling()); } }
//------------------------------------------------------------------------------ void CircleTreeDrawer::CalcInternal (Node *p) { double left_angle = node_angle[p->GetChild()]; double right_angle = node_angle[p->GetChild()->GetRightMostSibling()]; node_angle[p] = left_angle + (right_angle - left_angle)/2.0; node_radius[p] = nodeGap * (double)(maxDepth - p->GetDepth()); node_coordinates[p].x = node_radius[p] * cos (node_angle[p]); node_coordinates[p].y = node_radius[p] * sin (node_angle[p]); NodePtr q = p->GetChild(); while (q) { point pt; node_backarc[q] = pt; node_backarc[q].x = node_radius[p] * cos (node_angle[q]); node_backarc[q].y = node_radius[p] * sin (node_angle[q]); q = q->GetSibling(); } }
//------------------------------------------------------------------------------ void Tree::fillInAncestors (NodePtr p) { NodePtr q = p->GetAnc (); NodePtr r = p; while (q != Root) { if ( (q->GetSibling () && !(r->IsTheChild ())) || (!(q->IsTheChild ()) && r->IsTheChild()) ) { if (r ==p && q->GetHeight() == q->GetAnc()->GetHeight()) Line[q->GetAnc()->GetHeight()] = SIB; else Line[q->GetAnc()->GetHeight()] = VBAR; } r = q; q = q->GetAnc (); } }
int MAST (NTree &T1, NTree &T2) { int result = 0; // 1. create lists of the nodes in T1 and T2 in postorder int count = 0; NodeVector pot1; NodeIterator <Node> n1 (T1.GetRoot()); Node *q = n1.begin(); while (q) { q->SetIndex (count); pot1.push_back ((NNode *)q); count++; q = n1.next(); } count = 0; NodeVector pot2; NodeIterator <Node> n2 (T2.GetRoot()); q = n2.begin(); while (q) { q->SetIndex (count); pot2.push_back ((NNode *)q); count++; q = n2.next(); } // Matrix to hold solutions int **m; m = new int *[T1.GetNumNodes()]; for (int i = 0; i < T1.GetNumNodes(); i++) m[i] = new int [T2.GetNumNodes()]; for (int i = 0; i < T1.GetNumNodes(); i++) for (int j = 0; j <T2.GetNumNodes(); j++) m[i][j] = 0; // 2. Visit all pairs of nodes in T1 and T2 for (int i = 0; i < T1.GetNumNodes(); i++) { for (int j = 0; j <T2.GetNumNodes(); j++) { if (pot1[i]->IsLeaf() || pot2[j]->IsLeaf()) { // Both are leaves, so MAST[i,j] is 1 if labels are identical if (pot1[i]->IsLeaf() && pot2[j]->IsLeaf()) { if ( pot1[i]->GetLabel() == pot2[j]->GetLabel()) m[i][j] = 1; } else { // Only one is a leaf, so MAST[i,j] is 1 if leaf is element in cluster IntegerSet common; std::set_intersection (pot1[i]->Cluster.begin(), pot1[i]->Cluster.end(), pot2[j]->Cluster.begin(), pot2[j]->Cluster.end(), std::inserter (common, common.end())); int w = common.size(); m[i][j] = w; } } else { // Both are internals so MAST[i,j] is MAX (diag, match) std::vector <NodePtr> pchildren, qchildren; // diag int diag = 0; // Get MAST of base of subtree in t1 and immediate children of // base of subtree in t2, and at the same time store list of // immediate children NodePtr p = pot2[j]->GetChild(); while (p) { qchildren.push_back(p); diag = std::max (diag, m[i][p->GetIndex()]); p = p->GetSibling(); } // get MAST of base of subtree in t2 and immediate children of // base of subtree in t1, and at the same time store list of // immediate children NodePtr q = pot1[i]->GetChild(); while (q) { pchildren.push_back(q); diag = std::max (diag, m[q->GetIndex()][j]); q = q->GetSibling(); } // maximum weighted bipartite matching #if USE_MATCHING int match = 0; graph g; g.make_directed(); // Nodes for p and q children map <int, node, less <int> > p_node; map <int, node, less <int> > q_node; for (int k = 0; k < pchildren.size(); k++) { node n = g.new_node(); p_node[k] = n; } for (int k = 0; k < qchildren.size(); k++) { node n = g.new_node(); q_node[k] = n; } // Edges edge_map<int> weights(g, 0); for (int k = 0; k < pchildren.size(); k++) { for (int r = 0; r < qchildren.size(); r++) { int v = pchildren[k]->GetIndex(); int w = qchildren[r]->GetIndex(); // It seems that if the partition "from" is much larger than "to, // the matching algorithm can blow up with a memory access error // in fheap.c. Reversing the graph seems to help. edge e; if (pchildren.size() < qchildren.size()) e = g.new_edge (p_node[k], q_node[r]); else e = g.new_edge (q_node[r], p_node[k]); weights[e] = m[v][w]; } } // cout << "g" << endl; // cout << g; // g.save(); // cout << "Start matching..."; if (g.number_of_nodes() == 0) { match = 0; } else { mwbmatching mwbm; mwbm.set_vars (weights); if (mwbm.check(g) != algorithm::GTL_OK) { cout << "Maximum weight bipartite matching algorithm check failed" << endl; exit(1); } else { if (mwbm.run(g) != algorithm::GTL_OK) { cout << "Error running maximum weight bipartite matching algorithm" << endl; exit(1); } else { match = mwbm.get_mwbm(); } } } // cout << "matching done (" << match << ")" << endl; #else // For now (sigh) brute force generation of all matchings. Eventually // will need to do this more efficiently int n = std::max (pchildren.size(), qchildren.size()); // Store a vector of indices of children of subtree in t2. // We will permute this to generate all matchings. If t2 // has fewer children than subtree in t1, vector will contain // one or more "null" (-1) values. std::vector <int> perm; for (int k = 0; k < n; k++) { if (k < qchildren.size()) perm.push_back (k); else perm.push_back (-1); } // Generate all matchings // First matching int match = 0; for (int k = 0; k < n; k++) { if ((k < pchildren.size()) && (perm[k] != -1)) { int v = pchildren[k]->GetIndex(); int w = qchildren[perm[k]]->GetIndex(); match += m[v][w]; } } // Remaining matchings while (next_permutation (perm.begin(), perm.end()) ) { int this_match = 0; for (int k = 0; k < n; k++) { if ((k < pchildren.size()) && (perm[k] != -1)) { int v = pchildren[k]->GetIndex(); int w = qchildren[perm[k]]->GetIndex(); this_match += m[v][w]; } } match = std::max (match, this_match); } #endif m[i][j] = std::max (diag, match); } } } result = m[T1.GetNumNodes() - 1][T2.GetNumNodes() - 1]; // Show matrix /* for (int i = 0; i < T1.GetNumNodes(); i++) { cout << setw(3) << i << "|"; for (int j = 0; j < T2.GetNumNodes(); j++) cout << setw(3) << m[i][j]; cout << endl; } */ // clean up for (int i = 0; i < T1.GetNumNodes(); i++) delete [] m[i]; delete [] m; return result; }
//------------------------------------------------------------------------------ void Tree::drawInteriorEdge (NodePtr p) { NodePtr r = p->GetAnc (); int stop = r->GetHeight(); if (p->IsTheChild ()) { // Visiting ancestor for the first time, so draw the // end symbol if (r == Root) { // if (IsRooted ()) Line[stop] = TEE; // « // else // Line[stop] = VBAR; // Ò } else { Line[stop] = TEE; // « } // Draw branch itself if (r != Root) { // Line int start = r->GetAnc()->GetHeight(); for (int i = start + 1; i < stop; i++) { Line[i] = HBAR; // € } // Start symbol if (start == stop) Line[start] = VBAR; // Ò else if (r->IsTheChild ()) Line[start] = LEFT; // ò else if (r->GetSibling ()) Line[start] = SIB; // Ì else Line[start] = RIGHT; // Ë // fillInAncestors (r); } } else { // Just draw nodes below Line[stop] = VBAR; fillInAncestors (p->GetSibling()); } // Output the line Line[stop + 1] = '\0'; drawLine (r, p->IsTheChild()); /* *treeStream << Line.c_str(); // *treeStream << "h=" << r->GetHeight() << " w= " // << r->GetWeight() << "-- "; // Draw internal label, if present string s = r->GetLabel(); if (s != "" && p->IsTheChild ()) *treeStream << r->GetLabel(); *treeStream << endl; */ // Clear the line for the next pass for (int i = 0; i < (Leaves + 2); i++) // to do: get a better limit Line[i] = ' '; }
NodePtr Tree::RemoveNode (NodePtr Node) { NodePtr result = NULL; if (Node == Root) { if (Leaves == 1) { Root = NULL; Node->SetAnc (NULL); Leaves = Internals = 0; } return result; } NodePtr p; NodePtr Ancestor = Node->GetAnc(); if (Ancestor->GetDegree() == 2) { // ancestor is binary, so remove node and its ancestor if (Node->IsTheChild ()) p = Node->GetSibling(); else p = Ancestor->GetChild(); NodePtr q = Ancestor->GetAnc(); p->SetAnc (q); if (q != NULL) { if (Ancestor->IsTheChild()) q->SetChild (p); else { NodePtr r = Ancestor->LeftSiblingOf (); r->SetSibling (p); } p->SetSibling (Ancestor->GetSibling()); result = p; } else { // Ancestor is the root Root = p; p->SetSibling (NULL); result = p; } delete Ancestor; Internals--; if (Node->IsLeaf()) Leaves--; Node->SetAnc (NULL); Node->SetSibling (NULL); } else { // polytomy, just remove node NodePtr q; if (Node->IsTheChild()) { Ancestor->SetChild (Node->GetSibling()); q = Node->GetSibling (); } else { q = Node->LeftSiblingOf (); q->SetSibling (Node->GetSibling ()); } Node->SetSibling (NULL); Node->SetAnc (NULL); if (Node->IsLeaf()) Leaves--; Ancestor->SetDegree (Ancestor->GetDegree() - 1); result = q; } }