TreeTemplate<Node>* TreeTemplateTools::parenthesisToTree(const string& description, bool bootstrap, const string& propertyName, bool withId, bool verbose) throw (Exception) { string::size_type semi = description.rfind(';'); if (semi == string::npos) throw Exception("TreeTemplateTools::parenthesisToTree(). Bad format: no semi-colon found."); string content = description.substr(0, semi); unsigned int nodeCounter = 0; Node* node = parenthesisToNode(content, nodeCounter, bootstrap, propertyName, withId, verbose); TreeTemplate<Node>* tree = new TreeTemplate<Node>(); tree->setRootNode(node); if (!withId) { tree->resetNodesId(); } if (verbose) { (*ApplicationTools::message) << " nodes loaded."; ApplicationTools::message->endLine(); } return tree; }
TreeTemplate<Node>* TreeTemplateTools::getRandomTree(vector<string>& leavesNames, bool rooted) { if (leavesNames.size() == 0) return 0; // No taxa. // This vector will contain all nodes. // Start with all leaves, and then group nodes randomly 2 by 2. // Att the end, contains only the root node of the tree. vector<Node*> nodes(leavesNames.size()); // Create all leaves nodes: for (size_t i = 0; i < leavesNames.size(); ++i) { nodes[i] = new Node(leavesNames[i]); } // Now group all nodes: while (nodes.size() > (rooted ? 2 : 3)) { // Select random nodes: size_t pos1 = RandomTools::giveIntRandomNumberBetweenZeroAndEntry<size_t>(nodes.size()); Node* node1 = nodes[pos1]; nodes.erase(nodes.begin() + static_cast<ptrdiff_t>(pos1)); size_t pos2 = RandomTools::giveIntRandomNumberBetweenZeroAndEntry<size_t>(nodes.size()); Node* node2 = nodes[pos2]; nodes.erase(nodes.begin() + static_cast<ptrdiff_t>(pos2)); // Add new node: Node* parent = new Node(); parent->addSon(node1); parent->addSon(node2); nodes.push_back(parent); } // Return tree with last node as root node: Node* root = new Node(); for (size_t i = 0; i < nodes.size(); ++i) { root->addSon(nodes[i]); } TreeTemplate<Node>* tree = new TreeTemplate<Node>(root); tree->resetNodesId(); return tree; }
TreeTemplate<Node>* BipartitionList::toTree() const throw (Exception) { BipartitionList* sortedBipL; vector<int*> sortedBitBipL; int* bip; vector<Node*> vecNd, sonNd; vector<bool> alive; size_t lword, nbword, nbint, ii; /* check, copy and prepare bipartition list */ if (!BipartitionList::areAllCompatible()) throw Exception("Trying to build a tree from incompatible bipartitions"); sortedBipL = dynamic_cast<BipartitionList*>(clone()); for (size_t i = 0; i < sortedBipL->getNumberOfBipartitions(); i++) { if (sortedBipL->getPartitionSize(i) > sortedBipL->getNumberOfElements() / 2) sortedBipL->flip(i); } sortedBipL->sortByPartitionSize(); sortedBipL->removeRedundantBipartitions(); sortedBitBipL = sortedBipL->getBitBipartitionList(); for (size_t i = 0; i < sortedBipL->getNumberOfBipartitions(); i++) { alive.push_back(true); } vecNd.resize(sortedBipL->getNumberOfBipartitions() + 1); lword = static_cast<size_t>(BipartitionTools::LWORD); nbword = (elements_.size() + lword - 1) / lword; nbint = nbword * lword / (CHAR_BIT * sizeof(int)); bip = new int[1]; bip[0] = 0; /* main loop: create one node per bipartition */ for (size_t i = 0; i < sortedBipL->getNumberOfBipartitions(); i++) { if (sortedBipL->getPartitionSize(i) == 1) { // terminal for (size_t j = 0; j < sortedBipL->getNumberOfElements(); j++) { if (BipartitionTools::testBit(sortedBitBipL[i], static_cast<int>(j))) { vecNd[i] = new Node(elements_[j]); break; } } } else { // internal sonNd.clear(); for (size_t j = 0; j < i; j++) { if (alive[j]) { for (ii = 0; ii < nbint; ii++) { BipartitionTools::bitOr(bip, sortedBitBipL[j] + ii, sortedBitBipL[i] + ii, 1); if (bip[0] != sortedBitBipL[i][ii]) break; } if (ii == nbint) { sonNd.push_back(vecNd[j]); alive[j] = false; } } } vecNd[i] = new Node(); for (size_t k = 0; k < sonNd.size(); k++) { vecNd[i]->addSon(sonNd[k]); } } } /* create last node, which joins alive bipartitions = fatherless nodes */ Node* rootNd = new Node(); for (size_t i = 0; i < sortedBipL->getNumberOfBipartitions(); i++) { if (alive[i]) rootNd->addSon(vecNd[i]); } /* construct tree and return */ TreeTemplate<Node>* tr = new TreeTemplate<Node>(rootNd); tr->resetNodesId(); delete sortedBipL; return tr; }