Search in sources :

Example 1 with MTreeSearchCandidate

use of de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.query.MTreeSearchCandidate in project elki by elki-project.

the class MkAppTree method reverseKNNQuery.

/**
 * 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.
 *
 * @param id the query object id
 * @param k the number of nearest neighbors to be returned
 * @return a List of the query results
 */
@Override
public DoubleDBIDList reverseKNNQuery(DBIDRef id, int k) {
    ModifiableDoubleDBIDList result = DBIDUtil.newDistanceDBIDList();
    final Heap<MTreeSearchCandidate> pq = new UpdatableHeap<>();
    // push root
    pq.add(new MTreeSearchCandidate(0., getRootID(), null, Double.NaN));
    // search in tree
    while (!pq.isEmpty()) {
        MTreeSearchCandidate pqNode = pq.poll();
        // FIXME: cache the distance to the routing object in the queue node!
        MkAppTreeNode<O> node = getNode(pqNode.nodeID);
        // directory node
        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 ? FastMath.exp(entry.approximatedValueAt(k)) : entry.approximatedValueAt(k);
                if (approxValue < 0) {
                    approxValue = 0;
                }
                if (minDist <= approxValue) {
                    pq.add(new MTreeSearchCandidate(minDist, getPageID(entry), entry.getRoutingObjectID(), Double.NaN));
                }
            }
        } else // data node
        {
            for (int i = 0; i < node.getNumEntries(); i++) {
                MkAppLeafEntry entry = (MkAppLeafEntry) node.getEntry(i);
                double distance = distance(entry.getRoutingObjectID(), id);
                double approxValue = settings.log ? FastMath.exp(entry.approximatedValueAt(k)) : entry.approximatedValueAt(k);
                if (approxValue < 0) {
                    approxValue = 0;
                }
                if (distance <= approxValue) {
                    result.add(distance, entry.getRoutingObjectID());
                }
            }
        }
    }
    return result;
}
Also used : ModifiableDoubleDBIDList(de.lmu.ifi.dbs.elki.database.ids.ModifiableDoubleDBIDList) UpdatableHeap(de.lmu.ifi.dbs.elki.utilities.datastructures.heap.UpdatableHeap) MTreeSearchCandidate(de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.query.MTreeSearchCandidate)

Example 2 with MTreeSearchCandidate

use of de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.query.MTreeSearchCandidate in project elki by elki-project.

the class MkCoPTree method doReverseKNNQuery.

/**
 * Performs a reverse knn query.
 *
 * @param k the parameter k of the rknn query
 * @param q the id of the query object
 * @param result holds the true results (they need not to be refined)
 * @param candidates holds possible candidates for the result (they need a
 *        refinement)
 */
private void doReverseKNNQuery(int k, DBIDRef q, ModifiableDoubleDBIDList result, ModifiableDBIDs candidates) {
    final ComparableMinHeap<MTreeSearchCandidate> pq = new ComparableMinHeap<>();
    // push root
    pq.add(new MTreeSearchCandidate(0., getRootID(), null, Double.NaN));
    // search in tree
    while (!pq.isEmpty()) {
        MTreeSearchCandidate pqNode = pq.poll();
        // FIXME: cache the distance to the routing object in the queue node!
        MkCoPTreeNode<O> node = getNode(pqNode.nodeID);
        // directory node
        if (!node.isLeaf()) {
            for (int i = 0; i < node.getNumEntries(); i++) {
                MkCoPEntry entry = node.getEntry(i);
                double distance = distance(entry.getRoutingObjectID(), q);
                double minDist = entry.getCoveringRadius() > distance ? 0. : distance - entry.getCoveringRadius();
                double approximatedKnnDist_cons = entry.approximateConservativeKnnDistance(k);
                if (minDist <= approximatedKnnDist_cons) {
                    pq.add(new MTreeSearchCandidate(minDist, getPageID(entry), entry.getRoutingObjectID(), Double.NaN));
                }
            }
        } else // data node
        {
            for (int i = 0; i < node.getNumEntries(); i++) {
                MkCoPLeafEntry entry = (MkCoPLeafEntry) node.getEntry(i);
                double distance = distance(entry.getRoutingObjectID(), q);
                double approximatedKnnDist_prog = entry.approximateProgressiveKnnDistance(k);
                if (distance <= approximatedKnnDist_prog) {
                    result.add(distance, entry.getRoutingObjectID());
                } else {
                    double approximatedKnnDist_cons = entry.approximateConservativeKnnDistance(k);
                    double diff = distance - approximatedKnnDist_cons;
                    if (diff <= 1E-10) {
                        candidates.add(entry.getRoutingObjectID());
                    }
                }
            }
        }
    }
}
Also used : ComparableMinHeap(de.lmu.ifi.dbs.elki.utilities.datastructures.heap.ComparableMinHeap) MTreeSearchCandidate(de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.query.MTreeSearchCandidate)

Aggregations

MTreeSearchCandidate (de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.query.MTreeSearchCandidate)2 ModifiableDoubleDBIDList (de.lmu.ifi.dbs.elki.database.ids.ModifiableDoubleDBIDList)1 ComparableMinHeap (de.lmu.ifi.dbs.elki.utilities.datastructures.heap.ComparableMinHeap)1 UpdatableHeap (de.lmu.ifi.dbs.elki.utilities.datastructures.heap.UpdatableHeap)1