Example #1
0
 inline TreeNode down_heap(TreeNode x, const Compare& comp, ExternalData& edata) {
   while (x.children().size() > 0) {
     typename TreeNode::children_type::iterator 
       child_iter = std::min_element(x.children().begin(),
                                     x.children().end(), 
                                     comp);
     if (comp(*child_iter, x))
       x.swap(*child_iter, edata);
     else
       break;
   }
   return x;
 }
Example #2
0
    std::list<std::string> getNodeChildren(const std::string& parentId) const
    {
      std::list<std::string> children;
      if (parentId.empty()) {
        if (this->dataSource_->modelRoot() != NULL) {
          QPersistentModelIndex pindex(this->model_->index(this->dataSource_->modelRoot(), 0));
          this->nodeIndexes_.insert(pindex);

          // Convert uint64 internal id to string.
          QString qstr = QString::number(pindex.internalId());

          children.push_back(qstr.toLocal8Bit().constData());
        }
      } else {
        TreeNode* parentNode = getNode(parentId);
          if (parentNode != NULL) {
          QList<TreeNode*> childNodes = parentNode->children();
          for (int i = 0; i < childNodes.count(); ++i) {
            QPersistentModelIndex pindex(this->model_->index(childNodes[i], 0));
            this->nodeIndexes_.insert(pindex);

            // Convert uint64 internal id to string.
            QString qstr = QString::number(pindex.internalId());

            children.push_back(qstr.toLocal8Bit().constData());
          }
        }
      }
      return children;
    }
Example #3
0
Tree<_DATA>& Tree<_DATA>::
save_this(const char* dir) {
    char path[SIZEOF_PATH], * filename;
    std::strcpy(path, dir);
    std::size_t dir_len = std::strlen(path);
    std::size_t file_len;
    if (dir_len > 0 && (path[dir_len - 1] != '/' && path[dir_len - 1] != '\\'))
        path[dir_len++] = '/';
    filename = path + dir_len;
    file_len = SIZEOF_PATH - dir_len;
    std::strcpy(filename, "Tree");
    std::ofstream file(path);
    if (!file.is_open()) {
        std::cerr << "\nFailed opening file: " << path << std::endl;
        return *this;
    }
    unsigned long node_num = 0;
    file << std::setw(16) << std::setfill('0') << node_num << ".node"
         << "    # root" << std::endl;
    file.close();
    std::queue<TreeNode*>     node_pointer;
    std::queue<unsigned long> node_name;
    std::queue<unsigned long> node_parent_name;
    node_pointer.push(root_);
    node_name.push(node_num);
    node_parent_name.push(0);
    while (!node_pointer.empty()) {
        TreeNode*     node        = node_pointer.front();
        unsigned long name        = node_name.front();
        unsigned long parent_name = node_parent_name.front();
        std::snprintf(filename, file_len, "%016lu.node", name);
        file.open(path);
        if (!file.is_open()) {
            std::cerr << "\nFailed opening file: " << path << std::endl;
            return *this;
        }
        file << std::setw(16) << std::setfill('0') << parent_name
             << ".node    # parent\n"
             << node->depth() << "    # depth\n";
        unsigned int n_child = node->num_of_children();
        file << n_child << "    # number of children\n";
        if (n_child) {
            TreeNode** child = node->children();
            for (unsigned int i = 0; i < n_child; ++i) {
                node_pointer.push(child[i]);
                node_name.push(++node_num);
                node_parent_name.push(name);
                file << std::setw(16) << std::setfill('0') << node_num
                     << ".node    # child " << i << "\n";
            }
        }
        file << node->content();
        file.close();
        node_pointer.pop();
        node_name.pop();
        node_parent_name.pop();
    }
    return *this;
}
Example #4
0
template<class _DATA> inline 
Tree<_DATA>::~Tree() {
    if (!root_) return;
    std::queue<TreeNode*> breadth_first_traverse;
    breadth_first_traverse.push(root_);
    while (!breadth_first_traverse.empty()) {
        TreeNode*    cur      = breadth_first_traverse.front();
        unsigned int cur_n_ch = cur->num_of_children();
        if (cur_n_ch) {
            TreeNode** cur_ch = cur->children();
            for (unsigned int i = 0; i < cur_n_ch; i++) {
                breadth_first_traverse.push(cur_ch[i]);
            }
        }
        breadth_first_traverse.pop();
        delete cur;
    }
}
void ParticleTreeDustGridStructure::setupSelfBefore()
{
    GenDustGridStructure::setupSelfBefore();

    // Verify property values
    if (_xmax <= 0.0 || _ymax <= 0.0 || _zmax <= 0.0) throw FATALERROR("The maximum extent should be positive");

    // Cache some often used values
    Log* log = find<Log>();
    _eps = 1e-12 * extent().widths().norm();
    DustDistribution* dd = find<DustDistribution>();
    _dmib = dd->interface<DustMassInBoxInterface>();
    DustParticleInterface* dpi = dd->interface<DustParticleInterface>();
    if (!dpi) throw FATALERROR("Can't retrieve particle locations from this dust distribution");
    int numParticles = dpi->numParticles();
    log->info("Constructing tree for " + QString::number(numParticles) + " particles...");

    // Create a list, used only during construction, that contains the index of the particle
    // contained in each leaf node so far created, or -1 if the node is empty
    // (the value is undefined for nonleaf nodes)
    vector<int> particlev;

    // Create the root node (which at this point is an empty leaf) using the requested type
    switch (_treeType)
    {
    default:
    case OctTree:
        _tree.push_back(new OctTreeNode(0,0,extent()));
        break;
    case BinTree:
        _tree.push_back(new BinTreeNode(0,0,extent()));
        break;
    }
    particlev.push_back(-1);
    int maxlevel = 0;

    // Add particles one by one, subdividing if the leaf node containing the new particle
    // already contains another particle
    for (int i=0; i<numParticles; i++)
    {
        if (i%50000 == 0) log->info("Adding particle number " + QString::number(i) +
                                    " (" + QString::number(i*100/numParticles) + "%)...");
        int level = addParticleToNode(i, root(), dpi, particlev, _tree);
        maxlevel = max(maxlevel, level);
    }

    // Perform additional subdivisions as requested
    if (_extraLevels>0)
    {
        log->info("Performing additional subdivisions...");
        maxlevel += _extraLevels;
        for (int e=0; e<_extraLevels; e++)
        {
            int Nnodes = _tree.size();
            for (int l=0; l<Nnodes; l++)
            {
                TreeNode* node = _tree[l];
                if (node->ynchildless())
                {
                    node->createchildren(_tree.size());
                    _tree.insert(_tree.end(), node->children().begin(), node->children().end());
                }
            }
        }
    }

    // Construction of a vector _idv that contains the node IDs of all
    // leaves. This is the actual dust cell vector (only the leaves will
    // eventually become valid dust cells). We also create a vector
    // _cellnumberv with the cell numbers of all the nodes (i.e. the
    // rank m of the node in the vector _idv if the node is a leaf, and
    // -1 if the node is not a leaf).
    int Nnodes = _tree.size();
    int m = 0;
    _cellnumberv.resize(Nnodes,-1);
    for (int l=0; l<Nnodes; l++)
    {
        if (_tree[l]->ynchildless())
        {
            _idv.push_back(l);
            _cellnumberv[l] = m;
            m++;
        }
    }
    _Ncells = _idv.size();

    // Log the number of cells
    log->info("Construction of the tree finished.");
    log->info("  Total number of nodes: " + QString::number(Nnodes));
    log->info("  Total number of leaves: " + QString::number(_Ncells));
    vector<int> countv(maxlevel+1);
    for (int m=0; m<_Ncells; m++)
    {
        TreeNode* node = _tree[_idv[m]];
        int level = node->level();
        countv[level]++;
    }
    log->info("  Number of leaf cells of each level:");
    for (int level=0; level<=maxlevel; level++)
        log->info("    Level " + QString::number(level) + ": " + QString::number(countv[level]) + " cells");

    // Determine the number of levels to be included in 3D grid output (if such output is requested)
    if (writeGrid())
    {
        int cumulativeCells = 0;
        for (_highestWriteLevel=0; _highestWriteLevel<=maxlevel; _highestWriteLevel++)
        {
            cumulativeCells += countv[_highestWriteLevel];
            if (cumulativeCells > 1500) break;          // experimental number
        }
        if (_highestWriteLevel<maxlevel)
            log->info("Will be outputting 3D grid data up to level " + QString::number(_highestWriteLevel) +
                      ", i.e. " + QString::number(cumulativeCells) + " cells.");
    }
}