?? cftree.c~
字號:
tmpent.Init(Stats->Dimension);int i1,j1,imin,jmin;double d, dmin;if (actsize<2) print_error("Leaf::ClosestDiffTwo","Less than 2 entries");if (actsize==2) {d=distance(Stats->GDtype,entry[0],entry[1]); if (d<=0) print_error("Leaf::ClosestDiffTwo", "Same 2 entries in a leaf: should not happen"); }dmin = HUGE_DOUBLE;imin=0; jmin=1;for (i1=0;i1<actsize-1;i1++) for (j1=i1+1;j1<actsize;j1++) { d = distance(Stats->GDtype,entry[i1],entry[j1]); if (d>0 && d<dmin) { imin = i1; jmin = j1; dmin = d; } }i=imin; j=jmin;tmpent.Add(entry[i],entry[j]);return tmpent.Fitness(Stats->Ftype);}void Leaf::FarthestTwo(Stat *Stats, int &i, int &j) const {int i1,j1,imax,jmax;double d, dmax;if (actsize<2) print_error("Leaf::FarthestTwo","Less than 2 entries");if (actsize==2) {i=0; j=1; return;}imax = 0; jmax = 1;dmax = distance(Stats->BDtype,entry[0],entry[1]);for (i1=0;i1<actsize-1;i1++) for (j1=i1+1;j1<actsize;j1++) { d = distance(Stats->BDtype,entry[i1],entry[j1]); if (d>dmax) { imax = i1; jmax = j1; dmax = d;} }i=imax; j=jmax;}double Nonleaf::ClosestTwo(Stat *Stats, int &i, int &j) const {int i1,j1,imin,jmin;double d, dmin;if (actsize<2) print_error("Nonleaf::ClosestTwo","Less than 2 entries");if (actsize==2) { i=0; j=1; return distance(Stats->BDtype,entry[0],entry[1]); }imin = 0; jmin = 1;dmin = distance(Stats->BDtype,entry[0],entry[1]);for (i1=0;i1<actsize-1;i1++) for (j1=i1+1;j1<actsize;j1++) { d = distance(Stats->BDtype,entry[i1],entry[j1]); if (d<dmin) { imin = i1; jmin = j1; dmin = d; } }i=imin; j=jmin;return dmin;}double Nonleaf::ClosestDiffTwo(Stat *Stats, int &i, int &j) const {Entry tmpent;tmpent.Init(Stats->Dimension);int i1,j1,imin,jmin;double d, dmin;if (actsize<2) print_error("Nonleaf::ClosestDiffTwo","Less than 2 entries");if (actsize==2) { d=distance(Stats->GDtype,entry[0],entry[1]); if (d==0) print_error("Nonleaf::ClosestDiffTwo", "Same 2 entries in a nonleaf: should not happen"); }dmin=HUGE_DOUBLE;imin=0;jmin=1;for (i1=0;i1<actsize-1;i1++) for (j1=i1+1;j1<actsize;j1++) { d = distance(Stats->GDtype,entry[i1],entry[j1]); if (d>0 && d<dmin) { imin = i1; jmin = j1; dmin = d;} }i=imin; j=jmin;tmpent.Add(entry[i],entry[j]);return tmpent.Fitness(Stats->Ftype);}void Nonleaf::FarthestTwo(Stat *Stats, int &i, int &j) const {int i1,j1,imax,jmax;double d, dmax;if (actsize<2) print_error("Nonleaf::FarthestTwo","Less than 2 entries");if (actsize==2) {i=0; j=1; return;}imax = 0; jmax = 1;dmax = distance(Stats->BDtype,entry[0],entry[1]);for (i1=0;i1<actsize-1;i1++) for (j1=i1+1;j1<actsize;j1++) { d = distance(Stats->BDtype,entry[i1],entry[j1]); if (d>dmax) { imax = i1; jmax = j1; dmax = d;} }i=imax; j=jmax;}// follow chain of leavesint Leaf::count_leaf_nodes() const {int num=1;if (this->next!=NULL) num+=this->next->count_leaf_nodes();return num;}int Leaf::count_leaf_entries() const {int num=actsize;if (this->next!=NULL) num+=this->next->count_leaf_entries();return num;}int Leaf::count_leaf_tuples() const {int num=0;for (int i=0; i<actsize; i++) num += entry[i].n;if (this->next!=NULL) num+=this->next->count_leaf_tuples();return num;}void Nonleaf::Print_Tree(short ind, ostream &fo) const {for (int i=0; i<actsize; i++) { indent(ind,fo); fo<<entry[i]<<endl; child[i]->Print_Tree(ind+5,fo); }}void Nonleaf::Print_Tree(short ind, ofstream &fo) const {for (int i=0; i<actsize; i++) { indent(ind,fo); fo<<entry[i]<<endl; child[i]->Print_Tree(ind+5,fo); }}void Leaf::Print_Tree(short ind, ostream &fo) const {for (int i=0; i<actsize; i++) { indent(ind,fo); fo<<entry[i]<< endl; }}void Leaf::Print_Tree(short ind, ofstream &fo) const {for (int i=0; i<actsize; i++) { indent(ind,fo); fo<<entry[i]<<endl; }} void Leaf::visualize_leaf_entries(Stat *Stats, ostream &fo) const {if (Stats->Dimension>2) print_error("Nonleaf::Visualize", "can't visualize higher than 2 dimensions");int i;Leaf *tmp;tmp=this;while (tmp!=NULL) { for (i=0; i<tmp->actsize; i++) tmp->entry[i].Visualize_Rectangle(fo); tmp=tmp->next; }tmp=this;while (tmp!=NULL) { for (i=0; i<tmp->actsize; i++) tmp->entry[i].Visualize_Circle(fo); tmp=tmp->next; }}void Leaf::visualize_leaf_entries(Stat *Stats, ofstream &fo) const {if (Stats->Dimension>2) print_error("Nonleaf::Visualize", "can't visualize higher than 2 dimensions");int i;Leaf *tmp;tmp=this;while (tmp!=NULL) { for (i=0; i<tmp->actsize; i++) tmp->entry[i].Visualize_Rectangle(fo); tmp=tmp->next; }tmp=this;while (tmp!=NULL) { for (i=0; i<tmp->actsize; i++) tmp->entry[i].Visualize_Circle(fo); tmp=tmp->next; }}// follow chain of leavesvoid Leaf::print_leaf_entries_bychain(ofstream &fo) const {fo<<"#"<<actsize<<endl;for (int i=0; i<actsize; i++) fo<<entry[i]<<endl;if (this->next!=NULL) this->next->print_leaf_entries_bychain(fo);}// follow chain of leavesvoid Leaf::print_leaf_entries_bychain(ostream &fo) const {for (int i=0; i<actsize; i++) fo<<entry[i]<<endl;if (this->next!=NULL) this->next->print_leaf_entries_bychain(fo);}// topdown search for leavesvoid Leaf::print_leaf_entries_topdown(ofstream &fo) const {fo<<"#"<<actsize<<endl;for (int i=0; i<actsize; i++) fo<<entry[i]<<endl;}// topdown search for leavesvoid Nonleaf::print_leaf_entries_topdown(ofstream &fo) const {for (int i=0; i<actsize; i++) child[i]->print_leaf_entries_topdown(fo);}Node* Leaf::InsertMightSplit(Stat *Stats, const Entry &Ent, Node *ptr) {short samegroup;Leaf *NewNode;int i1,i2,n1,n2,head1,head2;double d1, d2;Entry ent1,ent2;ent1.Init(Stats->Dimension);ent2.Init(Stats->Dimension);if (NotFull(Stats)) { entry[actsize]=Ent; actsize++; Stats->CurrEntryCnt++; return NULL; }NewNode = new Leaf(Stats); Stats->MemUsed++; Stats->TreeSize++;NewNode->entry[NewNode->actsize]=Ent;NewNode->actsize++; Stats->CurrEntryCnt++;// chain leaf nodesif (this->next!=NULL) { this->next->prev=NewNode; }NewNode->next=this->next;NewNode->prev=this;this->next=NewNode;this->FarthestTwoOut(Stats,this,NewNode,samegroup,i1,i2);switch (samegroup) {case 0: this->swap(this,0, this,i1); NewNode->swap(NewNode,0, NewNode,i2); break;case 1: this->swap(this,0, this,i1); NewNode->swap(NewNode,0, this,i2); break;default: print_error("Leaf::InsertMightSplit","Invalid group flag");}n1 = MaxSize(Stats);n2 = 1;head1 = 1; head2 = 1;ent1 = this->entry[0];ent2 = NewNode->entry[0];while (head1<n1) { d1 = distance(Stats->BDtype,ent1,this->entry[head1]); d2 = distance(Stats->BDtype,ent2,this->entry[head1]); if (d1<d2) { ent1+=this->entry[head1]; head1++; } else { this->assign(NewNode,head2,this,head1); this->assign(this,head1,this,n1-1); ent2+=NewNode->entry[head2]; head2++; n1--; n2++; } }this->actsize=n1;NewNode->actsize=n2;return(NewNode);}Node* Nonleaf::InsertMightSplit(Stat *Stats, const Entry &Ent, Node *Ptr) {short samegroup;Nonleaf *NewNode;int i1,i2,n1,n2,head1,head2;double d1, d2;Entry ent1,ent2;ent1.Init(Stats->Dimension);ent2.Init(Stats->Dimension);if (NotFull(Stats)) { entry[actsize]=Ent; child[actsize]=Ptr; actsize++; return NULL; }NewNode=new Nonleaf(Stats); Stats->MemUsed++; Stats->TreeSize++;NewNode->entry[NewNode->actsize]=Ent;NewNode->child[NewNode->actsize]=Ptr;NewNode->actsize++;this->FarthestTwoOut(Stats,this,NewNode,samegroup,i1,i2);switch (samegroup) {case 0: this->swap(this,0, this,i1); NewNode->swap(NewNode,0, NewNode,i2); break;case 1: this->swap(this,0, this,i1); NewNode->swap(NewNode,0, this,i2); break;default: print_error("Nonleaf::InsertMightSplit","Invalid group flag");}n1=MaxSize(Stats);n2=1;head1=1; head2=1;ent1 = this->entry[0];ent2 = NewNode->entry[0];while (head1<n1) { d1 = distance(Stats->BDtype,ent1,this->entry[head1]); d2 = distance(Stats->BDtype,ent2,this->entry[head1]); if (d1<d2) { ent1+=this->entry[head1]; head1++; } else { this->assign(NewNode,head2,this,head1); this->assign(this,head1,this,n1-1); ent2+=NewNode->entry[head2]; head2++; n1--; n2++; } }this->actsize=n1; NewNode->actsize=n2;return(NewNode);}void Nonleaf::MergeMightResplit(Stat *Stats, int i, int j) {int head1,head2,k,j1,j2,n1,n2,total;short samegroup;double d1, d2;Entry ent1,ent2;ent1.Init(Stats->Dimension);ent2.Init(Stats->Dimension);n1 = child[i]->ActSize();n2 = child[j]->ActSize();total = n1+n2;// Merge: no overflowif (total<child[i]->MaxSize(Stats)) { child[i]->AssignActSize(total); entry[i]+=entry[j]; for (k=0;k<n2;k++) child[i]->assign(child[i],n1+k, child[j],k); child[j]->AssignNextPrev(Stats); delete child[j]; Stats->MemUsed--; Stats->TreeSize--; this->assign(this,j, this,actsize-1); actsize--; }// ReSplit: overflowelse {//farthest pair in tmpentrychild[i]->FarthestTwoOut(Stats, child[i],child[j],samegroup,j1,j2);switch (samegroup) {case 0: child[i]->swap(child[i],0, child[i],j1); child[j]->swap(child[j],0, child[j],j2); break;case 1: child[i]->swap(child[i],0, child[i],j1); child[j]->swap(child[j],0, child[i],j2); break;case 2: child[i]->swap(child[i],0, child[j],j1); child[j]->swap(child[j],0, child[j],j2); break;default: print_error("Nonleaf::MergeMightResplit","Invalid group flag");}head1=1; head2=1;ent1 = *(child[i]->TheEntry(0));ent2 = *(child[j]->TheEntry(0));while (head1<n1 && head2<n2) { d1 = distance(Stats->BDtype,ent1,*(child[i]->TheEntry(head1))); d2 = distance(Stats->BDtype,ent2,*(child[i]->TheEntry(head1))); if (d1<d2) { ent1+=*(child[i]->TheEntry(head1)); head1++; } else { child[i]->swap(child[i],head1,child[j],head2); ent2 += *(child[j]->TheEntry(head2)); head2++; } }// child[j] has left overif (head1>=n1 && head2<n2) { while (head2<n2 && n1<child[i]->MaxSize(Stats)) { d1 = distance(Stats->BDtype,ent1,*(child[j]->TheEntry(head2))); d2 = distance(Stats->BDtype,ent2,*(child[j]->TheEntry(head2))); if (d2<d1) { ent2 += *(child[j]->TheEntry(head2)); head2++; } else { child[i]->assign(child[i],head1,child[j],head2); child[j]->assign(child[j],head2,child[j],n2-1); ent1+=*(child[i]->TheEntry(head1)); head1++; n1++; n2--; } }}// child[i] has left overelse if (head1<n1 && head2>=n2) { while (head1<n1 && n2<child[j]->MaxSize(Stats)) { d1 = distance(Stats->BDtype,ent1,*(child[i]->TheEntry(head1))); d2 = distance(Stats->BDtype,ent2,*(child[i]->TheEntry(head1))); if (d1<d2) { ent1 += *(child[i]->TheEntry(head1)); head1++; } else { child[j]->assign(child[j],head2,child[i],head1); child[i]->assign(child[i],head1,child[i],n1-1); ent2+=*(child[j]->TheEntry(head2)); head2++; n1--; n2++; } }}child[i]->AssignActSize(n1);child[j]->AssignActSize(n2); child[i]->CF(entry[i]);child[j]->CF(entry[j]);}}void Leaf::FarthestTwoOut(Stat *Stats, Node *node1, Node *node2, short &samegroup, int &i, int &j) const {int i1, i2, j1, j2, n1, n2;double d, dmax;Leaf *leaf1, *leaf2;leaf1 = (Leaf *)node1;leaf2 = (Leaf *)node2;n1 = leaf1->ActSize();n2 = leaf2->ActSize();if (n1==0 || n2==0) print_error("Leaf::FarthestTwoOut","empty node");samegroup = 0;i=0; j=0;dmax = distance(Stats->BDtype,leaf1->entry[i],leaf2->entry[j]);for (i1=0; i1<n1; i1++) for (i2=0; i2<n2; i2++) { d = distance(Stats->BDtype,leaf1->entry[i1],leaf2->entry[i2]); if (d>dmax) { i=i1; j=i2; dmax=d; } }for (i1=0; i1<n1-1; i1++) for (j1=i1+1; j1<n1; j1++) { d = distance(Stats->BDtype,leaf1->entry[i1],leaf1->entry[j1]); if (d>dmax) { i=i1; j=j1; dmax=d; samegroup=1; } }for (i2=0; i2<n2-1; i2++) for (j2=i2+1; j2<n2; j2++) { d = distance(Stats->BDtype,leaf2->entry[i2],leaf2->entry[j2]); if (d>dmax) { i=i2; j=j2; dmax=d; samegroup=2; } }}void Nonleaf::FarthestTwoOut(Stat *Stats, Node *node1, Node *node2, short &samegroup, int &i, int &j) const {int i1, i2, j1, j2, n1, n2;double d, dmax;Nonleaf *nleaf1, *nleaf2;nleaf1 = (Nonleaf *)node1;nleaf2 = (Nonleaf *)node2;n1 = nleaf1->ActSize();n2 = nleaf2->ActSize();if (n1==0 || n2==0) print_error("Nonleaf::FarthestTwoOut","empty node");samegroup = 0;i=0; j=0;dmax=distance(Stats->BDtype,nleaf1->entry[i],nleaf2->entry[j]);for (i1=0; i1<n1; i1++) for (i2=0; i2<n2; i2++) { d = distance(Stats->BDtype,nleaf1->entry[i1],nleaf2->entry[i2]); if (d>dmax) { i=i1; j=i2; dmax=d; } }for (i1=0; i1<n1-1; i1++) for (j1=i1+1; j1<n1; j1++) { d = distance(Stats->BDtype,nleaf1->entry[i1],nleaf1->entry[j1]); if (d>dmax) { i=i1; j=j1; dmax=d; samegroup=1; } }for (i2=0; i2<n2-1; i2++) for (j2=i2+1; j2<n2; j2++) { d = distance(Stats->BDtype,nleaf2->entry[i2],nleaf2->entry[j2]); if (d>dmax) { i=i2; j=j2; dmax=d; samegroup=2; } }}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -