package de.lmu.ifi.dbs.elki.utilities.datastructures.heap;
/*
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see .
*/
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import de.lmu.ifi.dbs.elki.database.ids.DBID;
import de.lmu.ifi.dbs.elki.database.query.DistanceResultPair;
import de.lmu.ifi.dbs.elki.database.query.GenericDistanceResultPair;
import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
/**
* Heap used for KNN management.
*
* @author Erich Schubert
*
* @apiviz.has KNNList oneway - - serializes to
*
* @param distance type
*/
public class KNNHeap> extends TiedTopBoundedHeap> {
/**
* Serial version
*/
private static final long serialVersionUID = 1L;
/**
* Maximum distance, usually infiniteDistance
*/
private final D maxdist;
/**
* Constructor.
*
* @param k k Parameter
* @param maxdist k-distance to return for less than k neighbors - usually
* infiniteDistance
*/
public KNNHeap(int k, D maxdist) {
super(k, new Comp());
this.maxdist = maxdist;
}
/**
* Simplified constructor. Will return {@code null} as kNN distance with less
* than k entries.
*
* @param k k Parameter
*/
public KNNHeap(int k) {
this(k, null);
}
@Override
public ArrayList> toSortedArrayList() {
ArrayList> list = super.toSortedArrayList();
Collections.reverse(list);
return list;
}
/**
* Serialize to a {@link KNNList}. This empties the heap!
*
* @return KNNList with the heaps contents.
*/
public KNNList toKNNList() {
return new KNNList(this);
}
/**
* Get the K parameter ("maxsize" internally).
*
* @return K
*/
public int getK() {
return super.getMaxSize();
}
/**
* Get the distance to the k nearest neighbor, or maxdist otherwise.
*
* @return Maximum distance
*/
public D getKNNDistance() {
if(size() < getK()) {
return maxdist;
}
return peek().getDistance();
}
/**
* Get maximum distance in heap
*/
public D getMaximumDistance() {
if(isEmpty()) {
return maxdist;
}
return peek().getDistance();
}
/**
* Add a distance-id pair to the heap unless the distance is too large.
*
* Compared to the super.add() method, this often saves the pair construction.
*
* @param distance Distance value
* @param id ID number
* @return success code
*/
public boolean add(D distance, DBID id) {
if(size() < maxsize || peek().getDistance().compareTo(distance) >= 0) {
return super.add(new GenericDistanceResultPair(distance, id));
}
return true; /* "success" */
}
/**
* Comparator to use.
*
* @author Erich Schubert
*
* @apiviz.exclude
*/
public static class Comp> implements Comparator> {
@Override
public int compare(DistanceResultPair o1, DistanceResultPair o2) {
return -o1.compareByDistance(o2);
}
}
}