44 #include <unordered_set> 
   68 template <
typename _T>
 
   75   using DataDist = std::pair<const _T*, double>;
 
   76   struct DataDistCompare
 
   78     bool operator()(
const DataDist& d0, 
const DataDist& d1)
 
   80       return d0.second < d1.second;
 
   83   using NearQueue = std::priority_queue<DataDist, std::vector<DataDist>, DataDistCompare>;
 
   88   using NodeDist = std::pair<Node*, double>;
 
   89   struct NodeDistCompare
 
   91     bool operator()(
const NodeDist& n0, 
const NodeDist& n1)
 const 
   93       return (n0.second - n0.first->maxRadius_) > (n1.second - n1.first->maxRadius_);
 
   96   using NodeQueue = std::priority_queue<NodeDist, std::vector<NodeDist>, NodeDistCompare>;
 
  101                        unsigned int maxNumPtsPerLeaf = 50, 
unsigned int removedCacheSize = 500,
 
  102                        bool rebalancing = 
false)
 
  108     , 
rebuildSize_(rebalancing ? maxNumPtsPerLeaf * degree : std::numeric_limits<std::size_t>::max())
 
  136     if (
rebuildSize_ != std::numeric_limits<std::size_t>::max())
 
  145   void add(
const _T& data)
 override 
  159   void add(
const std::vector<_T>& data)
 override 
  163     else if (!data.empty())
 
  166       for (
unsigned int i = 1; i < data.size(); ++i)
 
  168       size_ += data.size();
 
  193     const _T* 
d = nbh_queue.top().first;
 
  211       if (!nbh_queue.empty())
 
  212         return *nbh_queue.top().first;
 
  214     throw moveit::Exception(
"No elements found in nearest neighbors data structure");
 
  218   void nearestK(
const _T& data, std::size_t k, std::vector<_T>& nbh)
 const override 
  232   void nearestR(
const _T& data, 
double radius, std::vector<_T>& nbh)
 const override 
  243   std::size_t 
size()
 const override 
  248   void list(std::vector<_T>& data)
 const override 
  251     data.reserve(
size());
 
  264         out << 
"Elements marked for removal:\n";
 
  265         for (
typename std::unordered_set<const _T*>::const_iterator it = gnat.
removed_.begin();
 
  278     std::unordered_set<const _T*> tmp;
 
  283     for (
typename std::unordered_set<const _T*>::iterator it = tmp.begin(); it != tmp.end(); ++it)
 
  286       for (i = 0; i < lst.size(); ++i)
 
  292         std::cout << 
"***** FAIL!! ******\n" << *
this << 
'\n';
 
  293         for (
unsigned int j = 0; j < lst.size(); ++j)
 
  294           std::cout << lst[j] << 
'\t';
 
  297       assert(i != lst.size());
 
  303     if (lst.size() != 
size_)
 
  304       std::cout << 
"#########################################\n" << *
this << 
'\n';
 
  305     assert(lst.size() == 
size_);
 
  326     NodeQueue node_queue;
 
  330     tree_->
nearestK(*
this, data, k, nbhQueue, node_queue, is_pivot);
 
  331     while (!node_queue.empty())
 
  333       dist = nbhQueue.top().second;  
 
  334       node_dist = node_queue.top();
 
  336       if (nbhQueue.size() == k && (node_dist.second > node_dist.first->maxRadius_ + dist ||
 
  337                                    node_dist.second < node_dist.first->minRadius_ - dist))
 
  339       node_dist.first->nearestK(*
this, data, k, nbhQueue, node_queue, is_pivot);
 
  346     double dist = radius;  
 
  347     NodeQueue node_queue;
 
  352     while (!node_queue.empty())
 
  354       node_dist = node_queue.top();
 
  356       if (node_dist.second > node_dist.first->maxRadius_ + dist || node_dist.second < node_dist.first->minRadius_ - dist)
 
  358       node_dist.first->nearestR(*
this, data, radius, nbhQueue, node_queue);
 
  365     typename std::vector<_T>::reverse_iterator it;
 
  366     nbh.resize(nbhQueue.size());
 
  367     for (it = nbh.rbegin(); it != nbh.rend(); it++, nbhQueue.pop())
 
  368       *it = *nbhQueue.top().first;
 
  377     Node(
int degree, 
int capacity, _T pivot)
 
  379       , 
pivot_(std::move(pivot))
 
  380       , 
minRadius_(std::numeric_limits<double>::infinity())
 
  386       data_.reserve(capacity + 1);
 
  391       for (
unsigned int i = 0; i < 
children_.size(); ++i)
 
  411         activity_ = std::max(-32, activity_ - 1);
 
  429         data_.push_back(data);
 
  446         std::vector<double> dist(
children_.size());
 
  450         for (
unsigned int i = 1; i < 
children_.size(); ++i)
 
  456         for (
unsigned int i = 0; i < 
children_.size(); ++i)
 
  458         children_[min_ind]->updateRadius(min_dist);
 
  465       unsigned int sz = 
data_.size();
 
  474       std::vector<unsigned int> pivots;
 
  478       for (
unsigned int& pivot : pivots)
 
  481       for (
unsigned int j = 0; j < 
data_.size(); ++j)
 
  484         for (
unsigned int i = 1; i < 
degree_; ++i)
 
  485           if (dists(j, i) < dists(j, k))
 
  493         for (
unsigned int i = 0; i < 
degree_; ++i)
 
  497       for (
unsigned int i = 0; i < 
degree_; ++i)
 
  511       for (
unsigned int i = 0; i < 
degree_; ++i)
 
  517     bool insertNeighborK(NearQueue& nbh, std::size_t k, 
const _T& data, 
const _T& key, 
double dist)
 const 
  521         nbh.push(std::make_pair(&data, dist));
 
  524       if (dist < nbh.top().second || (dist < std::numeric_limits<double>::epsilon() && data == key))
 
  527         nbh.push(std::make_pair(&data, dist));
 
  538     void nearestK(
const GNAT& gnat, 
const _T& data, std::size_t k, NearQueue& nbh, NodeQueue& nodeQueue,
 
  541       for (
unsigned int i = 0; i < 
data_.size(); ++i)
 
  551         std::vector<double> dist_to_pivot(
children_.size());
 
  552         std::vector<int> permutation(
children_.size());
 
  553         for (
unsigned int i = 0; i < permutation.size(); ++i)
 
  555         std::random_shuffle(permutation.begin(), permutation.end());
 
  557         for (
unsigned int i = 0; i < 
children_.size(); ++i)
 
  558           if (permutation[i] >= 0)
 
  561             dist_to_pivot[permutation[i]] = gnat.
distFun_(data, child->
pivot_);
 
  566               dist = nbh.top().second;  
 
  567               for (
unsigned int j = 0; j < 
children_.size(); ++j)
 
  568                 if (permutation[j] >= 0 && i != j &&
 
  569                     (dist_to_pivot[permutation[i]] - dist > child->
maxRange_[permutation[j]] ||
 
  570                      dist_to_pivot[permutation[i]] + dist < child->
minRange_[permutation[j]]))
 
  575         dist = nbh.top().second;
 
  576         for (
unsigned int i = 0; i < 
children_.size(); ++i)
 
  577           if (permutation[i] >= 0)
 
  580             if (nbh.size() < k || (dist_to_pivot[permutation[i]] - dist <= child->
maxRadius_ &&
 
  581                                    dist_to_pivot[permutation[i]] + dist >= child->
minRadius_))
 
  582               nodeQueue.push(std::make_pair(child, dist_to_pivot[permutation[i]]));
 
  590         nbh.push(std::make_pair(&data, dist));
 
  595     void nearestR(
const GNAT& gnat, 
const _T& data, 
double r, NearQueue& nbh, NodeQueue& nodeQueue)
 const 
  599       for (
unsigned int i = 0; i < 
data_.size(); ++i)
 
  605         std::vector<double> dist_to_pivot(
children_.size());
 
  606         std::vector<int> permutation(
children_.size());
 
  607         for (
unsigned int i = 0; i < permutation.size(); ++i)
 
  609         std::random_shuffle(permutation.begin(), permutation.end());
 
  611         for (
unsigned int i = 0; i < 
children_.size(); ++i)
 
  612           if (permutation[i] >= 0)
 
  617             for (
unsigned int j = 0; j < 
children_.size(); ++j)
 
  618               if (permutation[j] >= 0 && i != j &&
 
  619                   (dist_to_pivot[i] - dist > child->
maxRange_[permutation[j]] ||
 
  620                    dist_to_pivot[i] + dist < child->
minRange_[permutation[j]]))
 
  624         for (
unsigned int i = 0; i < 
children_.size(); ++i)
 
  625           if (permutation[i] >= 0)
 
  628             if (dist_to_pivot[i] - dist <= child->
maxRadius_ && dist_to_pivot[i] + dist >= child->
minRadius_)
 
  629               nodeQueue.push(std::make_pair(child, dist_to_pivot[i]));
 
  634     void list(
const GNAT& gnat, std::vector<_T>& data)
 const 
  638       for (
unsigned int i = 0; i < 
data_.size(); ++i)
 
  640           data.push_back(
data_[i]);
 
  641       for (
unsigned int i = 0; i < 
children_.size(); ++i)
 
  647       out << 
"\ndegree:\t" << node.
degree_;
 
  650       out << 
"\nminRange:\t";
 
  651       for (
unsigned int i = 0; i < node.
minRange_.size(); ++i)
 
  653       out << 
"\nmaxRange: ";
 
  654       for (
unsigned int i = 0; i < node.
maxRange_.size(); ++i)
 
  656       out << 
"\npivot:\t" << node.
pivot_;
 
  658       for (
unsigned int i = 0; i < node.
data_.size(); ++i)
 
  659         out << node.
data_[i] << 
'\t';
 
  660       out << 
"\nthis:\t" << &node;
 
  661       out << 
"\nchildren:\n";
 
  662       for (
unsigned int i = 0; i < node.
children_.size(); ++i)
 
  665       for (
unsigned int i = 0; i < node.
children_.size(); ++i)
 
An instance of this class can be used to greedily select a given number of representatives from a set...
 
Eigen::MatrixXd Matrix
A matrix type for storing distances between points and centers.
 
bool insertNeighborK(NearQueue &nbh, std::size_t k, const _T &data, const _T &key, double dist) const
 
std::vector< double > maxRange_
 
void nearestR(const GNAT &gnat, const _T &data, double r, NearQueue &nbh, NodeQueue &nodeQueue) const
 
void updateRadius(double dist)
 
void list(const GNAT &gnat, std::vector< _T > &data) const
 
void updateRange(unsigned int i, double dist)
 
Node(int degree, int capacity, _T pivot)
 
friend std::ostream & operator<<(std::ostream &out, const Node &node)
 
std::vector< Node * > children_
 
bool needToSplit(const GNAT &gnat) const
 
std::vector< double > minRange_
 
void insertNeighborR(NearQueue &nbh, double r, const _T &data, double dist) const
 
void add(GNAT &gnat, const _T &data)
 
void nearestK(const GNAT &gnat, const _T &data, std::size_t k, NearQueue &nbh, NodeQueue &nodeQueue, bool &isPivot) const
 
Geometric Near-neighbor Access Tree (GNAT), a data structure for nearest neighbor search.
 
friend std::ostream & operator<<(std::ostream &out, const NearestNeighborsGNAT< _T > &gnat)
 
std::size_t removedCacheSize_
 
std::size_t size() const override
Get the number of elements in the datastructure.
 
void list(std::vector< _T > &data) const override
Get all the elements in the datastructure.
 
~NearestNeighborsGNAT() override
 
void setDistanceFunction(const typename NearestNeighbors< _T >::DistanceFunction &distFun) override
 
void rebuildDataStructure()
 
bool remove(const _T &data) override
Remove an element from the datastructure.
 
void nearestR(const _T &data, double radius, std::vector< _T > &nbh) const override
Get the nearest neighbors of a point, within a specified radius.
 
void add(const _T &data) override
Add an element to the datastructure.
 
void clear() override
Clear the datastructure.
 
void postprocessNearest(NearQueue &nbhQueue, std::vector< _T > &nbh) const
 
unsigned int maxNumPtsPerLeaf_
 
void nearestRInternal(const _T &data, double radius, NearQueue &nbhQueue) const
 
std::unordered_set< const _T * > removed_
 
GreedyKCenters< _T > pivotSelector_
 
NearestNeighborsGNAT(unsigned int degree=8, unsigned int minDegree=4, unsigned int maxDegree=12, unsigned int maxNumPtsPerLeaf=50, unsigned int removedCacheSize=500, bool rebalancing=false)
 
void add(const std::vector< _T > &data) override
Add a vector of points.
 
bool reportsSortedResults() const override
Return true if the solutions reported by this data structure are sorted, when calling nearestK / near...
 
bool nearestKInternal(const _T &data, std::size_t k, NearQueue &nbhQueue) const
 
void nearestK(const _T &data, std::size_t k, std::vector< _T > &nbh) const override
Get the k-nearest neighbors of a point.
 
_T nearest(const _T &data) const override
Get the nearest neighbor of a point.
 
bool isRemoved(const _T &data) const
 
Abstract representation of a container that can perform nearest neighbors queries.
 
virtual void add(const _T &data)=0
Add an element to the datastructure.
 
std::function< double(const _T &, const _T &)> DistanceFunction
The definition of a distance function.
 
virtual void setDistanceFunction(const DistanceFunction &distFun)
Set the distance function to use.
 
DistanceFunction distFun_
The used distance function.
 
This may be thrown if unrecoverable errors occur.