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

📄 bd_tree.cpp

📁 c++实现的KNN库:建立高维度的K-d tree,实现K邻域搜索
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//----------------------------------------------------------------------// File:			bd_tree.cpp// Programmer:		David Mount// Description:		Basic methods for bd-trees.// Last modified:	01/04/05 (Version 1.0)//----------------------------------------------------------------------// Copyright (c) 1997-2005 University of Maryland and Sunil Arya and// David Mount.  All Rights Reserved.// // This software and related documentation is part of the Approximate// Nearest Neighbor Library (ANN).  This software is provided under// the provisions of the Lesser GNU Public License (LGPL).  See the// file ../ReadMe.txt for further information.// // The University of Maryland (U.M.) and the authors make no// representations about the suitability or fitness of this software for// any purpose.  It is provided "as is" without express or implied// warranty.//----------------------------------------------------------------------// History://	Revision 0.1  03/04/98//		Initial release//	Revision l.0  04/01/05//		Fixed centroid shrink threshold condition to depend on the//			dimension.//		Moved dump routine to kd_dump.cpp.//----------------------------------------------------------------------#include "bd_tree.h"					// bd-tree declarations#include "kd_util.h"					// kd-tree utilities#include "kd_split.h"					// kd-tree splitting rules#include <ANN/ANNperf.h>				// performance evaluation//----------------------------------------------------------------------//	Printing a bd-tree //		These routines print a bd-tree.   See the analogous procedure//		in kd_tree.cpp for more information.//----------------------------------------------------------------------void ANNbd_shrink::print(				// print shrinking node		int level,						// depth of node in tree		ostream &out)					// output stream{	child[ANN_OUT]->print(level+1, out);		// print out-child	out << "    ";	for (int i = 0; i < level; i++)				// print indentation		out << "..";	out << "Shrink";	for (int j = 0; j < n_bnds; j++) {			// print sides, 2 per line		if (j % 2 == 0) {			out << "\n";						// newline and indentation			for (int i = 0; i < level+2; i++) out << "  ";		}		out << "  ([" << bnds[j].cd << "]"			 << (bnds[j].sd > 0 ? ">=" : "< ")			 << bnds[j].cv << ")";	}	out << "\n";	child[ANN_IN]->print(level+1, out);			// print in-child}//----------------------------------------------------------------------//	kd_tree statistics utility (for performance evaluation)//		This routine computes various statistics information for//		shrinking nodes.  See file kd_tree.cpp for more information.//----------------------------------------------------------------------void ANNbd_shrink::getStats(					// get subtree statistics	int					dim,					// dimension of space	ANNkdStats			&st,					// stats (modified)	ANNorthRect			&bnd_box)				// bounding box{	ANNkdStats ch_stats;						// stats for children	ANNorthRect inner_box(dim);					// inner box of shrink	annBnds2Box(bnd_box,						// enclosing box				dim,							// dimension				n_bnds,							// number of bounds				bnds,							// bounds array				inner_box);						// inner box (modified)												// get stats for inner child	ch_stats.reset();							// reset	child[ANN_IN]->getStats(dim, ch_stats, inner_box);	st.merge(ch_stats);							// merge them												// get stats for outer child	ch_stats.reset();							// reset	child[ANN_OUT]->getStats(dim, ch_stats, bnd_box);	st.merge(ch_stats);							// merge them	st.depth++;									// increment depth	st.n_shr++;									// increment number of shrinks}//----------------------------------------------------------------------// bd-tree constructor//		This is the main constructor for bd-trees given a set of points.//		It first builds a skeleton kd-tree as a basis, then computes the//		bounding box of the data points, and then invokes rbd_tree() to//		actually build the tree, passing it the appropriate splitting//		and shrinking information.//----------------------------------------------------------------------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 ruleANNbd_tree::ANNbd_tree(					// construct from point array	ANNpointArray		pa,				// point array (with at least n pts)	int					n,				// number of points	int					dd,				// dimension	int					bs,				// bucket size	ANNsplitRule		split,			// splitting rule	ANNshrinkRule		shrink)			// shrinking rule	: ANNkd_tree(n, dd, bs)				// build skeleton base tree{	pts = pa;							// where the points are	if (n == 0) return;					// no points--no sweat	ANNorthRect bnd_box(dd);			// bounding box for points										// construct bounding rectangle	annEnclRect(pa, pidx, n, dd, bnd_box);										// copy to tree structure	bnd_box_lo = annCopyPt(dd, bnd_box.lo);	bnd_box_hi = annCopyPt(dd, bnd_box.hi);	switch (split) {					// build by rule	case ANN_KD_STD:					// standard kd-splitting rule		root = rbd_tree(pa, pidx, n, dd, bs, bnd_box, kd_split, shrink);		break;	case ANN_KD_MIDPT:					// midpoint split		root = rbd_tree(pa, pidx, n, dd, bs, bnd_box, midpt_split, shrink);		break;	case ANN_KD_SUGGEST:				// best (in our opinion)	case ANN_KD_SL_MIDPT:				// sliding midpoint split		root = rbd_tree(pa, pidx, n, dd, bs, bnd_box, sl_midpt_split, shrink);		break;	case ANN_KD_FAIR:					// fair split		root = rbd_tree(pa, pidx, n, dd, bs, bnd_box, fair_split, shrink);		break;	case ANN_KD_SL_FAIR:				// sliding fair split		root = rbd_tree(pa, pidx, n, dd, bs,						bnd_box, sl_fair_split, shrink);		break;	default:		annError("Illegal splitting method", ANNabort);	}}//----------------------------------------------------------------------//	Shrinking rules//----------------------------------------------------------------------enum ANNdecomp {SPLIT, SHRINK};			// decomposition methods//----------------------------------------------------------------------//	trySimpleShrink - Attempt a simple shrink////		We compute the tight bounding box of the points, and compute//		the 2*dim ``gaps'' between the sides of the tight box and the//		bounding box.  If any of the gaps is large enough relative to//		the longest side of the tight bounding box, then we shrink//		all sides whose gaps are large enough.  (The reason for//		comparing against the tight bounding box, is that after//		shrinking the longest box size will decrease, and if we use//		the standard bounding box, we may decide to shrink twice in//		a row.  Since the tight box is fixed, we cannot shrink twice//		consecutively.)//----------------------------------------------------------------------const float BD_GAP_THRESH = 0.5;		// gap threshold (must be < 1)const int   BD_CT_THRESH  = 2;			// min number of shrink sidesANNdecomp trySimpleShrink(				// try a simple 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	ANNorthRect			&inner_box)		// inner box if shrinking (returned){	int i;												// compute tight bounding box	annEnclRect(pa, pidx, n, dim, inner_box);	ANNcoord max_length = 0;					// find longest box side	for (i = 0; i < dim; i++) {		ANNcoord length = inner_box.hi[i] - inner_box.lo[i];		if (length > max_length) {			max_length = length;		}	}	int shrink_ct = 0;							// number of sides we shrunk	for (i = 0; i < dim; i++) {					// select which sides to shrink												// gap between boxes		ANNcoord gap_hi = bnd_box.hi[i] - inner_box.hi[i];												// big enough gap to shrink?		if (gap_hi < max_length*BD_GAP_THRESH)			inner_box.hi[i] = bnd_box.hi[i];	// no - expand		else shrink_ct++;						// yes - shrink this side

⌨️ 快捷键说明

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