Search in sources :

Example 1 with DeLiCluEntry

use of de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.deliclu.DeLiCluEntry in project elki by elki-project.

the class DeLiClu method expandDirNodes.

/**
 * Expands the specified directory nodes.
 *
 * @param distFunction the spatial distance function of this algorithm
 * @param node1 the first node
 * @param node2 the second node
 */
private void expandDirNodes(SpatialPrimitiveDistanceFunction<NV> distFunction, DeLiCluNode node1, DeLiCluNode node2) {
    if (LOG.isDebuggingFinest()) {
        LOG.debugFinest("ExpandDirNodes: " + node1.getPageID() + " + " + node2.getPageID());
    }
    int numEntries_1 = node1.getNumEntries();
    int numEntries_2 = node2.getNumEntries();
    // node1-node2 into pq
    for (int i = 0; i < numEntries_1; i++) {
        DeLiCluEntry entry1 = node1.getEntry(i);
        if (!entry1.hasUnhandled()) {
            continue;
        }
        for (int j = 0; j < numEntries_2; j++) {
            DeLiCluEntry entry2 = node2.getEntry(j);
            if (!entry2.hasHandled()) {
                continue;
            }
            double distance = distFunction.minDist(entry1, entry2);
            SpatialObjectPair nodePair = new SpatialObjectPair(distance, entry1, entry2, true);
            heap.add(nodePair);
        }
    }
}
Also used : DeLiCluEntry(de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.deliclu.DeLiCluEntry)

Example 2 with DeLiCluEntry

use of de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.deliclu.DeLiCluEntry in project elki by elki-project.

the class DeLiClu method run.

public ClusterOrder run(Database database, Relation<NV> relation) {
    Collection<DeLiCluTreeIndex<NV>> indexes = ResultUtil.filterResults(database.getHierarchy(), relation, DeLiCluTreeIndex.class);
    if (indexes.size() != 1) {
        throw new MissingPrerequisitesException("DeLiClu found " + indexes.size() + " DeLiCluTree indexes. DeLiClu needs a special index to operate, therefore you need to add this index to your database.");
    }
    DeLiCluTreeIndex<NV> index = indexes.iterator().next();
    if (!(getDistanceFunction() instanceof SpatialPrimitiveDistanceFunction<?>)) {
        throw new IllegalArgumentException("Distance Function must be an instance of " + SpatialPrimitiveDistanceFunction.class.getName());
    }
    @SuppressWarnings("unchecked") SpatialPrimitiveDistanceFunction<NV> distFunction = (SpatialPrimitiveDistanceFunction<NV>) getDistanceFunction();
    // first do the knn-Join
    if (LOG.isVerbose()) {
        LOG.verbose("knnJoin...");
    }
    Relation<KNNList> knns = knnJoin.run(relation);
    DBIDs ids = relation.getDBIDs();
    final int size = ids.size();
    FiniteProgress progress = LOG.isVerbose() ? new FiniteProgress("DeLiClu", size, LOG) : null;
    ClusterOrder clusterOrder = new ClusterOrder(ids, "DeLiClu Clustering", "deliclu-clustering");
    heap = new UpdatableHeap<>();
    // add start object to cluster order and (root, root) to priority queue
    DBID startID = DBIDUtil.deref(ids.iter());
    clusterOrder.add(startID, Double.POSITIVE_INFINITY, null);
    int numHandled = 1;
    index.setHandled(startID, relation.get(startID));
    SpatialDirectoryEntry rootEntry = (SpatialDirectoryEntry) index.getRootEntry();
    SpatialObjectPair spatialObjectPair = new SpatialObjectPair(0., rootEntry, rootEntry, true);
    heap.add(spatialObjectPair);
    while (numHandled < size) {
        if (heap.isEmpty()) {
            throw new AbortException("DeLiClu heap was empty when it shouldn't have been.");
        }
        SpatialObjectPair dataPair = heap.poll();
        // pair of nodes
        if (dataPair.isExpandable) {
            expandNodes(index, distFunction, dataPair, knns);
        } else // pair of objects
        {
            // set handled
            LeafEntry e1 = (LeafEntry) dataPair.entry1;
            LeafEntry e2 = (LeafEntry) dataPair.entry2;
            final DBID e1id = e1.getDBID();
            IndexTreePath<DeLiCluEntry> path = index.setHandled(e1id, relation.get(e1id));
            if (path == null) {
                throw new RuntimeException("snh: parent(" + e1id + ") = null!!!");
            }
            // add to cluster order
            clusterOrder.add(e1id, dataPair.distance, e2.getDBID());
            numHandled++;
            // reinsert expanded leafs
            reinsertExpanded(distFunction, index, path, knns);
            if (progress != null) {
                progress.setProcessed(numHandled, LOG);
            }
        }
    }
    LOG.ensureCompleted(progress);
    return clusterOrder;
}
Also used : DeLiCluEntry(de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.deliclu.DeLiCluEntry) DBID(de.lmu.ifi.dbs.elki.database.ids.DBID) LeafEntry(de.lmu.ifi.dbs.elki.index.tree.LeafEntry) DBIDs(de.lmu.ifi.dbs.elki.database.ids.DBIDs) FiniteProgress(de.lmu.ifi.dbs.elki.logging.progress.FiniteProgress) MissingPrerequisitesException(de.lmu.ifi.dbs.elki.utilities.exceptions.MissingPrerequisitesException) SpatialDirectoryEntry(de.lmu.ifi.dbs.elki.index.tree.spatial.SpatialDirectoryEntry) KNNList(de.lmu.ifi.dbs.elki.database.ids.KNNList) DeLiCluTreeIndex(de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.deliclu.DeLiCluTreeIndex) SpatialPrimitiveDistanceFunction(de.lmu.ifi.dbs.elki.distance.distancefunction.SpatialPrimitiveDistanceFunction) AbortException(de.lmu.ifi.dbs.elki.utilities.exceptions.AbortException)

Example 3 with DeLiCluEntry

use of de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.deliclu.DeLiCluEntry in project elki by elki-project.

the class DeLiClu method reinsertExpanded.

/**
 * Reinserts the objects of the already expanded nodes.
 *
 * @param distFunction the spatial distance function of this algorithm
 * @param index the index storing the objects
 * @param path the path of the object inserted last
 * @param knns the knn list
 */
private void reinsertExpanded(SpatialPrimitiveDistanceFunction<NV> distFunction, DeLiCluTree index, IndexTreePath<DeLiCluEntry> path, Relation<KNNList> knns) {
    // Count the number of components.
    int l = 0;
    for (IndexTreePath<DeLiCluEntry> it = path; it != null; it = it.getParentPath()) {
        l++;
    }
    ArrayList<IndexTreePath<DeLiCluEntry>> p = new ArrayList<>(l - 1);
    // All except the last (= root).
    IndexTreePath<DeLiCluEntry> it = path;
    for (; it.getParentPath() != null; it = it.getParentPath()) {
        p.add(it);
    }
    assert (p.size() == l - 1);
    DeLiCluEntry rootEntry = it.getEntry();
    reinsertExpanded(distFunction, index, p, l - 2, rootEntry, knns);
}
Also used : DeLiCluEntry(de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.deliclu.DeLiCluEntry) IndexTreePath(de.lmu.ifi.dbs.elki.index.tree.IndexTreePath) ArrayList(java.util.ArrayList)

Example 4 with DeLiCluEntry

use of de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.deliclu.DeLiCluEntry in project elki by elki-project.

the class DeLiClu method expandLeafNodes.

/**
 * Expands the specified leaf nodes.
 *
 * @param distFunction the spatial distance function of this algorithm
 * @param node1 the first node
 * @param node2 the second node
 * @param knns the knn list
 */
private void expandLeafNodes(SpatialPrimitiveDistanceFunction<NV> distFunction, DeLiCluNode node1, DeLiCluNode node2, Relation<KNNList> knns) {
    if (LOG.isDebuggingFinest()) {
        LOG.debugFinest("ExpandLeafNodes: " + node1.getPageID() + " + " + node2.getPageID());
    }
    int numEntries_1 = node1.getNumEntries();
    int numEntries_2 = node2.getNumEntries();
    // node1-node2 into pq
    for (int i = 0; i < numEntries_1; i++) {
        DeLiCluEntry entry1 = node1.getEntry(i);
        if (!entry1.hasUnhandled()) {
            continue;
        }
        for (int j = 0; j < numEntries_2; j++) {
            DeLiCluEntry entry2 = node2.getEntry(j);
            if (!entry2.hasHandled()) {
                continue;
            }
            double distance = distFunction.minDist(entry1, entry2);
            double reach = MathUtil.max(distance, knns.get(((LeafEntry) entry2).getDBID()).getKNNDistance());
            SpatialObjectPair dataPair = new SpatialObjectPair(reach, entry1, entry2, false);
            heap.add(dataPair);
        }
    }
}
Also used : DeLiCluEntry(de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.deliclu.DeLiCluEntry)

Example 5 with DeLiCluEntry

use of de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.deliclu.DeLiCluEntry in project elki by elki-project.

the class DeLiClu method reinsertExpanded.

private void reinsertExpanded(SpatialPrimitiveDistanceFunction<NV> distFunction, DeLiCluTree index, List<IndexTreePath<DeLiCluEntry>> path, int pos, DeLiCluEntry parentEntry, Relation<KNNList> knns) {
    DeLiCluNode parentNode = index.getNode(parentEntry);
    SpatialEntry entry2 = path.get(pos).getEntry();
    if (entry2 instanceof LeafEntry) {
        assert (pos == 0);
        for (int i = 0; i < parentNode.getNumEntries(); i++) {
            DeLiCluEntry entry1 = parentNode.getEntry(i);
            if (entry1.hasHandled()) {
                continue;
            }
            double distance = distFunction.minDist(entry1, entry2);
            double reach = MathUtil.max(distance, knns.get(((LeafEntry) entry2).getDBID()).getKNNDistance());
            SpatialObjectPair dataPair = new SpatialObjectPair(reach, entry1, entry2, false);
            heap.add(dataPair);
        }
        return;
    }
    IntSet expanded = index.getExpanded(entry2);
    for (int i = 0; i < parentNode.getNumEntries(); i++) {
        DeLiCluDirectoryEntry entry1 = (DeLiCluDirectoryEntry) parentNode.getEntry(i);
        // not yet expanded
        if (!expanded.contains(entry1.getPageID())) {
            double distance = distFunction.minDist(entry1, entry2);
            SpatialObjectPair nodePair = new SpatialObjectPair(distance, entry1, entry2, true);
            heap.add(nodePair);
        } else // already expanded
        {
            reinsertExpanded(distFunction, index, path, pos - 1, entry1, knns);
        }
    }
}
Also used : DeLiCluEntry(de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.deliclu.DeLiCluEntry) LeafEntry(de.lmu.ifi.dbs.elki.index.tree.LeafEntry) IntSet(it.unimi.dsi.fastutil.ints.IntSet) DeLiCluDirectoryEntry(de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.deliclu.DeLiCluDirectoryEntry) DeLiCluNode(de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.deliclu.DeLiCluNode) SpatialEntry(de.lmu.ifi.dbs.elki.index.tree.spatial.SpatialEntry)

Aggregations

DeLiCluEntry (de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.deliclu.DeLiCluEntry)5 LeafEntry (de.lmu.ifi.dbs.elki.index.tree.LeafEntry)2 DBID (de.lmu.ifi.dbs.elki.database.ids.DBID)1 DBIDs (de.lmu.ifi.dbs.elki.database.ids.DBIDs)1 KNNList (de.lmu.ifi.dbs.elki.database.ids.KNNList)1 SpatialPrimitiveDistanceFunction (de.lmu.ifi.dbs.elki.distance.distancefunction.SpatialPrimitiveDistanceFunction)1 IndexTreePath (de.lmu.ifi.dbs.elki.index.tree.IndexTreePath)1 SpatialDirectoryEntry (de.lmu.ifi.dbs.elki.index.tree.spatial.SpatialDirectoryEntry)1 SpatialEntry (de.lmu.ifi.dbs.elki.index.tree.spatial.SpatialEntry)1 DeLiCluDirectoryEntry (de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.deliclu.DeLiCluDirectoryEntry)1 DeLiCluNode (de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.deliclu.DeLiCluNode)1 DeLiCluTreeIndex (de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.deliclu.DeLiCluTreeIndex)1 FiniteProgress (de.lmu.ifi.dbs.elki.logging.progress.FiniteProgress)1 AbortException (de.lmu.ifi.dbs.elki.utilities.exceptions.AbortException)1 MissingPrerequisitesException (de.lmu.ifi.dbs.elki.utilities.exceptions.MissingPrerequisitesException)1 IntSet (it.unimi.dsi.fastutil.ints.IntSet)1 ArrayList (java.util.ArrayList)1