⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bd_tree.cpp

📁 c++实现的KNN库:建立高维度的K-d tree,实现K邻域搜索
💻 CPP
📖 第 1 页 / 共 2 页
字号:
												// repeat for high side		ANNcoord gap_lo = inner_box.lo[i] - bnd_box.lo[i];		if (gap_lo < max_length*BD_GAP_THRESH)			inner_box.lo[i] = bnd_box.lo[i];	// no - expand		else shrink_ct++;						// yes - shrink this side	}	if (shrink_ct >= BD_CT_THRESH)				// did we shrink enough sides?		 return SHRINK;	else return SPLIT;}//----------------------------------------------------------------------//	tryCentroidShrink - Attempt a centroid shrink////	We repeatedly apply the splitting rule, always to the larger subset//	of points, until the number of points decreases by the constant//	fraction BD_FRACTION.  If this takes more than dim*BD_MAX_SPLIT_FAC//	splits for this to happen, then we shrink to the final inner box//	Otherwise we split.//----------------------------------------------------------------------const float	BD_MAX_SPLIT_FAC = 0.5;		// maximum number of splits allowedconst float	BD_FRACTION = 0.5;			// ...to reduce points by this fraction										// ...This must be < 1.ANNdecomp tryCentroidShrink(			// try a centroid shrink	ANNpointArray		pa,				// point array	ANNidxArray			pidx,			// point indices to store in subtree	int					n,				// number of points	int					dim,			// dimension of space	const ANNorthRect	&bnd_box,		// current bounding box	ANNkd_splitter		splitter,		// splitting procedure	ANNorthRect			&inner_box)		// inner box if shrinking (returned){	int n_sub = n;						// number of points in subset	int n_goal = (int) (n*BD_FRACTION); // number of point in goal	int n_splits = 0;					// number of splits needed										// initialize inner box to bounding box	annAssignRect(dim, inner_box, bnd_box);	while (n_sub > n_goal) {			// keep splitting until goal reached		int cd;							// cut dim from splitter (ignored)		ANNcoord cv;					// cut value from splitter (ignored)		int n_lo;						// number of points on low side										// invoke splitting procedure		(*splitter)(pa, pidx, inner_box, n_sub, dim, cd, cv, n_lo);		n_splits++;						// increment split count		if (n_lo >= n_sub/2) {			// most points on low side			inner_box.hi[cd] = cv;		// collapse high side			n_sub = n_lo;				// recurse on lower points		}		else {							// most points on high side			inner_box.lo[cd] = cv;		// collapse low side			pidx += n_lo;				// recurse on higher points			n_sub -= n_lo;		}	}    if (n_splits > dim*BD_MAX_SPLIT_FAC)// took too many splits		return SHRINK;					// shrink to final subset	else		return SPLIT;}//----------------------------------------------------------------------//	selectDecomp - select which decomposition to use//----------------------------------------------------------------------ANNdecomp selectDecomp(			// select decomposition method	ANNpointArray		pa,				// point array	ANNidxArray			pidx,			// point indices to store in subtree	int					n,				// number of points	int					dim,			// dimension of space	const ANNorthRect	&bnd_box,		// current bounding box	ANNkd_splitter		splitter,		// splitting procedure	ANNshrinkRule		shrink,			// shrinking rule	ANNorthRect			&inner_box)		// inner box if shrinking (returned){	ANNdecomp decomp = SPLIT;			// decomposition	switch (shrink) {					// check shrinking rule	case ANN_BD_NONE:					// no shrinking allowed		decomp = SPLIT;		break;	case ANN_BD_SUGGEST:				// author's suggestion	case ANN_BD_SIMPLE:					// simple shrink		decomp = trySimpleShrink(				pa, pidx,				// points and indices				n, dim,					// number of points and dimension				bnd_box,				// current bounding box				inner_box);				// inner box if shrinking (returned)		break;	case ANN_BD_CENTROID:				// centroid shrink		decomp = tryCentroidShrink(				pa, pidx,				// points and indices				n, dim,					// number of points and dimension				bnd_box,				// current bounding box				splitter,				// splitting procedure				inner_box);				// inner box if shrinking (returned)		break;	default:		annError("Illegal shrinking rule", ANNabort);	}	return decomp;}//----------------------------------------------------------------------//	rbd_tree - recursive procedure to build a bd-tree////		This is analogous to rkd_tree, but for bd-trees.  See the//		procedure rkd_tree() in kd_split.cpp for more information.////		If the number of points falls below the bucket size, then a//		leaf node is created for the points.  Otherwise we invoke the//		procedure selectDecomp() which determines whether we are to//		split or shrink.  If splitting is chosen, then we essentially//		do exactly as rkd_tree() would, and invoke the specified//		splitting procedure to the points.  Otherwise, the selection//		procedure returns a bounding box, from which we extract the//		appropriate shrinking bounds, and create a shrinking node.//		Finally the points are subdivided, and the procedure is//		invoked recursively on the two subsets to form the children.//----------------------------------------------------------------------ANNkd_ptr rbd_tree(				// recursive construction of bd-tree	ANNpointArray		pa,				// point array	ANNidxArray			pidx,			// point indices to store in subtree	int					n,				// number of points	int					dim,			// dimension of space	int					bsp,			// bucket space	ANNorthRect			&bnd_box,		// bounding box for current node	ANNkd_splitter		splitter,		// splitting routine	ANNshrinkRule		shrink)			// shrinking rule{	ANNdecomp decomp;					// decomposition method	ANNorthRect inner_box(dim);			// inner box (if shrinking)	if (n <= bsp) {						// n small, make a leaf node		if (n == 0)						// empty leaf node			return KD_TRIVIAL;			// return (canonical) empty leaf		else							// construct the node and return			return new ANNkd_leaf(n, pidx); 	}		decomp = selectDecomp(				// select decomposition method				pa, pidx,				// points and indices				n, dim,					// number of points and dimension				bnd_box,				// current bounding box				splitter, shrink,		// splitting/shrinking methods				inner_box);				// inner box if shrinking (returned)		if (decomp == SPLIT) {				// split selected		int cd;							// cutting dimension		ANNcoord cv;					// cutting value		int n_lo;						// number on low side of cut										// invoke splitting procedure		(*splitter)(pa, pidx, bnd_box, n, dim, cd, cv, n_lo);		ANNcoord lv = bnd_box.lo[cd];	// save bounds for cutting dimension		ANNcoord hv = bnd_box.hi[cd];		bnd_box.hi[cd] = cv;			// modify bounds for left subtree		ANNkd_ptr lo = rbd_tree(		// build left subtree				pa, pidx, n_lo,			// ...from pidx[0..n_lo-1]				dim, bsp, bnd_box, splitter, shrink);		bnd_box.hi[cd] = hv;			// restore bounds		bnd_box.lo[cd] = cv;			// modify bounds for right subtree		ANNkd_ptr hi = rbd_tree(		// build right subtree				pa, pidx + n_lo, n-n_lo,// ...from pidx[n_lo..n-1]				dim, bsp, bnd_box, splitter, shrink);		bnd_box.lo[cd] = lv;			// restore bounds										// create the splitting node		return new ANNkd_split(cd, cv, lv, hv, lo, hi);	}	else {								// shrink selected		int n_in;						// number of points in box		int n_bnds;						// number of bounding sides		annBoxSplit(					// split points around inner box				pa,						// points to split				pidx,					// point indices				n,						// number of points				dim,					// dimension				inner_box,				// inner box				n_in);					// number of points inside (returned)		ANNkd_ptr in = rbd_tree(		// build inner subtree pidx[0..n_in-1]				pa, pidx, n_in, dim, bsp, inner_box, splitter, shrink);		ANNkd_ptr out = rbd_tree(		// build outer subtree pidx[n_in..n]				pa, pidx+n_in, n - n_in, dim, bsp, bnd_box, splitter, shrink);		ANNorthHSArray bnds = NULL;		// bounds (alloc in Box2Bnds and										// ...freed in bd_shrink destroyer)		annBox2Bnds(					// convert inner box to bounds				inner_box,				// inner box				bnd_box,				// enclosing box				dim,					// dimension				n_bnds,					// number of bounds (returned)				bnds);					// bounds array (modified)										// return shrinking node		return new ANNbd_shrink(n_bnds, bnds, in, out);	}} 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -