summaryrefslogtreecommitdiff
path: root/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/query/MetricalIndexKNNQuery.java
diff options
context:
space:
mode:
authorErich Schubert <erich@debian.org>2013-10-29 20:02:37 +0100
committerAndrej Shadura <andrewsh@debian.org>2019-03-09 22:30:37 +0000
commitec7f409f6e795bbcc6f3c005687954e9475c600c (patch)
treefbf36c0ab791c556198b487ca40ae56ae5ab1ee5 /src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/query/MetricalIndexKNNQuery.java
parent974d4cf6d54cadc06258039f2cd0515cc34aeac6 (diff)
parent8300861dc4c62c5567a4e654976072f854217544 (diff)
Import Debian changes 0.6.0~beta2-1
elki (0.6.0~beta2-1) unstable; urgency=low * New upstream beta release. * 3DPC extension is not yet included.
Diffstat (limited to 'src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/query/MetricalIndexKNNQuery.java')
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/query/MetricalIndexKNNQuery.java83
1 files changed, 34 insertions, 49 deletions
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/query/MetricalIndexKNNQuery.java b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/query/MetricalIndexKNNQuery.java
index c2fafdae..f40e001b 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/query/MetricalIndexKNNQuery.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/query/MetricalIndexKNNQuery.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.query;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2012
+ Copyright (C) 2013
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
@@ -23,25 +23,19 @@ package de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.query;
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-import java.util.List;
-
-import de.lmu.ifi.dbs.elki.database.ids.ArrayDBIDs;
import de.lmu.ifi.dbs.elki.database.ids.DBID;
-import de.lmu.ifi.dbs.elki.database.ids.DBIDRef;
+import de.lmu.ifi.dbs.elki.database.ids.DBIDUtil;
+import de.lmu.ifi.dbs.elki.database.ids.distance.KNNHeap;
+import de.lmu.ifi.dbs.elki.database.ids.distance.KNNList;
import de.lmu.ifi.dbs.elki.database.query.distance.DistanceQuery;
import de.lmu.ifi.dbs.elki.database.query.knn.AbstractDistanceKNNQuery;
-import de.lmu.ifi.dbs.elki.distance.DistanceUtil;
-import de.lmu.ifi.dbs.elki.distance.distanceresultlist.KNNHeap;
-import de.lmu.ifi.dbs.elki.distance.distanceresultlist.KNNResult;
-import de.lmu.ifi.dbs.elki.distance.distanceresultlist.KNNUtil;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
+import de.lmu.ifi.dbs.elki.distance.distancevalue.NumberDistance;
import de.lmu.ifi.dbs.elki.index.tree.DirectoryEntry;
import de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.AbstractMTree;
import de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.AbstractMTreeNode;
import de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.MTreeEntry;
-import de.lmu.ifi.dbs.elki.index.tree.query.GenericMTreeDistanceSearchCandidate;
-import de.lmu.ifi.dbs.elki.utilities.datastructures.heap.Heap;
-import de.lmu.ifi.dbs.elki.utilities.exceptions.ExceptionMessages;
+import de.lmu.ifi.dbs.elki.index.tree.query.DoubleMTreeDistanceSearchCandidate;
+import de.lmu.ifi.dbs.elki.utilities.datastructures.heap.ComparableMinHeap;
/**
* Instance of a KNN query for a particular spatial index.
@@ -53,11 +47,11 @@ import de.lmu.ifi.dbs.elki.utilities.exceptions.ExceptionMessages;
* @param <O> Object type
* @param <D> Distance type
*/
-public class MetricalIndexKNNQuery<O, D extends Distance<D>> extends AbstractDistanceKNNQuery<O, D> {
+public class MetricalIndexKNNQuery<O, D extends NumberDistance<D, ?>> extends AbstractDistanceKNNQuery<O, D> {
/**
* The index to use
*/
- protected final AbstractMTree<O, D, ?, ?> index;
+ protected final AbstractMTree<O, D, ?, ?, ?> index;
/**
* Constructor.
@@ -65,55 +59,56 @@ public class MetricalIndexKNNQuery<O, D extends Distance<D>> extends AbstractDis
* @param index Index to use
* @param distanceQuery Distance query used
*/
- public MetricalIndexKNNQuery(AbstractMTree<O, D, ?, ?> index, DistanceQuery<O, D> distanceQuery) {
+ public MetricalIndexKNNQuery(AbstractMTree<O, D, ?, ?, ?> index, DistanceQuery<O, D> distanceQuery) {
super(distanceQuery);
this.index = index;
}
@Override
- public KNNResult<D> getKNNForObject(O q, int k) {
+ public KNNList<D> getKNNForObject(O q, int k) {
if (k < 1) {
throw new IllegalArgumentException("At least one object has to be requested!");
}
+ index.statistics.countKNNQuery();
- final D nullDistance = index.getDistanceFactory().nullDistance();
- KNNHeap<D> knnList = KNNUtil.newHeap(distanceQuery.getDistanceFactory(), k);
+ KNNHeap<D> knnList = DBIDUtil.newHeap(distanceQuery.getDistanceFactory(), k);
D d_k = knnList.getKNNDistance();
- final Heap<GenericMTreeDistanceSearchCandidate<D>> pq = new Heap<GenericMTreeDistanceSearchCandidate<D>>();
+ final ComparableMinHeap<DoubleMTreeDistanceSearchCandidate> pq = new ComparableMinHeap<>();
// push root
- pq.add(new GenericMTreeDistanceSearchCandidate<D>(nullDistance, index.getRootID(), null, nullDistance));
+ pq.add(new DoubleMTreeDistanceSearchCandidate(0., index.getRootID(), null, 0.));
// search in tree
while (!pq.isEmpty()) {
- GenericMTreeDistanceSearchCandidate<D> pqNode = pq.poll();
+ DoubleMTreeDistanceSearchCandidate pqNode = pq.poll();
- if (knnList.size() >= k && pqNode.mindist.compareTo(d_k) > 0) {
+ if (knnList.size() >= k && pqNode.mindist > d_k.doubleValue()) {
break;
}
AbstractMTreeNode<?, D, ?, ?> node = index.getNode(pqNode.nodeID);
DBID id_p = pqNode.routingObjectID;
- D d1 = pqNode.routingDistance;
+ double d1 = pqNode.routingDistance;
// directory node
if (!node.isLeaf()) {
for (int i = 0; i < node.getNumEntries(); i++) {
- MTreeEntry<D> entry = node.getEntry(i);
+ MTreeEntry entry = node.getEntry(i);
DBID o_r = entry.getRoutingObjectID();
- D r_or = entry.getCoveringRadius();
- D d2 = id_p != null ? entry.getParentDistance() : nullDistance;
+ double r_or = entry.getCoveringRadius();
+ double d2 = id_p != null ? entry.getParentDistance() : 0.;
- D diff = d1.compareTo(d2) > 0 ? d1.minus(d2) : d2.minus(d1);
+ double diff = Math.abs(d1 - d2);
- D sum = d_k.plus(r_or);
+ double sum = d_k.doubleValue() + r_or;
- if (diff.compareTo(sum) <= 0) {
- D d3 = distanceQuery.distance(o_r, q);
- D d_min = DistanceUtil.max(d3.minus(r_or), index.getDistanceFactory().nullDistance());
- if (d_min.compareTo(d_k) <= 0) {
- pq.add(new GenericMTreeDistanceSearchCandidate<D>(d_min, ((DirectoryEntry) entry).getPageID(), o_r, d3));
+ if (diff <= sum) {
+ double d3 = distanceQuery.distance(o_r, q).doubleValue();
+ index.statistics.countDistanceCalculation();
+ double d_min = Math.max(d3 - r_or, 0.);
+ if (d_min <= d_k.doubleValue()) {
+ pq.add(new DoubleMTreeDistanceSearchCandidate(d_min, ((DirectoryEntry) entry).getPageID(), o_r, d3));
}
}
}
@@ -121,15 +116,16 @@ public class MetricalIndexKNNQuery<O, D extends Distance<D>> extends AbstractDis
// data node
else {
for (int i = 0; i < node.getNumEntries(); i++) {
- MTreeEntry<D> entry = node.getEntry(i);
+ MTreeEntry entry = node.getEntry(i);
DBID o_j = entry.getRoutingObjectID();
- D d2 = id_p != null ? entry.getParentDistance() : nullDistance;
+ double d2 = id_p != null ? entry.getParentDistance() : 0.;
- D diff = (d1.compareTo(d2) > 0) ? d1.minus(d2) : d2.minus(d1);
+ double diff = Math.abs(d1 - d2);
- if (diff.compareTo(d_k) <= 0) {
+ if (diff <= d_k.doubleValue()) {
D d3 = distanceQuery.distance(o_j, q);
+ index.statistics.countDistanceCalculation();
if (d3.compareTo(d_k) <= 0) {
knnList.add(d3, o_j);
d_k = knnList.getKNNDistance();
@@ -140,15 +136,4 @@ public class MetricalIndexKNNQuery<O, D extends Distance<D>> extends AbstractDis
}
return knnList.toKNNList();
}
-
- @Override
- public KNNResult<D> getKNNForDBID(DBIDRef id, int k) {
- return getKNNForObject(relation.get(id), k);
- }
-
- @Override
- public List<KNNResult<D>> getKNNForBulkDBIDs(ArrayDBIDs ids, int k) {
- // TODO: implement
- throw new UnsupportedOperationException(ExceptionMessages.UNSUPPORTED_NOT_YET);
- }
}