use of de.lmu.ifi.dbs.elki.utilities.datastructures.heap.UpdatableHeap in project elki by elki-project.
the class FastOPTICS method expandClusterOrder.
/**
* OPTICS algorithm for processing a point, but with different density
* estimates
*
* @param ipt Point
* @param order Cluster order (output)
* @param dq Distance query
* @param prog Progress for logging.
*/
protected void expandClusterOrder(DBID ipt, ClusterOrder order, DistanceQuery<V> dq, FiniteProgress prog) {
UpdatableHeap<OPTICSHeapEntry> heap = new UpdatableHeap<>();
heap.add(new OPTICSHeapEntry(ipt, null, Double.POSITIVE_INFINITY));
while (!heap.isEmpty()) {
final OPTICSHeapEntry current = heap.poll();
DBID currPt = current.objectID;
order.add(currPt, current.reachability, current.predecessorID);
processed.add(currPt);
double coredist = inverseDensities.doubleValue(currPt);
for (DBIDIter it = neighs.get(currPt).iter(); it.valid(); it.advance()) {
if (processed.contains(it)) {
continue;
}
double nrdist = dq.distance(currPt, it);
if (coredist > nrdist) {
nrdist = coredist;
}
if (reachDist.doubleValue(it) == UNDEFINED_DISTANCE) {
reachDist.put(it, nrdist);
} else if (nrdist < reachDist.doubleValue(it)) {
reachDist.put(it, nrdist);
}
heap.add(new OPTICSHeapEntry(DBIDUtil.deref(it), currPt, nrdist));
}
LOG.incrementProcessed(prog);
}
}
use of de.lmu.ifi.dbs.elki.utilities.datastructures.heap.UpdatableHeap 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;
}
Aggregations