Search in sources :

Example 1 with DirectoryEntry

use of de.lmu.ifi.dbs.elki.index.tree.DirectoryEntry in project elki by elki-project.

the class MetricalIndexKNNQuery method getKNNForObject.

@Override
public KNNList getKNNForObject(O q, int k) {
    if (k < 1) {
        throw new IllegalArgumentException("At least one object has to be requested!");
    }
    index.statistics.countKNNQuery();
    KNNHeap knnList = DBIDUtil.newHeap(k);
    double d_k = Double.POSITIVE_INFINITY;
    final ComparableMinHeap<MTreeSearchCandidate> pq = new ComparableMinHeap<>();
    // Push the root node
    pq.add(new MTreeSearchCandidate(0., index.getRootID(), null, 0.));
    // search in tree
    while (!pq.isEmpty()) {
        MTreeSearchCandidate pqNode = pq.poll();
        if (knnList.size() >= k && pqNode.mindist > d_k) {
            break;
        }
        AbstractMTreeNode<?, ?, ?> node = index.getNode(pqNode.nodeID);
        DBID id_p = pqNode.routingObjectID;
        double d1 = pqNode.routingDistance;
        // directory node
        if (!node.isLeaf()) {
            for (int i = 0; i < node.getNumEntries(); i++) {
                MTreeEntry entry = node.getEntry(i);
                DBID o_r = entry.getRoutingObjectID();
                double r_or = entry.getCoveringRadius();
                double d2 = id_p != null ? entry.getParentDistance() : 0.;
                double diff = Math.abs(d1 - d2);
                double sum = d_k + r_or;
                if (diff <= sum) {
                    double d3 = distanceQuery.distance(o_r, q);
                    index.statistics.countDistanceCalculation();
                    double d_min = Math.max(d3 - r_or, 0.);
                    if (d_min <= d_k) {
                        pq.add(new MTreeSearchCandidate(d_min, ((DirectoryEntry) entry).getPageID(), o_r, d3));
                    }
                }
            }
        } else // data node
        {
            for (int i = 0; i < node.getNumEntries(); i++) {
                MTreeEntry entry = node.getEntry(i);
                DBID o_j = entry.getRoutingObjectID();
                double d2 = id_p != null ? entry.getParentDistance() : 0.;
                double diff = Math.abs(d1 - d2);
                if (diff <= d_k) {
                    double d3 = distanceQuery.distance(o_j, q);
                    index.statistics.countDistanceCalculation();
                    if (d3 <= d_k) {
                        knnList.insert(d3, o_j);
                        d_k = knnList.getKNNDistance();
                    }
                }
            }
        }
    }
    return knnList.toKNNList();
}
Also used : ComparableMinHeap(de.lmu.ifi.dbs.elki.utilities.datastructures.heap.ComparableMinHeap) DBID(de.lmu.ifi.dbs.elki.database.ids.DBID) MTreeEntry(de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.MTreeEntry) DirectoryEntry(de.lmu.ifi.dbs.elki.index.tree.DirectoryEntry) KNNHeap(de.lmu.ifi.dbs.elki.database.ids.KNNHeap)

Aggregations

DBID (de.lmu.ifi.dbs.elki.database.ids.DBID)1 KNNHeap (de.lmu.ifi.dbs.elki.database.ids.KNNHeap)1 DirectoryEntry (de.lmu.ifi.dbs.elki.index.tree.DirectoryEntry)1 MTreeEntry (de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.MTreeEntry)1 ComparableMinHeap (de.lmu.ifi.dbs.elki.utilities.datastructures.heap.ComparableMinHeap)1