From fd79e21b234b65a53d9d93a607200195df1f533f Mon Sep 17 00:00:00 2001 From: Peter Steinbach Date: Wed, 10 Jan 2018 10:55:29 +0100 Subject: [PATCH] added size method similar to STL containers --- Cover_Tree.h | 57 +++++++++++++++++++++++++++++++--------------------- 1 file changed, 34 insertions(+), 23 deletions(-) diff --git a/Cover_Tree.h b/Cover_Tree.h index b2b7beb..14e910b 100644 --- a/Cover_Tree.h +++ b/Cover_Tree.h @@ -28,6 +28,7 @@ #include #include #include +#include #include #include @@ -37,7 +38,7 @@ * * The user should define double Point::distance(const Point& p) and * bool Point::operator==(const Point& p), where - * p1.distance(p2)==0 doesn't necessarily mean that p1==p2). + * p1.distance(p2)==0 doesn't necessarily mean that p1==p2). * * For example, a point could consist of a vector and a string * name, where their distance measure is simply euclidean distance but to be @@ -73,12 +74,12 @@ class CoverTree void removePoint(const Point& p); const std::vector& getPoints() { return _points; } double distance(const CoverTreeNode& p) const; - + bool isSingle() const; bool hasPoint(const Point& p) const; - + const Point& getPoint() const; - + /** * Return every child of the node from any level. This is handy for * the destructor. @@ -101,7 +102,7 @@ class CoverTree bool insert_rec(const Point& p, const std::vector& Qi, const int& level); - + /** * Finds the node in Q with the minimum distance to p. Returns a * pair consisting of this node and the distance. @@ -109,7 +110,7 @@ class CoverTree distNodePair distance(const Point& p, const std::vector& Q); - + void remove_rec(const Point& p, std::map >& coverSets, int level, @@ -126,7 +127,7 @@ class CoverTree * p,q that you will ever try to insert. The cover tree may be invalid * if an inaccurate maxDist is given. */ - + CoverTree(const std::vector& points=std::vector()); ~CoverTree(); @@ -155,6 +156,11 @@ class CoverTree */ void remove(const Point& p); + /** + * Return the number of Points/Nodes currently in the tree + */ + std::size_t size() const ; + /** * Returns the k nearest points to p in order (the 0th element of the vector * is closest to p, 1th is next, etc). It may return greater than k points @@ -201,7 +207,7 @@ CoverTree::~CoverTree() //std::cout << _numNodes << "\n"; delete byeNode; //_numNodes--; - } + } } template @@ -210,15 +216,15 @@ CoverTree::kNearestNodes(const Point& p, const unsigned int k) const { if(_root==NULL) return std::vector(); if(_numNodes<2) return std::vector(1,_root); - + //maxDist is the kth nearest known point to p, and also the farthest //point from p in the set minNodes defined below. double maxDist = p.distance(_root->getPoint()); - + //minNodes stores the k nearest known points to p. std::set minNodes; minNodes.insert(std::make_pair(maxDist,_root)); - + std::vector Qj(1,std::make_pair(maxDist,_root)); for(int level=_maxLevel; level>=_minLevel; level--) { size_t size = Qj.size(); @@ -421,7 +427,7 @@ CoverTree::distance(const Point& p, minNode = *it; } } - return std::make_pair(minDist,minNode); + return std::make_pair(minDist,minNode); } template @@ -432,16 +438,16 @@ void CoverTree::insert(const Point& newPoint) _numNodes=1; return; } - + double rootDist = newPoint.distance(_root->getPoint()); - + if( rootDist == 0.0) { _root->addPoint(newPoint); return; } - + int rqdLevel = ceilf(log(rootDist)/log(base)); - + if(_numNodes == 1) { _maxLevel = rqdLevel+1; _minLevel = rqdLevel-1; @@ -449,11 +455,11 @@ void CoverTree::insert(const Point& newPoint) _numNodes++; return; } - + if(rqdLevel >= _maxLevel) { _maxLevel = rqdLevel + 1; } - + //TODO: this is pretty inefficient, there may be a better way //to check if the node already exists... CoverTreeNode* n = kNearestNodes(newPoint,1)[0]; @@ -510,6 +516,12 @@ void CoverTree::remove(const Point& p) } } +template +std::size_t CoverTree::size() const { + + return _numNodes; +} + template std::vector CoverTree::kNearestNeighbors(const Point& p, const unsigned int k) const @@ -533,13 +545,13 @@ void CoverTree::print() const std::cout << "Empty Tree\n"; return; } - + if(_numNodes==1) { std::cout << "Single Node -- NO levels\n"; _root->getPoint().print(); return; } - + int d = _maxLevel-_minLevel+1; std::vector Q; Q.push_back(_root); @@ -630,7 +642,7 @@ double CoverTree::CoverTreeNode::distance(const CoverTreeNode& p) const { return _points[0].distance(p.getPoint()); } - + template bool CoverTree::CoverTreeNode::isSingle() const { @@ -680,7 +692,7 @@ bool CoverTree::isValidTree() const { } } std::vector allChildren; - for(it=nodes.begin(); it!=nodes.end(); ++it) { + for(it=nodes.begin(); it!=nodes.end(); ++it) { std::vector children = (*it)->getChildren(i); //verify covering tree invariant: the children of node n at level //i are no further than base^i away @@ -699,4 +711,3 @@ bool CoverTree::isValidTree() const { return true; } #endif // _COVER_TREE_H -