Пример #1
0
void kd_tree::build_tree(array_2d<double> &mm,
    array_1d<double> &nmin, array_1d<double> &nmax){
   
    if(nmin.get_dim()!=mm.get_cols()){
        printf("WARNING nimin dim %d cols %d\n",nmin.get_dim(),mm.get_cols());
        throw -1;
    }
   
    if(nmax.get_dim()!=mm.get_cols()){
        printf("WARNING nmax dim %d cols %d\n",nmax.get_dim(),mm.get_cols());
        throw -1;
    } 
    
    search_time=0.0;
    search_ct=0;
    
    search_ct_solo=0;
    search_time_solo=0.0;
    
    data.reset();
    tree.reset();
   
    array_1d<int> inn,use_left,use_right;
    array_1d<double> tosort,sorted;
  
    int i,j,k,l,inp;

    tol=1.0e-7;

    diagnostic=1;
  
    tree.set_dim(mm.get_rows(),4);
    data.set_dim(mm.get_rows(),mm.get_cols());
   
    use_left.set_name("kd_tree_constructor_use_left");
    use_right.set_name("kd_tree_constructor_use_right");
    tree.set_name("kd_tree_tree");
    data.set_name("kd_tree_data");
   
    //tree[i][0] will be the dimension being split
    //tree[i][1] will be left hand node (so, lt)
    //tree[i][2] will be right hand node (so, ge)
    //tree[i][3] will be parent
      
    mins.set_name("kd_tree_mins");
    maxs.set_name("kd_tree_maxs");
   
    for(i=0;i<data.get_cols();i++){
        mins.set(i,nmin.get_data(i));
        maxs.set(i,nmax.get_data(i));
    }
   
    array_1d<double> vector;
   
    for(i=0;i<data.get_rows();i++){
         data.set_row(i,(*mm(i)));
    }

    sorted.set_name("kd_tree_constructor_sorted");
    tosort.set_name("kd_tree_constructor_tosort");
    inn.set_name("kd_tree_constructor_inn");
    
    /*sort the data points by their 0th dimension component*/
    for(i=0;i<data.get_rows();i++){
         tosort.set(i,data.get_data(i,0));
         inn.set(i,i);
    }

    sort_and_check(tosort,sorted,inn);

    /*try to pick the median value as the first node in the tree (the
    masterparent)*/
    inp=data.get_rows()/2;
    while(inp>0 && sorted.get_data(inp)-sorted.get_data(inp-1)<tol){
         /*make sure that the division doesn't come in the middle of a bunch
         of identical points*/
         
         inp--;
    }
   
    masterparent=inn.get_data(inp);
    
    /*assign the remaining points to either the left branch or the right
    branch of the masterparent*/
    for(j=0;j<data.get_rows();j++){
        if(masterparent!=j){
            if(data.get_data(j,0)<sorted.get_data(inp)){
                use_left.add(j);
            }
            else{
                use_right.add(j);
            }
        }
    } 

    /*organize all of the points on the left branch of the masterparent*/
    if(use_left.get_dim()>0){
        organize(use_left,0,masterparent,1,use_left.get_dim(),1);   
    }
    else tree.set(masterparent,1,-1);
   
    /*organize all of the points on the right branch of the masterparent*/
    if(use_right.get_dim()>0){
        organize(use_right,0,masterparent,1,use_right.get_dim(),2);    
    }
    else tree.set(masterparent,2,-1);
   
    tree.set(masterparent,3,-1);/*masterparent has no parent of its own*/
    
    tree.set(masterparent,0,0);/*masterparent split on the 0th dimension*/
   
    /*check to make sure everything has the dimensions that it should*/
    if(mins.get_dim()!=maxs.get_dim() || mins.get_dim()!=data.get_cols() || tree.get_rows()!=data.get_rows()){
        printf("WARNING tried to make tree but\n");
        printf("nmax %d\n",maxs.get_dim());
        printf("nmin %d\n",mins.get_dim());
        printf("tree %d %d data %d %d\n",tree.get_rows(),tree.get_cols(),
        data.get_rows(),data.get_cols());
       
        exit(1);
    }
  
}