diff options
Diffstat (limited to 'src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/util/TopologicalSplitter.java')
-rw-r--r-- | src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/util/TopologicalSplitter.java | 270 |
1 files changed, 0 insertions, 270 deletions
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/util/TopologicalSplitter.java b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/util/TopologicalSplitter.java deleted file mode 100644 index 011e56ab..00000000 --- a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/util/TopologicalSplitter.java +++ /dev/null @@ -1,270 +0,0 @@ -package de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.util; - -/* - This file is part of ELKI: - Environment for Developing KDD-Applications Supported by Index-Structures - - Copyright (C) 2011 - 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 <http://www.gnu.org/licenses/>. - */ - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -import de.lmu.ifi.dbs.elki.data.HyperBoundingBox; -import de.lmu.ifi.dbs.elki.data.spatial.SpatialComparable; -import de.lmu.ifi.dbs.elki.data.spatial.SpatialUtil; -import de.lmu.ifi.dbs.elki.index.tree.spatial.SpatialEntry; -import de.lmu.ifi.dbs.elki.utilities.documentation.Reference; -import de.lmu.ifi.dbs.elki.utilities.pairs.Pair; - -/** - * Encapsulates the required parameters for a topological split of a R*-Tree. - * - * @author Elke Achtert - * - * @apiviz.has Split - * @apiviz.uses SpatialComparator - */ -@Reference(authors = "N. Beckmann, H.-P. Kriegel, R. Schneider, B. Seeger", title = "The R*-tree: an efficient and robust access method for points and rectangles", booktitle = "Proceedings of the 1990 ACM SIGMOD International Conference on Management of Data, Atlantic City, NJ, May 23-25, 1990", url = "http://dx.doi.org/10.1145/93597.98741") -public class TopologicalSplitter implements SplitStrategy<SpatialEntry> { - /** - * constructor. - */ - public TopologicalSplitter() { - // Nothing to do. - } - - @Override - public <E extends SpatialEntry> Pair<List<E>, List<E>> split(List<E> entries, int minEntries) { - Split<E> split = new Split<E>(); - split.chooseSplitAxis(entries, minEntries); - split.chooseSplitPoint(minEntries); - int splitpoint = split.getSplitPoint(); - List<E> sorted = split.getBestSorting(); - - return new Pair<List<E>, List<E>>(sorted.subList(0, splitpoint), sorted.subList(splitpoint, sorted.size())); - } - - /** - * Internal data for an actual split. - * - * @author Erich Schubert - * - * @param <E> Actual entry type - */ - private class Split<E extends SpatialEntry> { - /** - * The split axis. - */ - int splitAxis = 0; - - /** - * The index of the split point. - */ - int splitPoint = -1; - - /** - * Indicates whether the sorting according to maximal or to minimal value - * has been used for choosing the split axis and split point. - */ - int bestSorting; - - /** - * The entries sorted according to their max values of their MBRs. - */ - List<E> maxSorting; - - /** - * The entries sorted according to their min values of their MBRs. - */ - List<E> minSorting; - - /** - * Constructor. - */ - public Split() { - // Initialized by calling chooseSplitAxis. - } - - /** - * Chooses a split axis. - * - * @param entries the entries to be split - * @param minEntries number of minimum entries in the node to be split - */ - void chooseSplitAxis(List<E> entries, int minEntries) { - int dim = entries.get(0).getDimensionality(); - - maxSorting = new ArrayList<E>(entries); - minSorting = new ArrayList<E>(entries); - - // best value for the surface - double minSurface = Double.MAX_VALUE; - // comparator used by sort method - - for(int i = 1; i <= dim; i++) { - double sumOfAllMargins = 0; - // sort the entries according to their minimal and according to their - // maximal value - final SpatialComparator compMin = new SpatialComparator(i, SpatialComparator.MIN); - Collections.sort(minSorting, compMin); - final SpatialComparator compMax = new SpatialComparator(i, SpatialComparator.MAX); - Collections.sort(maxSorting, compMax); - - SpatialComparable mbr_min_left = minSorting.get(0); - SpatialComparable mbr_min_right = minSorting.get(minSorting.size() - 1); - SpatialComparable mbr_max_left = maxSorting.get(0); - SpatialComparable mbr_max_right = maxSorting.get(maxSorting.size() - 1); - - for(int k = 1; k < entries.size() - minEntries; k++) { - mbr_min_left = SpatialUtil.union(mbr_min_left, minSorting.get(k)); - mbr_min_right = SpatialUtil.union(mbr_min_right, minSorting.get(minSorting.size() - 1 - k)); - mbr_max_left = SpatialUtil.union(mbr_max_left, maxSorting.get(k)); - mbr_max_right = SpatialUtil.union(mbr_max_right, maxSorting.get(maxSorting.size() - 1 - k)); - if(k >= minEntries - 1) { - // Yes, build the sum. This value is solely used for finding the - // split axis! - // Compare with the original paper, "sum of all margin-values". - // Note that mbr_min_left and mbr_max_left do not add up to a - // complete split, but when the sum is complete, it will also - // include their proper counterpart. - sumOfAllMargins += SpatialUtil.perimeter(mbr_min_left) + SpatialUtil.perimeter(mbr_min_right) + SpatialUtil.perimeter(mbr_max_left) + SpatialUtil.perimeter(mbr_max_right); - } - } - if(sumOfAllMargins < minSurface) { - splitAxis = i; - minSurface = sumOfAllMargins; - } - } - } - - /** - * Chooses a split axis. - * - * @param minEntries number of minimum entries in the node to be split - */ - void chooseSplitPoint(int minEntries) { - // numEntries - int numEntries = maxSorting.size(); - // sort upper and lower in the right dimension - final SpatialComparator compMin = new SpatialComparator(splitAxis, SpatialComparator.MIN); - Collections.sort(minSorting, compMin); - final SpatialComparator compMax = new SpatialComparator(splitAxis, SpatialComparator.MAX); - Collections.sort(maxSorting, compMax); - - // the split point (first set to minimum entries in the node) - splitPoint = minEntries; - // best value for the overlap - double minOverlap = Double.MAX_VALUE; - // the volume of mbr1 and mbr2 - double volume = 0.0; - // indicates whether the sorting according to maximal or to minimal value - // is - // best for the split axis - bestSorting = -1; - - for(int i = 0; i <= numEntries - 2 * minEntries; i++) { - // test the sorting with respect to the minimal values - HyperBoundingBox mbr1 = mbr(minSorting, 0, minEntries + i); - HyperBoundingBox mbr2 = mbr(minSorting, minEntries + i, numEntries); - double currentOverlap = SpatialUtil.relativeOverlap(mbr1, mbr2); - double vol1 = SpatialUtil.volume(mbr1); - double vol2 = SpatialUtil.volume(mbr2); - if(currentOverlap < minOverlap || (currentOverlap == minOverlap && (vol1 + vol2) < volume)) { - minOverlap = currentOverlap; - splitPoint = minEntries + i; - bestSorting = SpatialComparator.MIN; - volume = vol1 + vol2; - } - // test the sorting with respect to the maximal values - mbr1 = mbr(maxSorting, 0, minEntries + i); - mbr2 = mbr(maxSorting, minEntries + i, numEntries); - currentOverlap = SpatialUtil.relativeOverlap(mbr1, mbr2); - vol1 = SpatialUtil.volume(mbr1); - vol2 = SpatialUtil.volume(mbr2); - if(currentOverlap < minOverlap || (currentOverlap == minOverlap && (vol1 + vol2) < volume)) { - minOverlap = currentOverlap; - splitPoint = minEntries + i; - bestSorting = SpatialComparator.MAX; - volume = vol1 + vol2; - } - } - } - - /** - * Computes and returns the mbr of the specified nodes, only the nodes - * between from and to index are considered. - * - * @param entries the array of nodes - * @param from the start index - * @param to the end index - * @return the mbr of the specified nodes - */ - private HyperBoundingBox mbr(final List<E> entries, final int from, final int to) { - double[] min = new double[entries.get(from).getDimensionality()]; - double[] max = new double[entries.get(from).getDimensionality()]; - - for(int d = 1; d <= min.length; d++) { - min[d - 1] = entries.get(from).getMin(d); - max[d - 1] = entries.get(from).getMax(d); - } - - for(int i = from + 1; i < to; i++) { - SpatialComparable currMBR = entries.get(i); - for(int d = 1; d <= min.length; d++) { - if(min[d - 1] > currMBR.getMin(d)) { - min[d - 1] = currMBR.getMin(d); - } - if(max[d - 1] < currMBR.getMax(d)) { - max[d - 1] = currMBR.getMax(d); - } - } - } - return new HyperBoundingBox(min, max); - } - - /** - * Returns the split point. - * - * @return the split point - */ - public int getSplitPoint() { - return splitPoint; - } - - /** - * Returns whether the sorting according to maximal or to minimal value has - * been used for choosing the split axis and split point. - * - * @return The sorting to use - */ - public List<E> getBestSorting() { - if(bestSorting == SpatialComparator.MIN) { - return minSorting; - } - if(bestSorting == SpatialComparator.MAX) { - return maxSorting; - } - else { - throw new IllegalStateException("split.bestSort is undefined: " + bestSorting); - } - } - } -} |