@Override public DoubleDBIDList reverseKNNQuery(DBIDRef id,int k){
  ModifiableDoubleDBIDList result=DBIDUtil.newDistanceDBIDList();
  final Heap<GenericMTreeDistanceSearchCandidate> pq=new UpdatableHeap<>();
  pq.add(new GenericMTreeDistanceSearchCandidate(0.,getRootID(),null));
  while (!pq.isEmpty()) {
    GenericMTreeDistanceSearchCandidate pqNode=pq.poll();
    MkAppTreeNode<O> node=getNode(pqNode.nodeID);
    if (!node.isLeaf()) {
      for (int i=0; i < node.getNumEntries(); i++) {
        MkAppEntry entry=node.getEntry(i);
        double distance=distance(entry.getRoutingObjectID(),id);
        double minDist=(entry.getCoveringRadius() > distance) ? 0. : distance - entry.getCoveringRadius();
        double approxValue=settings.log ? Math.exp(entry.approximatedValueAt(k)) : entry.approximatedValueAt(k);
        if (approxValue < 0) {
          approxValue=0;
        }
        if (minDist <= approxValue) {
          pq.add(new GenericMTreeDistanceSearchCandidate(minDist,getPageID(entry),entry.getRoutingObjectID()));
        }
      }
    }
 else {
      for (int i=0; i < node.getNumEntries(); i++) {
        MkAppLeafEntry entry=(MkAppLeafEntry)node.getEntry(i);
        double distance=distance(entry.getRoutingObjectID(),id);
        double approxValue=settings.log ? StrictMath.exp(entry.approximatedValueAt(k)) : entry.approximatedValueAt(k);
        if (approxValue < 0) {
          approxValue=0;
        }
        if (distance <= approxValue) {
          result.add(distance,entry.getRoutingObjectID());
        }
      }
    }
  }
  return result;
}

@ Override public DoubleDBIDList reverseKNNQuery ( DBIDRef id , int k ) { ModifiableDoubleDBIDList result = DBIDUtil . newDistanceDBIDList ( ) ; final Heap < GenericMTreeDistanceSearchCandidate > pq = new UpdatableHeap < > ( ) ; pq . add ( new GenericMTreeDistanceSearchCandidate ( 0. , getRootID ( ) , null ) ) ; while ( ! pq . isEmpty ( ) ) { GenericMTreeDistanceSearchCandidate pqNode = pq . poll ( ) ; MkAppTreeNode < O > node = getNode ( pqNode . nodeID ) ; if ( ! node . isLeaf ( ) ) { for ( int i = 0 ; i < node . getNumEntries ( ) ; i ++ ) { MkAppEntry entry = node . getEntry ( i ) ; double distance = distance ( entry . getRoutingObjectID ( ) , id ) ; double minDist = ( entry . getCoveringRadius ( ) > distance ) ? 0. : distance - entry . getCoveringRadius ( ) ; double approxValue = settings . log ? Math . exp ( entry . approximatedValueAt ( k ) ) : entry . approximatedValueAt ( k ) ; if ( approxValue < 0 ) { approxValue = 0 ; } if ( minDist <= approxValue ) { pq . add ( new GenericMTreeDistanceSearchCandidate ( minDist , getPageID ( entry ) , entry . getRoutingObjectID ( ) ) ) ; } } } else { for ( int i = 0 ; i < node . getNumEntries ( ) ; i ++ ) { MkAppLeafEntry entry = ( MkAppLeafEntry ) node . getEntry ( i ) ; double distance = distance ( entry . getRoutingObjectID ( ) , id ) ; double approxValue = settings . log ? StrictMath . exp ( entry . approximatedValueAt ( k ) ) : entry . approximatedValueAt ( k ) ; if ( approxValue < 0 ) { approxValue = 0 ; } if ( distance <= approxValue ) { result . add ( distance , entry . getRoutingObjectID ( ) ) ; } } } } return result ; }
performs a reverse k - nearest neighbor query for the given object id . the query result is in ascending order to the distance to the query object .
