summaryrefslogtreecommitdiff
path: root/src/de/lmu/ifi/dbs/elki/index
diff options
context:
space:
mode:
Diffstat (limited to 'src/de/lmu/ifi/dbs/elki/index')
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/AbstractIndex.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/AbstractRefiningIndex.java192
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/Index.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/IndexFactory.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/KNNIndex.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/RKNNIndex.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/RangeIndex.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/package-info.java34
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/preprocessed/AbstractPreprocessorIndex.java4
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/preprocessed/LocalProjectionIndex.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/preprocessed/knn/AbstractMaterializeKNNPreprocessor.java68
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/preprocessed/knn/KNNChangeEvent.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/preprocessed/knn/KNNJoinMaterializeKNNPreprocessor.java128
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/preprocessed/knn/KNNListener.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/preprocessed/knn/MaterializeKNNAndRKNNPreprocessor.java37
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/preprocessed/knn/MaterializeKNNPreprocessor.java87
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/preprocessed/knn/MetricalIndexApproximationMaterializeKNNPreprocessor.java13
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/preprocessed/knn/PartitionApproximationMaterializeKNNPreprocessor.java14
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/preprocessed/knn/RandomSampleKNNPreprocessor.java237
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/preprocessed/knn/SpatialApproximationMaterializeKNNPreprocessor.java12
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/preprocessed/knn/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/preprocessed/localpca/AbstractFilteredPCAIndex.java10
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/preprocessed/localpca/FilteredLocalPCAIndex.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/preprocessed/localpca/KNNQueryFilteredPCAIndex.java8
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/preprocessed/localpca/RangeQueryFilteredPCAIndex.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/preprocessed/localpca/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/preprocessed/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/preprocessed/preference/AbstractPreferenceVectorIndex.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/preprocessed/preference/DiSHPreferenceVectorIndex.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/preprocessed/preference/HiSCPreferenceVectorIndex.java19
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/preprocessed/preference/PreferenceVectorIndex.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/preprocessed/preference/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/preprocessed/snn/SharedNearestNeighborIndex.java6
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/preprocessed/snn/SharedNearestNeighborPreprocessor.java26
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/preprocessed/snn/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/preprocessed/subspaceproj/AbstractSubspaceProjectionIndex.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/preprocessed/subspaceproj/FourCSubspaceIndex.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/preprocessed/subspaceproj/PreDeConSubspaceIndex.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/preprocessed/subspaceproj/SubspaceProjectionIndex.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/preprocessed/subspaceproj/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/AbstractDirectoryEntry.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/AbstractLeafEntry.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/AbstractNode.java89
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/BreadthFirstEnumeration.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/DirectoryEntry.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/DistanceEntry.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/Entry.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/IndexTree.java10
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/IndexTreePath.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/LeafEntry.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/Node.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/TreeIndexFactory.java6
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/TreeIndexHeader.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/TreeIndexPathComponent.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/metrical/MetricalIndexTree.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/AbstractMTree.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/AbstractMTreeFactory.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/AbstractMTreeNode.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/MTreeDirectoryEntry.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/MTreeEntry.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/MTreeLeafEntry.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/AbstractMkTree.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/AbstractMkTreeUnified.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/AbstractMkTreeUnifiedFactory.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/MkTreeHeader.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkapp/MkAppDirectoryEntry.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkapp/MkAppEntry.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkapp/MkAppLeafEntry.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkapp/MkAppTree.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkapp/MkAppTreeFactory.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkapp/MkAppTreeIndex.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkapp/MkAppTreeNode.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkapp/PolynomialApproximation.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkapp/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkcop/ApproximationLine.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkcop/ConvexHull.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkcop/MkCoPDirectoryEntry.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkcop/MkCoPEntry.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkcop/MkCoPLeafEntry.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkcop/MkCoPTree.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkcop/MkCoPTreeIndex.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkcop/MkCoPTreeNode.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkcop/MkCopTreeFactory.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkcop/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkmax/MkMaxDirectoryEntry.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkmax/MkMaxEntry.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkmax/MkMaxLeafEntry.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkmax/MkMaxTree.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkmax/MkMaxTreeFactory.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkmax/MkMaxTreeIndex.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkmax/MkMaxTreeNode.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkmax/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mktab/MkTabDirectoryEntry.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mktab/MkTabEntry.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mktab/MkTabLeafEntry.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mktab/MkTabTree.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mktab/MkTabTreeFactory.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mktab/MkTabTreeIndex.java10
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mktab/MkTabTreeNode.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mktab/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mtree/MTree.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mtree/MTreeFactory.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mtree/MTreeIndex.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mtree/MTreeNode.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mtree/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/query/MetricalIndexKNNQuery.java24
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/query/MetricalIndexRangeQuery.java18
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/query/MkTreeRKNNQuery.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/query/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/split/Assignments.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/split/MLBDistSplit.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/split/MRadSplit.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/split/MTreeSplit.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/split/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/metrical/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/query/DoubleDistanceSearchCandidate.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/query/GenericDistanceSearchCandidate.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/query/GenericMTreeDistanceSearchCandidate.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/query/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/spatial/SpatialDirectoryEntry.java34
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/spatial/SpatialEntry.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/spatial/SpatialIndexTree.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/spatial/SpatialNode.java7
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/spatial/SpatialPair.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/spatial/SpatialPointLeafEntry.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/spatial/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/AbstractRStarTree.java300
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/AbstractRStarTreeFactory.java93
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/AbstractRStarTreeNode.java105
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/NonFlatRStarTree.java53
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/bulk/ZCurveBulkSplit.java184
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/deliclu/DeLiCluDirectoryEntry.java6
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/deliclu/DeLiCluEntry.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/deliclu/DeLiCluLeafEntry.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/deliclu/DeLiCluNode.java7
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/deliclu/DeLiCluTree.java10
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/deliclu/DeLiCluTreeFactory.java25
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/deliclu/DeLiCluTreeIndex.java10
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/deliclu/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/query/DoubleDistanceRStarTreeKNNQuery.java89
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/query/DoubleDistanceRStarTreeRangeQuery.java13
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/query/GenericRStarTreeKNNQuery.java85
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/query/GenericRStarTreeRangeQuery.java15
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/query/RStarTreeUtil.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/query/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/rstar/RStarTree.java10
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/rstar/RStarTreeFactory.java25
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/rstar/RStarTreeIndex.java10
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/rstar/RStarTreeNode.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/rstar/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/bulk/AbstractBulkSplit.java (renamed from src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/bulk/AbstractBulkSplit.java)37
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/bulk/BulkSplit.java (renamed from src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/bulk/BulkSplit.java)7
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/bulk/FileOrderBulkSplit.java67
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/bulk/MaxExtensionBulkSplit.java (renamed from src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/bulk/MaxExtensionBulkSplit.java)24
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/bulk/OneDimSortBulkSplit.java86
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/bulk/SortTileRecursiveBulkSplit.java115
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/bulk/SpatialSortBulkSplit.java107
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/bulk/package-info.java (renamed from src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/bulk/package-info.java)4
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/insert/ApproximativeLeastOverlapInsertionStrategy.java168
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/insert/CombinedInsertionStrategy.java127
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/insert/InsertionStrategy.java (renamed from src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/util/InsertionStrategy.java)29
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/insert/LeastEnlargementInsertionStrategy.java89
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/insert/LeastEnlargementWithAreaInsertionStrategy.java102
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/insert/LeastOverlapInsertionStrategy.java120
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/insert/package-info.java26
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/overflow/LimitedReinsertOverflowTreatment.java135
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/overflow/OverflowTreatment.java53
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/overflow/SplitOnlyOverflowTreatment.java73
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/overflow/package-info.java26
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/package-info.java26
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/reinsert/AbstractPartialReinsert.java105
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/reinsert/CloseReinsert.java88
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/reinsert/FarReinsert.java88
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/reinsert/ReinsertStrategy.java44
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/reinsert/package-info.java26
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/split/AngTanLinearSplit.java193
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/split/GreeneSplit.java158
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/split/RTreeLinearSplit.java219
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/split/RTreeQuadraticSplit.java183
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/split/SplitStrategy.java (renamed from src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/util/SplitStrategy.java)22
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/split/TopologicalSplitter.java309
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/split/package-info.java26
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/util/ApproximateLeastOverlapInsertionStrategy.java150
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/util/Enlargement.java119
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/util/LeastOverlapInsertionStrategy.java87
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/util/NodeArrayAdapter.java58
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/util/SpatialComparator.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/util/TopologicalSplitter.java270
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/util/package-info.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/vafile/VAFile.java518
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/vafile/VALPNormDistance.java169
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/vafile/VectorApproximation.java103
-rw-r--r--src/de/lmu/ifi/dbs/elki/index/vafile/package-info.java27
197 files changed, 5163 insertions, 1583 deletions
diff --git a/src/de/lmu/ifi/dbs/elki/index/AbstractIndex.java b/src/de/lmu/ifi/dbs/elki/index/AbstractIndex.java
index 061d7893..30966fd1 100644
--- a/src/de/lmu/ifi/dbs/elki/index/AbstractIndex.java
+++ b/src/de/lmu/ifi/dbs/elki/index/AbstractIndex.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2011
+ Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
diff --git a/src/de/lmu/ifi/dbs/elki/index/AbstractRefiningIndex.java b/src/de/lmu/ifi/dbs/elki/index/AbstractRefiningIndex.java
new file mode 100644
index 00000000..30abb4a4
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/index/AbstractRefiningIndex.java
@@ -0,0 +1,192 @@
+package de.lmu.ifi.dbs.elki.index;
+
+import java.util.List;
+import java.util.Map;
+
+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.DBIDs;
+import de.lmu.ifi.dbs.elki.database.query.DistanceResultPair;
+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.database.query.knn.KNNQuery;
+import de.lmu.ifi.dbs.elki.database.query.knn.KNNResult;
+import de.lmu.ifi.dbs.elki.database.query.range.AbstractDistanceRangeQuery;
+import de.lmu.ifi.dbs.elki.database.relation.Relation;
+import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
+import de.lmu.ifi.dbs.elki.persistent.PageFileStatistics;
+import de.lmu.ifi.dbs.elki.utilities.datastructures.heap.KNNHeap;
+
+/**
+ * Abstract base class for Filter-refinement indexes.
+ *
+ * The number of refinements will be counted as individual page accesses.
+ *
+ * @author Erich Schubert
+ *
+ * @param <O> Object type
+ */
+public abstract class AbstractRefiningIndex<O> extends AbstractIndex<O> implements PageFileStatistics {
+ /**
+ * Refinement counter.
+ */
+ private int refinements;
+
+ /**
+ * Constructor.
+ *
+ * @param relation Relation indexed
+ */
+ public AbstractRefiningIndex(Relation<O> relation) {
+ super(relation);
+ }
+
+ /**
+ * Initialize the index.
+ *
+ * @param relation Relation to index
+ * @param ids database ids
+ */
+ abstract protected void initialize(Relation<O> relation, DBIDs ids);
+
+ /**
+ * Refine a given object (and count the refinement!)
+ *
+ * @param id Object id
+ * @return refined object
+ */
+ protected O refine(DBID id) {
+ refinements++;
+ return relation.get(id);
+ }
+
+ @Override
+ public PageFileStatistics getPageFileStatistics() {
+ return this;
+ }
+
+ @Override
+ public long getReadOperations() {
+ return refinements;
+ }
+
+ @Override
+ public long getWriteOperations() {
+ return 0;
+ }
+
+ @Override
+ public void resetPageAccess() {
+ refinements = 0;
+ }
+
+ @Override
+ public PageFileStatistics getInnerStatistics() {
+ return null;
+ }
+
+ @Override
+ public void insertAll(DBIDs ids) {
+ initialize(relation, ids);
+ }
+
+ /**
+ * Range query for this index.
+ *
+ * @author Erich Schubert
+ */
+ public abstract class AbstractRangeQuery<D extends Distance<D>> extends AbstractDistanceRangeQuery<O, D> {
+ /**
+ * Hold the distance function to be used.
+ */
+ private DistanceQuery<O, D> distanceQuery;
+
+ /**
+ * Constructor.
+ *
+ * @param distanceQuery Distance query object
+ */
+ public AbstractRangeQuery(DistanceQuery<O, D> distanceQuery) {
+ super(distanceQuery);
+ this.distanceQuery = distanceQuery;
+ }
+
+ @Override
+ public List<DistanceResultPair<D>> getRangeForDBID(DBID id, D range) {
+ return getRangeForObject(relation.get(id), range);
+ }
+
+ /**
+ * Refinement distance computation.
+ *
+ * @param id Candidate ID
+ * @param q Query object
+ * @return Distance
+ */
+ protected D refine(DBID id, O q) {
+ AbstractRefiningIndex.this.refinements++;
+ return distanceQuery.distance(q, id);
+ }
+
+ /**
+ * Count extra refinements.
+ *
+ * @param c Refinements
+ */
+ protected void incRefinements(int c) {
+ AbstractRefiningIndex.this.refinements += c;
+ }
+ }
+
+ /**
+ * KNN query for this index.
+ *
+ * @author Erich Schubert
+ */
+ abstract public class AbstractKNNQuery<D extends Distance<D>> extends AbstractDistanceKNNQuery<O, D> implements KNNQuery<O, D> {
+ /**
+ * Constructor.
+ *
+ * @param distanceQuery Distance query object
+ */
+ public AbstractKNNQuery(DistanceQuery<O, D> distanceQuery) {
+ super(distanceQuery);
+ }
+
+ @Override
+ public List<KNNResult<D>> getKNNForBulkDBIDs(ArrayDBIDs ids, int k) {
+ throw new UnsupportedOperationException("Not yet implemented.");
+ }
+
+ @Override
+ public void getKNNForBulkHeaps(Map<DBID, KNNHeap<D>> heaps) {
+ throw new UnsupportedOperationException("Not yet implemented.");
+ }
+
+ @Override
+ public KNNResult<D> getKNNForDBID(DBID id, int k) {
+ return getKNNForObject(relation.get(id), k);
+ }
+
+ /**
+ * Refinement distance computation.
+ *
+ * @param id Candidate ID
+ * @param q Query object
+ * @return Distance
+ */
+ protected D refine(DBID id, O q) {
+ AbstractRefiningIndex.this.refinements++;
+ return distanceQuery.distance(q, id);
+ }
+
+ /**
+ * Count extra refinements.
+ *
+ * @param c Refinements
+ */
+ protected void incRefinements(int c) {
+ AbstractRefiningIndex.this.refinements += c;
+ }
+ }
+} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/index/Index.java b/src/de/lmu/ifi/dbs/elki/index/Index.java
index 2021fbbb..9e77073c 100644
--- a/src/de/lmu/ifi/dbs/elki/index/Index.java
+++ b/src/de/lmu/ifi/dbs/elki/index/Index.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2011
+ Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
diff --git a/src/de/lmu/ifi/dbs/elki/index/IndexFactory.java b/src/de/lmu/ifi/dbs/elki/index/IndexFactory.java
index b1eb649b..ac34c53f 100644
--- a/src/de/lmu/ifi/dbs/elki/index/IndexFactory.java
+++ b/src/de/lmu/ifi/dbs/elki/index/IndexFactory.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2011
+ Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
diff --git a/src/de/lmu/ifi/dbs/elki/index/KNNIndex.java b/src/de/lmu/ifi/dbs/elki/index/KNNIndex.java
index 7fcb7376..83a37f88 100644
--- a/src/de/lmu/ifi/dbs/elki/index/KNNIndex.java
+++ b/src/de/lmu/ifi/dbs/elki/index/KNNIndex.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2011
+ Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
diff --git a/src/de/lmu/ifi/dbs/elki/index/RKNNIndex.java b/src/de/lmu/ifi/dbs/elki/index/RKNNIndex.java
index f29fbe89..6c990cd8 100644
--- a/src/de/lmu/ifi/dbs/elki/index/RKNNIndex.java
+++ b/src/de/lmu/ifi/dbs/elki/index/RKNNIndex.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2011
+ Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
diff --git a/src/de/lmu/ifi/dbs/elki/index/RangeIndex.java b/src/de/lmu/ifi/dbs/elki/index/RangeIndex.java
index 1bcfad12..5d64a8fa 100644
--- a/src/de/lmu/ifi/dbs/elki/index/RangeIndex.java
+++ b/src/de/lmu/ifi/dbs/elki/index/RangeIndex.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2011
+ Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
diff --git a/src/de/lmu/ifi/dbs/elki/index/package-info.java b/src/de/lmu/ifi/dbs/elki/index/package-info.java
index 3f9c7cce..ca7dbe28 100644
--- a/src/de/lmu/ifi/dbs/elki/index/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/index/package-info.java
@@ -2,25 +2,25 @@
* <p>Index structure implementations</p>
*/
/*
-This file is part of ELKI:
-Environment for Developing KDD-Applications Supported by Index-Structures
+ 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
+ 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 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.
+ 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/>.
-*/
+ 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/>.
+ */
package de.lmu.ifi.dbs.elki.index; \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/index/preprocessed/AbstractPreprocessorIndex.java b/src/de/lmu/ifi/dbs/elki/index/preprocessed/AbstractPreprocessorIndex.java
index 4b6fbe3a..0160480f 100644
--- a/src/de/lmu/ifi/dbs/elki/index/preprocessed/AbstractPreprocessorIndex.java
+++ b/src/de/lmu/ifi/dbs/elki/index/preprocessed/AbstractPreprocessorIndex.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.preprocessed;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2011
+ Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
@@ -43,7 +43,7 @@ public abstract class AbstractPreprocessorIndex<O, R> extends AbstractIndex<O> {
/**
* The data store
*/
- protected WritableDataStore<R> storage;
+ protected WritableDataStore<R> storage = null;
/**
* Constructor.
diff --git a/src/de/lmu/ifi/dbs/elki/index/preprocessed/LocalProjectionIndex.java b/src/de/lmu/ifi/dbs/elki/index/preprocessed/LocalProjectionIndex.java
index 8b4272d5..cef2fbdc 100644
--- a/src/de/lmu/ifi/dbs/elki/index/preprocessed/LocalProjectionIndex.java
+++ b/src/de/lmu/ifi/dbs/elki/index/preprocessed/LocalProjectionIndex.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.preprocessed;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2011
+ Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
diff --git a/src/de/lmu/ifi/dbs/elki/index/preprocessed/knn/AbstractMaterializeKNNPreprocessor.java b/src/de/lmu/ifi/dbs/elki/index/preprocessed/knn/AbstractMaterializeKNNPreprocessor.java
index 0579262b..b9b72d87 100644
--- a/src/de/lmu/ifi/dbs/elki/index/preprocessed/knn/AbstractMaterializeKNNPreprocessor.java
+++ b/src/de/lmu/ifi/dbs/elki/index/preprocessed/knn/AbstractMaterializeKNNPreprocessor.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.preprocessed.knn;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2011
+ Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
@@ -23,14 +23,15 @@ package de.lmu.ifi.dbs.elki.index.preprocessed.knn;
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-import java.util.List;
-
-import javax.swing.event.EventListenerList;
-
import de.lmu.ifi.dbs.elki.data.type.TypeInformation;
-import de.lmu.ifi.dbs.elki.database.query.DistanceResultPair;
+import de.lmu.ifi.dbs.elki.database.datastore.DataStoreFactory;
+import de.lmu.ifi.dbs.elki.database.datastore.DataStoreUtil;
+import de.lmu.ifi.dbs.elki.database.datastore.WritableDataStore;
+import de.lmu.ifi.dbs.elki.database.ids.DBID;
+import de.lmu.ifi.dbs.elki.database.ids.DBIDs;
import de.lmu.ifi.dbs.elki.database.query.distance.DistanceQuery;
import de.lmu.ifi.dbs.elki.database.query.knn.KNNQuery;
+import de.lmu.ifi.dbs.elki.database.query.knn.KNNResult;
import de.lmu.ifi.dbs.elki.database.query.knn.PreprocessorKNNQuery;
import de.lmu.ifi.dbs.elki.database.relation.Relation;
import de.lmu.ifi.dbs.elki.distance.distancefunction.DistanceFunction;
@@ -54,7 +55,7 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ObjectParameter;
* @param <O> Object type
* @param <D> Distance type
*/
-public abstract class AbstractMaterializeKNNPreprocessor<O, D extends Distance<D>> extends AbstractPreprocessorIndex<O, List<DistanceResultPair<D>>> implements KNNIndex<O> {
+public abstract class AbstractMaterializeKNNPreprocessor<O, D extends Distance<D>, T extends KNNResult<D>> extends AbstractPreprocessorIndex<O, T> implements KNNIndex<O> {
/**
* The query k value.
*/
@@ -71,11 +72,6 @@ public abstract class AbstractMaterializeKNNPreprocessor<O, D extends Distance<D
protected final DistanceQuery<O, D> distanceQuery;
/**
- * Holds the listener.
- */
- protected final EventListenerList listenerList = new EventListenerList();
-
- /**
* Constructor.
*
* @param relation Relation
@@ -121,6 +117,42 @@ public abstract class AbstractMaterializeKNNPreprocessor<O, D extends Distance<D
*/
protected abstract void preprocess();
+ /**
+ * Get the k nearest neighbors.
+ *
+ * @param objid Object ID
+ * @return Neighbors
+ */
+ public KNNResult<D> get(DBID objid) {
+ if(storage == null) {
+ if(getLogger().isDebugging()) {
+ getLogger().debug("Running kNN preprocessor: " + this.getClass());
+ }
+ preprocess();
+ }
+ return storage.get(objid);
+ }
+
+ /**
+ * Create the default storage.
+ */
+ void createStorage() {
+ WritableDataStore<T> s = DataStoreUtil.makeStorage(relation.getDBIDs(), DataStoreFactory.HINT_HOT, KNNResult.class);
+ storage = s;
+ }
+
+ @Override
+ public void insertAll(DBIDs ids) {
+ if(storage == null) {
+ if(ids.size() > 0) {
+ preprocess();
+ }
+ }
+ else {
+ throw new UnsupportedOperationException("Preprocessor already ran.");
+ }
+ }
+
@SuppressWarnings("unchecked")
@Override
public <S extends Distance<S>> KNNQuery<O, S> getKNNQuery(DistanceQuery<O, S> distanceQuery, Object... hints) {
@@ -136,7 +168,9 @@ public abstract class AbstractMaterializeKNNPreprocessor<O, D extends Distance<D
break;
}
}
- return new PreprocessorKNNQuery<O, S>(relation, (MaterializeKNNPreprocessor<O, S>) this);
+ // To make compilers happy:
+ AbstractMaterializeKNNPreprocessor<?, ?, ?> tmp = this;
+ return new PreprocessorKNNQuery<O, S, KNNResult<S>>(relation, (AbstractMaterializeKNNPreprocessor<O, S, KNNResult<S>>) tmp);
}
/**
@@ -151,7 +185,7 @@ public abstract class AbstractMaterializeKNNPreprocessor<O, D extends Distance<D
* @param <O> The object type
* @param <D> The distance type
*/
- public static abstract class Factory<O, D extends Distance<D>> implements IndexFactory<O, KNNIndex<O>> {
+ public static abstract class Factory<O, D extends Distance<D>, T extends KNNResult<D>> implements IndexFactory<O, KNNIndex<O>> {
/**
* Parameter to specify the number of nearest neighbors of an object to be
* materialized. must be an integer greater than 1.
@@ -197,7 +231,7 @@ public abstract class AbstractMaterializeKNNPreprocessor<O, D extends Distance<D
}
@Override
- abstract public AbstractMaterializeKNNPreprocessor<O, D> instantiate(Relation<O> relation);
+ abstract public AbstractMaterializeKNNPreprocessor<O, D, T> instantiate(Relation<O> relation);
/**
* Get the distance function.
@@ -217,7 +251,7 @@ public abstract class AbstractMaterializeKNNPreprocessor<O, D extends Distance<D
public D getDistanceFactory() {
return distanceFunction.getDistanceFactory();
}
-
+
@Override
public TypeInformation getInputTypeRestriction() {
return distanceFunction.getInputTypeRestriction();
@@ -258,7 +292,7 @@ public abstract class AbstractMaterializeKNNPreprocessor<O, D extends Distance<D
}
@Override
- abstract protected Factory<O, D> makeInstance();
+ abstract protected Factory<O, D, ?> makeInstance();
}
}
} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/index/preprocessed/knn/KNNChangeEvent.java b/src/de/lmu/ifi/dbs/elki/index/preprocessed/knn/KNNChangeEvent.java
index ef26d62b..6c677fda 100644
--- a/src/de/lmu/ifi/dbs/elki/index/preprocessed/knn/KNNChangeEvent.java
+++ b/src/de/lmu/ifi/dbs/elki/index/preprocessed/knn/KNNChangeEvent.java
@@ -3,7 +3,7 @@ package de.lmu.ifi.dbs.elki.index.preprocessed.knn;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
-Copyright (C) 2011
+Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
diff --git a/src/de/lmu/ifi/dbs/elki/index/preprocessed/knn/KNNJoinMaterializeKNNPreprocessor.java b/src/de/lmu/ifi/dbs/elki/index/preprocessed/knn/KNNJoinMaterializeKNNPreprocessor.java
new file mode 100644
index 00000000..b7c3f0ac
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/index/preprocessed/knn/KNNJoinMaterializeKNNPreprocessor.java
@@ -0,0 +1,128 @@
+package de.lmu.ifi.dbs.elki.index.preprocessed.knn;
+
+import de.lmu.ifi.dbs.elki.algorithm.KNNJoin;
+import de.lmu.ifi.dbs.elki.data.NumberVector;
+import de.lmu.ifi.dbs.elki.database.relation.Relation;
+import de.lmu.ifi.dbs.elki.distance.distancefunction.DistanceFunction;
+import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
+import de.lmu.ifi.dbs.elki.index.tree.spatial.SpatialEntry;
+import de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.rstar.RStarTreeNode;
+import de.lmu.ifi.dbs.elki.logging.Logging;
+import de.lmu.ifi.dbs.elki.utilities.datastructures.heap.KNNList;
+
+/*
+ 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 <http://www.gnu.org/licenses/>.
+ */
+
+/**
+ * Class to materialize the kNN using a spatial join on an R-tree.
+ *
+ * @author Erich Schubert
+ *
+ * @param <V> vector type
+ * @param <D> distance type
+ */
+public class KNNJoinMaterializeKNNPreprocessor<V extends NumberVector<V, ?>, D extends Distance<D>> extends AbstractMaterializeKNNPreprocessor<V, D, KNNList<D>> {
+ /**
+ * Logging class.
+ */
+ private static final Logging logger = Logging.getLogger(KNNJoinMaterializeKNNPreprocessor.class);
+
+ /**
+ * Constructor.
+ *
+ * @param relation Relation to index
+ * @param distanceFunction Distance function
+ * @param k k
+ */
+ public KNNJoinMaterializeKNNPreprocessor(Relation<V> relation, DistanceFunction<? super V, D> distanceFunction, int k) {
+ super(relation, distanceFunction, k);
+ }
+
+ @Override
+ protected void preprocess() {
+ // Run KNNJoin
+ KNNJoin<V, D, ?, ?> knnjoin = new KNNJoin<V, D, RStarTreeNode, SpatialEntry>(distanceFunction, k);
+ storage = knnjoin.run(relation.getDatabase(), relation);
+ }
+
+ @Override
+ protected Logging getLogger() {
+ return logger;
+ }
+
+ @Override
+ public String getLongName() {
+ return "knn-join materialized neighbors";
+ }
+
+ @Override
+ public String getShortName() {
+ return "knn-join";
+ }
+
+ /**
+ * The parameterizable factory.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.landmark
+ * @apiviz.stereotype factory
+ * @apiviz.uses AbstractMaterializeKNNPreprocessor oneway - - «create»
+ *
+ * @param <O> The object type
+ * @param <D> The distance type
+ */
+ public static class Factory<O extends NumberVector<O, ?>, D extends Distance<D>> extends AbstractMaterializeKNNPreprocessor.Factory<O, D, KNNList<D>> {
+ /**
+ * Constructor.
+ *
+ * @param k K
+ * @param distanceFunction distance function
+ */
+ public Factory(int k, DistanceFunction<? super O, D> distanceFunction) {
+ super(k, distanceFunction);
+ }
+
+ @Override
+ public KNNJoinMaterializeKNNPreprocessor<O, D> instantiate(Relation<O> relation) {
+ return new KNNJoinMaterializeKNNPreprocessor<O, D>(relation, distanceFunction, k);
+ }
+
+ /**
+ * Parameterization class
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ *
+ * @param <O> Object type
+ * @param <D> Distance type
+ */
+ public static class Parameterizer<O extends NumberVector<O, ?>, D extends Distance<D>> extends AbstractMaterializeKNNPreprocessor.Factory.Parameterizer<O, D> {
+ @Override
+ protected KNNJoinMaterializeKNNPreprocessor.Factory<O, D> makeInstance() {
+ return new KNNJoinMaterializeKNNPreprocessor.Factory<O, D>(k, distanceFunction);
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/index/preprocessed/knn/KNNListener.java b/src/de/lmu/ifi/dbs/elki/index/preprocessed/knn/KNNListener.java
index c4456f83..4a726ad0 100644
--- a/src/de/lmu/ifi/dbs/elki/index/preprocessed/knn/KNNListener.java
+++ b/src/de/lmu/ifi/dbs/elki/index/preprocessed/knn/KNNListener.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.preprocessed.knn;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2011
+ Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
diff --git a/src/de/lmu/ifi/dbs/elki/index/preprocessed/knn/MaterializeKNNAndRKNNPreprocessor.java b/src/de/lmu/ifi/dbs/elki/index/preprocessed/knn/MaterializeKNNAndRKNNPreprocessor.java
index 9abd4a74..1436efe2 100644
--- a/src/de/lmu/ifi/dbs/elki/index/preprocessed/knn/MaterializeKNNAndRKNNPreprocessor.java
+++ b/src/de/lmu/ifi/dbs/elki/index/preprocessed/knn/MaterializeKNNAndRKNNPreprocessor.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.preprocessed.knn;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2011
+ Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
@@ -34,13 +34,15 @@ import de.lmu.ifi.dbs.elki.database.datastore.DataStoreFactory;
import de.lmu.ifi.dbs.elki.database.datastore.DataStoreUtil;
import de.lmu.ifi.dbs.elki.database.datastore.WritableDataStore;
import de.lmu.ifi.dbs.elki.database.ids.ArrayDBIDs;
+import de.lmu.ifi.dbs.elki.database.ids.ArrayModifiableDBIDs;
import de.lmu.ifi.dbs.elki.database.ids.DBID;
import de.lmu.ifi.dbs.elki.database.ids.DBIDUtil;
import de.lmu.ifi.dbs.elki.database.ids.DBIDs;
-import de.lmu.ifi.dbs.elki.database.ids.TreeSetDBIDs;
+import de.lmu.ifi.dbs.elki.database.ids.SetDBIDs;
import de.lmu.ifi.dbs.elki.database.query.DistanceResultPair;
import de.lmu.ifi.dbs.elki.database.query.GenericDistanceResultPair;
import de.lmu.ifi.dbs.elki.database.query.distance.DistanceQuery;
+import de.lmu.ifi.dbs.elki.database.query.knn.KNNResult;
import de.lmu.ifi.dbs.elki.database.query.rknn.PreprocessorRKNNQuery;
import de.lmu.ifi.dbs.elki.database.query.rknn.RKNNQuery;
import de.lmu.ifi.dbs.elki.database.relation.Relation;
@@ -51,6 +53,7 @@ import de.lmu.ifi.dbs.elki.logging.Logging;
import de.lmu.ifi.dbs.elki.logging.progress.FiniteProgress;
import de.lmu.ifi.dbs.elki.logging.progress.StepProgress;
import de.lmu.ifi.dbs.elki.utilities.datastructures.heap.KNNHeap;
+import de.lmu.ifi.dbs.elki.utilities.datastructures.heap.KNNList;
import de.lmu.ifi.dbs.elki.utilities.documentation.Description;
import de.lmu.ifi.dbs.elki.utilities.documentation.Title;
@@ -88,7 +91,7 @@ public class MaterializeKNNAndRKNNPreprocessor<O, D extends Distance<D>> extends
@Override
protected void preprocess() {
- storage = DataStoreUtil.makeStorage(relation.getDBIDs(), DataStoreFactory.HINT_HOT, List.class);
+ createStorage();
materialized_RkNN = DataStoreUtil.makeStorage(relation.getDBIDs(), DataStoreFactory.HINT_HOT, Set.class);
FiniteProgress progress = getLogger().isVerbose() ? new FiniteProgress("Materializing k nearest neighbors and reverse k nearest neighbors (k=" + k + ")", relation.size(), getLogger()) : null;
materializeKNNAndRKNNs(DBIDUtil.ensureArray(relation.getDBIDs()), progress);
@@ -100,7 +103,6 @@ public class MaterializeKNNAndRKNNPreprocessor<O, D extends Distance<D>> extends
* @param ids the IDs of the objects
*/
private void materializeKNNAndRKNNs(ArrayDBIDs ids, FiniteProgress progress) {
-
// add an empty list to each rknn
for(DBID id : ids) {
if(materialized_RkNN.get(id) == null) {
@@ -109,10 +111,10 @@ public class MaterializeKNNAndRKNNPreprocessor<O, D extends Distance<D>> extends
}
// knn query
- List<List<DistanceResultPair<D>>> kNNList = knnQuery.getKNNForBulkDBIDs(ids, k);
+ List<KNNResult<D>> kNNList = knnQuery.getKNNForBulkDBIDs(ids, k);
for(int i = 0; i < ids.size(); i++) {
DBID id = ids.get(i);
- List<DistanceResultPair<D>> kNNs = kNNList.get(i);
+ KNNResult<D> kNNs = kNNList.get(i);
storage.put(id, kNNs);
for(DistanceResultPair<D> kNN : kNNs) {
Set<DistanceResultPair<D>> rknns = materialized_RkNN.get(kNN.getDBID());
@@ -165,13 +167,12 @@ public class MaterializeKNNAndRKNNPreprocessor<O, D extends Distance<D>> extends
* updated
*/
private ArrayDBIDs updateKNNsAndRkNNs(DBIDs ids) {
- ArrayDBIDs rkNN_ids = DBIDUtil.newArray();
+ ArrayModifiableDBIDs rkNN_ids = DBIDUtil.newArray();
DBIDs oldids = DBIDUtil.difference(relation.getDBIDs(), ids);
for(DBID id1 : oldids) {
- List<DistanceResultPair<D>> kNNs = storage.get(id1);
- D knnDist = kNNs.get(kNNs.size() - 1).getDistance();
+ KNNResult<D> kNNs = storage.get(id1);
+ D knnDist = kNNs.getKNNDistance();
// look for new kNNs
- List<DistanceResultPair<D>> newKNNs = new ArrayList<DistanceResultPair<D>>();
KNNHeap<D> heap = null;
for(DBID id2 : ids) {
D dist = distanceQuery.distance(id1, id2);
@@ -184,7 +185,7 @@ public class MaterializeKNNAndRKNNPreprocessor<O, D extends Distance<D>> extends
}
}
if(heap != null) {
- newKNNs = heap.toSortedArrayList();
+ KNNList<D> newKNNs = heap.toKNNList();
storage.put(id1, newKNNs);
// get the difference
@@ -234,7 +235,7 @@ public class MaterializeKNNAndRKNNPreprocessor<O, D extends Distance<D>> extends
if(stepprog != null) {
stepprog.beginStep(1, "New deletions ocurred, remove their materialized kNNs and RkNNs.", getLogger());
}
- List<List<DistanceResultPair<D>>> kNNs = new ArrayList<List<DistanceResultPair<D>>>(ids.size());
+ List<KNNResult<D>> kNNs = new ArrayList<KNNResult<D>>(ids.size());
List<List<DistanceResultPair<D>>> rkNNs = new ArrayList<List<DistanceResultPair<D>>>(ids.size());
for(DBID id : aids) {
kNNs.add(storage.get(id));
@@ -250,7 +251,7 @@ public class MaterializeKNNAndRKNNPreprocessor<O, D extends Distance<D>> extends
stepprog.beginStep(2, "New deletions ocurred, update the affected kNNs and RkNNs.", getLogger());
}
// update the kNNs of the RkNNs
- List<List<DistanceResultPair<D>>> kNNList = knnQuery.getKNNForBulkDBIDs(rkNN_ids, k);
+ List<KNNResult<D>> kNNList = knnQuery.getKNNForBulkDBIDs(rkNN_ids, k);
for(int i = 0; i < rkNN_ids.size(); i++) {
DBID id = rkNN_ids.get(i);
storage.put(id, kNNList.get(i));
@@ -260,7 +261,7 @@ public class MaterializeKNNAndRKNNPreprocessor<O, D extends Distance<D>> extends
}
}
// update the RkNNs of the kNNs
- TreeSetDBIDs idsSet = DBIDUtil.newTreeSet(ids);
+ SetDBIDs idsSet = DBIDUtil.ensureSet(ids);
for(int i = 0; i < kNN_ids.size(); i++) {
DBID id = kNN_ids.get(i);
SortedSet<DistanceResultPair<D>> rkNN = materialized_RkNN.get(id);
@@ -289,7 +290,7 @@ public class MaterializeKNNAndRKNNPreprocessor<O, D extends Distance<D>> extends
* @param id the query id
* @return the kNNs
*/
- public List<DistanceResultPair<D>> getKNN(DBID id) {
+ public KNNResult<D> getKNN(DBID id) {
return storage.get(id);
}
@@ -333,7 +334,7 @@ public class MaterializeKNNAndRKNNPreprocessor<O, D extends Distance<D>> extends
public String getShortName() {
return "knn and rknn preprocessor";
}
-
+
@Override
protected Logging getLogger() {
return logger;
@@ -373,8 +374,8 @@ public class MaterializeKNNAndRKNNPreprocessor<O, D extends Distance<D>> extends
*/
public static class Parameterizer<O, D extends Distance<D>> extends MaterializeKNNPreprocessor.Factory.Parameterizer<O, D> {
@Override
- protected Factory<O,D> makeInstance() {
- return new Factory<O,D>(k, distanceFunction);
+ protected Factory<O, D> makeInstance() {
+ return new Factory<O, D>(k, distanceFunction);
}
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/index/preprocessed/knn/MaterializeKNNPreprocessor.java b/src/de/lmu/ifi/dbs/elki/index/preprocessed/knn/MaterializeKNNPreprocessor.java
index 9d55e916..fcd6fad1 100644
--- a/src/de/lmu/ifi/dbs/elki/index/preprocessed/knn/MaterializeKNNPreprocessor.java
+++ b/src/de/lmu/ifi/dbs/elki/index/preprocessed/knn/MaterializeKNNPreprocessor.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.preprocessed.knn;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2011
+ Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
@@ -23,19 +23,22 @@ package de.lmu.ifi.dbs.elki.index.preprocessed.knn;
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-import java.util.ArrayList;
+import java.util.Collection;
import java.util.List;
-import de.lmu.ifi.dbs.elki.database.datastore.DataStoreFactory;
-import de.lmu.ifi.dbs.elki.database.datastore.DataStoreUtil;
+import javax.swing.event.EventListenerList;
+
import de.lmu.ifi.dbs.elki.database.ids.ArrayDBIDs;
+import de.lmu.ifi.dbs.elki.database.ids.ArrayModifiableDBIDs;
import de.lmu.ifi.dbs.elki.database.ids.DBID;
import de.lmu.ifi.dbs.elki.database.ids.DBIDUtil;
import de.lmu.ifi.dbs.elki.database.ids.DBIDs;
-import de.lmu.ifi.dbs.elki.database.ids.TreeSetModifiableDBIDs;
+import de.lmu.ifi.dbs.elki.database.ids.HashSetModifiableDBIDs;
+import de.lmu.ifi.dbs.elki.database.ids.SetDBIDs;
import de.lmu.ifi.dbs.elki.database.query.DatabaseQuery;
import de.lmu.ifi.dbs.elki.database.query.DistanceResultPair;
import de.lmu.ifi.dbs.elki.database.query.knn.KNNQuery;
+import de.lmu.ifi.dbs.elki.database.query.knn.KNNResult;
import de.lmu.ifi.dbs.elki.database.relation.Relation;
import de.lmu.ifi.dbs.elki.distance.distancefunction.DistanceFunction;
import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
@@ -64,7 +67,7 @@ import de.lmu.ifi.dbs.elki.utilities.documentation.Title;
*/
@Title("Materialize kNN Neighborhood preprocessor")
@Description("Materializes the k nearest neighbors of objects of a database.")
-public class MaterializeKNNPreprocessor<O, D extends Distance<D>> extends AbstractMaterializeKNNPreprocessor<O, D> {
+public class MaterializeKNNPreprocessor<O, D extends Distance<D>> extends AbstractMaterializeKNNPreprocessor<O, D, KNNResult<D>> {
/**
* Logger to use.
*/
@@ -83,30 +86,20 @@ public class MaterializeKNNPreprocessor<O, D extends Distance<D>> extends Abstra
protected final KNNQuery<O, D> knnQuery;
/**
- * Constructor with preprocessing step.
- *
- * @param relation Relation to preprocess
- * @param distanceFunction the distance function to use
- * @param k query k
+ * Holds the listener.
*/
- public MaterializeKNNPreprocessor(Relation<O> relation, DistanceFunction<? super O, D> distanceFunction, int k) {
- this(relation, distanceFunction, k, true);
- }
+ protected final EventListenerList listenerList = new EventListenerList();
/**
- * Constructor.
+ * Constructor with preprocessing step.
*
* @param relation Relation to preprocess
* @param distanceFunction the distance function to use
* @param k query k
*/
- protected MaterializeKNNPreprocessor(Relation<O> relation, DistanceFunction<? super O, D> distanceFunction, int k, boolean preprocess) {
+ public MaterializeKNNPreprocessor(Relation<O> relation, DistanceFunction<? super O, D> distanceFunction, int k) {
super(relation, distanceFunction, k);
this.knnQuery = relation.getDatabase().getKNNQuery(distanceQuery, k, DatabaseQuery.HINT_BULK, DatabaseQuery.HINT_HEAVY_USE, DatabaseQuery.HINT_NO_CACHE);
-
- if(preprocess) {
- preprocess();
- }
}
/**
@@ -114,13 +107,13 @@ public class MaterializeKNNPreprocessor<O, D extends Distance<D>> extends Abstra
*/
@Override
protected void preprocess() {
- storage = DataStoreUtil.makeStorage(relation.getDBIDs(), DataStoreFactory.HINT_STATIC, List.class);
+ createStorage();
ArrayDBIDs ids = DBIDUtil.ensureArray(relation.getDBIDs());
FiniteProgress progress = getLogger().isVerbose() ? new FiniteProgress("Materializing k nearest neighbors (k=" + k + ")", ids.size(), getLogger()) : null;
// Try bulk
- List<List<DistanceResultPair<D>>> kNNList = null;
+ List<KNNResult<D>> kNNList = null;
if(usebulk) {
kNNList = knnQuery.getKNNForBulkDBIDs(ids, k);
if(kNNList != null) {
@@ -135,7 +128,7 @@ public class MaterializeKNNPreprocessor<O, D extends Distance<D>> extends Abstra
}
else {
for(DBID id : ids) {
- List<DistanceResultPair<D>> knn = knnQuery.getKNNForDBID(id, k);
+ KNNResult<D> knn = knnQuery.getKNNForDBID(id, k);
storage.put(id, knn);
if(progress != null) {
progress.incrementProcessed(getLogger());
@@ -148,16 +141,6 @@ public class MaterializeKNNPreprocessor<O, D extends Distance<D>> extends Abstra
}
}
- /**
- * Get the k nearest neighbors.
- *
- * @param objid Object ID
- * @return Neighbors
- */
- public List<DistanceResultPair<D>> get(DBID objid) {
- return storage.get(objid);
- }
-
@Override
public final void insert(DBID id) {
objectsInserted(id);
@@ -165,6 +148,9 @@ public class MaterializeKNNPreprocessor<O, D extends Distance<D>> extends Abstra
@Override
public void insertAll(DBIDs ids) {
+ if(storage == null && ids.size() > 0) {
+ preprocess();
+ }
objectsInserted(ids);
}
@@ -193,7 +179,7 @@ public class MaterializeKNNPreprocessor<O, D extends Distance<D>> extends Abstra
if(stepprog != null) {
stepprog.beginStep(1, "New insertions ocurred, materialize their new kNNs.", getLogger());
}
- List<List<DistanceResultPair<D>>> kNNList = knnQuery.getKNNForBulkDBIDs(aids, k);
+ List<KNNResult<D>> kNNList = knnQuery.getKNNForBulkDBIDs(aids, k);
for(int i = 0; i < aids.size(); i++) {
DBID id = aids.get(i);
storage.put(id, kNNList.get(i));
@@ -225,13 +211,12 @@ public class MaterializeKNNPreprocessor<O, D extends Distance<D>> extends Abstra
* updated
*/
private ArrayDBIDs updateKNNsAfterInsertion(DBIDs ids) {
- ArrayDBIDs rkNN_ids = DBIDUtil.newArray();
+ ArrayModifiableDBIDs rkNN_ids = DBIDUtil.newArray();
DBIDs oldids = DBIDUtil.difference(relation.getDBIDs(), ids);
for(DBID id1 : oldids) {
- List<DistanceResultPair<D>> kNNs = storage.get(id1);
+ KNNResult<D> kNNs = storage.get(id1);
D knnDist = kNNs.get(kNNs.size() - 1).getDistance();
// look for new kNNs
- List<DistanceResultPair<D>> newKNNs = new ArrayList<DistanceResultPair<D>>();
KNNHeap<D> heap = null;
for(DBID id2 : ids) {
D dist = distanceQuery.distance(id1, id2);
@@ -244,8 +229,8 @@ public class MaterializeKNNPreprocessor<O, D extends Distance<D>> extends Abstra
}
}
if(heap != null) {
- newKNNs = heap.toSortedArrayList();
- storage.put(id1, newKNNs);
+ kNNs = heap.toKNNList();
+ storage.put(id1, kNNs);
rkNN_ids.add(id1);
}
}
@@ -260,10 +245,10 @@ public class MaterializeKNNPreprocessor<O, D extends Distance<D>> extends Abstra
* updated
*/
private ArrayDBIDs updateKNNsAfterDeletion(DBIDs ids) {
- TreeSetModifiableDBIDs idsSet = DBIDUtil.newTreeSet(ids);
- ArrayDBIDs rkNN_ids = DBIDUtil.newArray();
+ SetDBIDs idsSet = DBIDUtil.ensureSet(ids);
+ ArrayModifiableDBIDs rkNN_ids = DBIDUtil.newArray();
for(DBID id1 : relation.iterDBIDs()) {
- List<DistanceResultPair<D>> kNNs = storage.get(id1);
+ KNNResult<D> kNNs = storage.get(id1);
for(DistanceResultPair<D> kNN : kNNs) {
if(idsSet.contains(kNN.getDBID())) {
rkNN_ids.add(id1);
@@ -273,7 +258,7 @@ public class MaterializeKNNPreprocessor<O, D extends Distance<D>> extends Abstra
}
// update the kNNs of the RkNNs
- List<List<DistanceResultPair<D>>> kNNList = knnQuery.getKNNForBulkDBIDs(rkNN_ids, k);
+ List<KNNResult<D>> kNNList = knnQuery.getKNNForBulkDBIDs(rkNN_ids, k);
for(int i = 0; i < rkNN_ids.size(); i++) {
DBID id = rkNN_ids.get(i);
storage.put(id, kNNList.get(i));
@@ -360,16 +345,18 @@ public class MaterializeKNNPreprocessor<O, D extends Distance<D>> extends Abstra
* @param remove the ids to remove
* @return the DBIDs in the given collection
*/
- protected ArrayDBIDs extractAndRemoveIDs(List<List<DistanceResultPair<D>>> extraxt, ArrayDBIDs remove) {
- TreeSetModifiableDBIDs ids = DBIDUtil.newTreeSet();
- for(List<DistanceResultPair<D>> drps : extraxt) {
+ protected ArrayDBIDs extractAndRemoveIDs(List<? extends Collection<DistanceResultPair<D>>> extraxt, ArrayDBIDs remove) {
+ HashSetModifiableDBIDs ids = DBIDUtil.newHashSet();
+ for(Collection<DistanceResultPair<D>> drps : extraxt) {
for(DistanceResultPair<D> drp : drps) {
ids.add(drp.getDBID());
}
}
- ids.removeAll(remove);
- return DBIDUtil.ensureArray(ids);
-
+ for(DBID id : remove) {
+ ids.remove(id);
+ }
+ // Convert back to array
+ return DBIDUtil.newArray(ids);
}
/**
@@ -423,7 +410,7 @@ public class MaterializeKNNPreprocessor<O, D extends Distance<D>> extends Abstra
* @param <O> The object type
* @param <D> The distance type
*/
- public static class Factory<O, D extends Distance<D>> extends AbstractMaterializeKNNPreprocessor.Factory<O, D> {
+ public static class Factory<O, D extends Distance<D>> extends AbstractMaterializeKNNPreprocessor.Factory<O, D, KNNResult<D>> {
/**
* Index factory.
*
diff --git a/src/de/lmu/ifi/dbs/elki/index/preprocessed/knn/MetricalIndexApproximationMaterializeKNNPreprocessor.java b/src/de/lmu/ifi/dbs/elki/index/preprocessed/knn/MetricalIndexApproximationMaterializeKNNPreprocessor.java
index f20e6e39..5ac7d2d2 100644
--- a/src/de/lmu/ifi/dbs/elki/index/preprocessed/knn/MetricalIndexApproximationMaterializeKNNPreprocessor.java
+++ b/src/de/lmu/ifi/dbs/elki/index/preprocessed/knn/MetricalIndexApproximationMaterializeKNNPreprocessor.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.preprocessed.knn;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2011
+ Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
@@ -28,12 +28,11 @@ import java.util.HashMap;
import java.util.List;
import de.lmu.ifi.dbs.elki.data.NumberVector;
-import de.lmu.ifi.dbs.elki.database.datastore.DataStoreFactory;
-import de.lmu.ifi.dbs.elki.database.datastore.DataStoreUtil;
import de.lmu.ifi.dbs.elki.database.ids.DBID;
import de.lmu.ifi.dbs.elki.database.ids.DBIDPair;
import de.lmu.ifi.dbs.elki.database.ids.DBIDUtil;
import de.lmu.ifi.dbs.elki.database.query.distance.DistanceQuery;
+import de.lmu.ifi.dbs.elki.database.query.knn.KNNResult;
import de.lmu.ifi.dbs.elki.database.relation.Relation;
import de.lmu.ifi.dbs.elki.distance.distancefunction.DistanceFunction;
import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
@@ -69,7 +68,7 @@ import de.lmu.ifi.dbs.elki.utilities.documentation.Title;
*/
@Title("Spatial Approximation Materialize kNN Preprocessor")
@Description("Caterializes the (approximate) k nearest neighbors of objects of a database using a spatial approximation.")
-public class MetricalIndexApproximationMaterializeKNNPreprocessor<O extends NumberVector<? super O, ?>, D extends Distance<D>, N extends Node<E>, E extends MTreeEntry<D>> extends AbstractMaterializeKNNPreprocessor<O, D> {
+public class MetricalIndexApproximationMaterializeKNNPreprocessor<O extends NumberVector<? super O, ?>, D extends Distance<D>, N extends Node<E>, E extends MTreeEntry<D>> extends AbstractMaterializeKNNPreprocessor<O, D, KNNResult<D>> {
/**
* Logger to use
*/
@@ -92,7 +91,7 @@ public class MetricalIndexApproximationMaterializeKNNPreprocessor<O extends Numb
MetricalIndexTree<O, D, N, E> index = getMetricalIndex(relation);
- storage = DataStoreUtil.makeStorage(relation.getDBIDs(), DataStoreFactory.HINT_STATIC, List.class);
+ createStorage();
MeanVariance pagesize = new MeanVariance();
MeanVariance ksize = new MeanVariance();
if(getLogger().isVerbose()) {
@@ -133,7 +132,7 @@ public class MetricalIndexApproximationMaterializeKNNPreprocessor<O extends Numb
}
}
ksize.put(kNN.size());
- storage.put(id, kNN.toSortedArrayList());
+ storage.put(id, kNN.toKNNList());
}
if(getLogger().isDebugging()) {
if(cache.size() > 0) {
@@ -203,7 +202,7 @@ public class MetricalIndexApproximationMaterializeKNNPreprocessor<O extends Numb
* @param <N> the type of spatial nodes in the spatial index
* @param <E> the type of spatial entries in the spatial index
*/
- public static class Factory<O extends NumberVector<? super O, ?>, D extends Distance<D>, N extends Node<E>, E extends MTreeEntry<D>> extends AbstractMaterializeKNNPreprocessor.Factory<O, D> {
+ public static class Factory<O extends NumberVector<? super O, ?>, D extends Distance<D>, N extends Node<E>, E extends MTreeEntry<D>> extends AbstractMaterializeKNNPreprocessor.Factory<O, D, KNNResult<D>> {
/**
* Constructor.
*
diff --git a/src/de/lmu/ifi/dbs/elki/index/preprocessed/knn/PartitionApproximationMaterializeKNNPreprocessor.java b/src/de/lmu/ifi/dbs/elki/index/preprocessed/knn/PartitionApproximationMaterializeKNNPreprocessor.java
index 3e7d1b8f..90813b92 100644
--- a/src/de/lmu/ifi/dbs/elki/index/preprocessed/knn/PartitionApproximationMaterializeKNNPreprocessor.java
+++ b/src/de/lmu/ifi/dbs/elki/index/preprocessed/knn/PartitionApproximationMaterializeKNNPreprocessor.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.preprocessed.knn;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2011
+ Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
@@ -24,7 +24,6 @@ package de.lmu.ifi.dbs.elki.index.preprocessed.knn;
*/
import java.util.HashMap;
-import java.util.List;
import de.lmu.ifi.dbs.elki.database.datastore.DataStoreFactory;
import de.lmu.ifi.dbs.elki.database.datastore.DataStoreUtil;
@@ -34,6 +33,7 @@ import de.lmu.ifi.dbs.elki.database.ids.DBID;
import de.lmu.ifi.dbs.elki.database.ids.DBIDPair;
import de.lmu.ifi.dbs.elki.database.ids.DBIDUtil;
import de.lmu.ifi.dbs.elki.database.query.distance.DistanceQuery;
+import de.lmu.ifi.dbs.elki.database.query.knn.KNNResult;
import de.lmu.ifi.dbs.elki.database.relation.Relation;
import de.lmu.ifi.dbs.elki.distance.distancefunction.DistanceFunction;
import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
@@ -61,7 +61,7 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.IntParameter;
*/
@Title("Partitioning Approximate kNN Preprocessor")
@Description("Caterializes the (approximate) k nearest neighbors of objects of a database by partitioning and only computing kNN within each partition.")
-public class PartitionApproximationMaterializeKNNPreprocessor<O, D extends Distance<D>> extends AbstractMaterializeKNNPreprocessor<O, D> {
+public class PartitionApproximationMaterializeKNNPreprocessor<O, D extends Distance<D>> extends AbstractMaterializeKNNPreprocessor<O, D, KNNResult<D>> {
// TODO: randomize/shuffle?
/**
@@ -85,14 +85,12 @@ public class PartitionApproximationMaterializeKNNPreprocessor<O, D extends Dista
public PartitionApproximationMaterializeKNNPreprocessor(Relation<O> relation, DistanceFunction<? super O, D> distanceFunction, int k, int partitions) {
super(relation, distanceFunction, k);
this.partitions = partitions;
- // preprocess now
- preprocess();
}
@Override
protected void preprocess() {
DistanceQuery<O, D> distanceQuery = relation.getDatabase().getDistanceQuery(relation, distanceFunction);
- storage = DataStoreUtil.makeStorage(relation.getDBIDs(), DataStoreFactory.HINT_STATIC, List.class);
+ storage = DataStoreUtil.makeStorage(relation.getDBIDs(), DataStoreFactory.HINT_STATIC, KNNResult.class);
MeanVariance ksize = new MeanVariance();
if(logger.isVerbose()) {
logger.verbose("Approximating nearest neighbor lists to database objects");
@@ -130,7 +128,7 @@ public class PartitionApproximationMaterializeKNNPreprocessor<O, D extends Dista
}
}
ksize.put(kNN.size());
- storage.put(id, kNN.toSortedArrayList());
+ storage.put(id, kNN.toKNNList());
}
if(logger.isDebugging()) {
if(cache.size() > 0) {
@@ -176,7 +174,7 @@ public class PartitionApproximationMaterializeKNNPreprocessor<O, D extends Dista
* @param <O> The object type
* @param <D> The distance type
*/
- public static class Factory<O, D extends Distance<D>> extends AbstractMaterializeKNNPreprocessor.Factory<O, D> {
+ public static class Factory<O, D extends Distance<D>> extends AbstractMaterializeKNNPreprocessor.Factory<O, D, KNNResult<D>> {
/**
* Parameter to specify the number of partitions to use for materializing
* the kNN. Must be an integer greater than 1.
diff --git a/src/de/lmu/ifi/dbs/elki/index/preprocessed/knn/RandomSampleKNNPreprocessor.java b/src/de/lmu/ifi/dbs/elki/index/preprocessed/knn/RandomSampleKNNPreprocessor.java
new file mode 100644
index 00000000..924c7c3c
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/index/preprocessed/knn/RandomSampleKNNPreprocessor.java
@@ -0,0 +1,237 @@
+package de.lmu.ifi.dbs.elki.index.preprocessed.knn;
+
+/*
+ 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 <http://www.gnu.org/licenses/>.
+ */
+
+import java.util.Random;
+
+import de.lmu.ifi.dbs.elki.database.datastore.DataStoreFactory;
+import de.lmu.ifi.dbs.elki.database.datastore.DataStoreUtil;
+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.DBIDUtil;
+import de.lmu.ifi.dbs.elki.database.ids.DBIDs;
+import de.lmu.ifi.dbs.elki.database.query.GenericDistanceResultPair;
+import de.lmu.ifi.dbs.elki.database.query.distance.DistanceQuery;
+import de.lmu.ifi.dbs.elki.database.query.knn.KNNResult;
+import de.lmu.ifi.dbs.elki.database.relation.Relation;
+import de.lmu.ifi.dbs.elki.distance.distancefunction.DistanceFunction;
+import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
+import de.lmu.ifi.dbs.elki.logging.Logging;
+import de.lmu.ifi.dbs.elki.logging.progress.FiniteProgress;
+import de.lmu.ifi.dbs.elki.utilities.datastructures.heap.KNNHeap;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.OptionID;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.constraints.IntervalConstraint;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.constraints.IntervalConstraint.IntervalBoundary;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.DoubleParameter;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.LongParameter;
+
+/**
+ * Class that computed the kNN only on a random sample.
+ *
+ * @author Erich Schubert
+ *
+ * @param <O> Object type
+ * @param <D> Distance type
+ */
+public class RandomSampleKNNPreprocessor<O, D extends Distance<D>> extends AbstractMaterializeKNNPreprocessor<O, D, KNNResult<D>> {
+ /**
+ * Logger
+ */
+ private static final Logging logger = Logging.getLogger(RandomSampleKNNPreprocessor.class);
+
+ /**
+ * Relative share of objects to get
+ */
+ private final double share;
+
+ /**
+ * Random seed
+ */
+ private final Long seed;
+
+ /**
+ * Constructor.
+ *
+ * @param relation Relation to index
+ * @param distanceFunction distance function
+ * @param k k
+ * @param share Relative share
+ * @param seed Random seed (may be null)
+ */
+ public RandomSampleKNNPreprocessor(Relation<O> relation, DistanceFunction<? super O, D> distanceFunction, int k, double share, Long seed) {
+ super(relation, distanceFunction, k);
+ this.share = share;
+ this.seed = seed;
+ }
+
+ @Override
+ protected void preprocess() {
+ DistanceQuery<O, D> distanceQuery = relation.getDatabase().getDistanceQuery(relation, distanceFunction);
+ storage = DataStoreUtil.makeStorage(relation.getDBIDs(), DataStoreFactory.HINT_STATIC, KNNResult.class);
+ FiniteProgress progress = getLogger().isVerbose() ? new FiniteProgress("Materializing random-sample k nearest neighbors (k=" + k + ")", relation.size(), getLogger()) : null;
+
+ final ArrayDBIDs ids = DBIDUtil.ensureArray(relation.getDBIDs());
+ final int samplesize = (int) (ids.size() * share);
+ final long iseed = (seed != null) ? seed : (new Random()).nextLong();
+
+ int i = 0;
+ for(DBID id : ids) {
+ KNNHeap<D> kNN = new KNNHeap<D>(k, distanceQuery.infiniteDistance());
+
+ long rseed = i * 0x7FFFFFFFFFFFFFE7L + iseed;
+ DBIDs rsamp = DBIDUtil.randomSample(ids, samplesize, rseed);
+ for(DBID oid : rsamp) {
+ D dist = distanceQuery.distance(id, oid);
+ kNN.add(new GenericDistanceResultPair<D>(dist, oid));
+ }
+
+ storage.put(id, kNN.toKNNList());
+ if(progress != null) {
+ progress.incrementProcessed(getLogger());
+ }
+ }
+
+ if(progress != null) {
+ progress.ensureCompleted(getLogger());
+ }
+ }
+
+ @Override
+ protected Logging getLogger() {
+ return logger;
+ }
+
+ @Override
+ public String getLongName() {
+ return "random sample kNN";
+ }
+
+ @Override
+ public String getShortName() {
+ return "random-sample-knn";
+ }
+
+ /**
+ * The parameterizable factory.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.landmark
+ * @apiviz.stereotype factory
+ * @apiviz.uses AbstractMaterializeKNNPreprocessor oneway - - «create»
+ *
+ * @param <O> The object type
+ * @param <D> The distance type
+ */
+ public static class Factory<O, D extends Distance<D>> extends AbstractMaterializeKNNPreprocessor.Factory<O, D, KNNResult<D>> {
+ /**
+ * Relative share of objects to get
+ */
+ private final double share;
+
+ /**
+ * Random seed
+ */
+ private final Long seed;
+
+ /**
+ * Constructor.
+ *
+ * @param k K
+ * @param distanceFunction distance function
+ * @param share Sample size (relative)
+ * @param seed Random seed
+ */
+ public Factory(int k, DistanceFunction<? super O, D> distanceFunction, double share, Long seed) {
+ super(k, distanceFunction);
+ this.share = share;
+ this.seed = seed;
+ }
+
+ @Override
+ public RandomSampleKNNPreprocessor<O, D> instantiate(Relation<O> relation) {
+ return new RandomSampleKNNPreprocessor<O, D>(relation, distanceFunction, k, share, seed);
+ }
+
+ /**
+ * Parameterization class
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ *
+ * @param <O> Object type
+ * @param <D> Distance type
+ */
+ public static class Parameterizer<O, D extends Distance<D>> extends AbstractMaterializeKNNPreprocessor.Factory.Parameterizer<O, D> {
+ /**
+ * Parameter to specify how many objects to consider for computing the
+ * kNN.
+ *
+ * <p>
+ * Key: {@code -randomknn.share}
+ * </p>
+ */
+ public static final OptionID SHARE_ID = OptionID.getOrCreateOptionID("randomknn.share", "The relative amount of objects to consider for kNN computations.");
+
+ /**
+ * Random number generator seed.
+ *
+ * <p>
+ * Key: {@code -randomknn.seed}
+ * </p>
+ */
+ public static final OptionID SEED_ID = OptionID.getOrCreateOptionID("randomknn.seed", "The random number seed.");
+
+ /**
+ * Relative share of objects to get
+ */
+ private double share = 0.0;
+
+ /**
+ * Random seed
+ */
+ private Long seed = null;
+
+ @Override
+ protected void makeOptions(Parameterization config) {
+ super.makeOptions(config);
+ DoubleParameter shareP = new DoubleParameter(SHARE_ID, new IntervalConstraint(0.0, IntervalBoundary.OPEN, 1.0, IntervalBoundary.OPEN));
+ if(config.grab(shareP)) {
+ share = shareP.getValue();
+ }
+ LongParameter seedP = new LongParameter(SEED_ID, true);
+ if(config.grab(seedP)) {
+ seed = seedP.getValue();
+ }
+ }
+
+ @Override
+ protected RandomSampleKNNPreprocessor.Factory<O, D> makeInstance() {
+ return new RandomSampleKNNPreprocessor.Factory<O, D>(k, distanceFunction, share, seed);
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/index/preprocessed/knn/SpatialApproximationMaterializeKNNPreprocessor.java b/src/de/lmu/ifi/dbs/elki/index/preprocessed/knn/SpatialApproximationMaterializeKNNPreprocessor.java
index 320a3636..e78f5e89 100644
--- a/src/de/lmu/ifi/dbs/elki/index/preprocessed/knn/SpatialApproximationMaterializeKNNPreprocessor.java
+++ b/src/de/lmu/ifi/dbs/elki/index/preprocessed/knn/SpatialApproximationMaterializeKNNPreprocessor.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.preprocessed.knn;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2011
+ Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
@@ -34,6 +34,7 @@ import de.lmu.ifi.dbs.elki.database.ids.DBID;
import de.lmu.ifi.dbs.elki.database.ids.DBIDPair;
import de.lmu.ifi.dbs.elki.database.ids.DBIDUtil;
import de.lmu.ifi.dbs.elki.database.query.distance.DistanceQuery;
+import de.lmu.ifi.dbs.elki.database.query.knn.KNNResult;
import de.lmu.ifi.dbs.elki.database.relation.Relation;
import de.lmu.ifi.dbs.elki.distance.distancefunction.DistanceFunction;
import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
@@ -68,7 +69,7 @@ import de.lmu.ifi.dbs.elki.utilities.exceptions.AbortException;
*/
@Title("Spatial Approximation Materialize kNN Preprocessor")
@Description("Caterializes the (approximate) k nearest neighbors of objects of a database using a spatial approximation.")
-public class SpatialApproximationMaterializeKNNPreprocessor<O extends NumberVector<?, ?>, D extends Distance<D>, N extends SpatialNode<N, E>, E extends SpatialEntry> extends AbstractMaterializeKNNPreprocessor<O, D> {
+public class SpatialApproximationMaterializeKNNPreprocessor<O extends NumberVector<?, ?>, D extends Distance<D>, N extends SpatialNode<N, E>, E extends SpatialEntry> extends AbstractMaterializeKNNPreprocessor<O, D, KNNResult<D>> {
/**
* Logger to use
*/
@@ -83,7 +84,6 @@ public class SpatialApproximationMaterializeKNNPreprocessor<O extends NumberVect
*/
public SpatialApproximationMaterializeKNNPreprocessor(Relation<O> relation, DistanceFunction<? super O, D> distanceFunction, int k) {
super(relation, distanceFunction, k);
- preprocess();
}
@Override
@@ -96,7 +96,7 @@ public class SpatialApproximationMaterializeKNNPreprocessor<O extends NumberVect
}
SpatialIndexTree<N, E> index = indexes.iterator().next();
- storage = DataStoreUtil.makeStorage(relation.getDBIDs(), DataStoreFactory.HINT_STATIC, List.class);
+ storage = DataStoreUtil.makeStorage(relation.getDBIDs(), DataStoreFactory.HINT_STATIC, KNNResult.class);
MeanVariance pagesize = new MeanVariance();
MeanVariance ksize = new MeanVariance();
if(getLogger().isVerbose()) {
@@ -137,7 +137,7 @@ public class SpatialApproximationMaterializeKNNPreprocessor<O extends NumberVect
}
}
ksize.put(kNN.size());
- storage.put(id, kNN.toSortedArrayList());
+ storage.put(id, kNN.toKNNList());
}
if(getLogger().isDebugging()) {
if(cache.size() > 0) {
@@ -185,7 +185,7 @@ public class SpatialApproximationMaterializeKNNPreprocessor<O extends NumberVect
* @param <N> the type of spatial nodes in the spatial index
* @param <E> the type of spatial entries in the spatial index
*/
- public static class Factory<D extends Distance<D>, N extends SpatialNode<N, E>, E extends SpatialEntry> extends AbstractMaterializeKNNPreprocessor.Factory<NumberVector<?, ?>, D> {
+ public static class Factory<D extends Distance<D>, N extends SpatialNode<N, E>, E extends SpatialEntry> extends AbstractMaterializeKNNPreprocessor.Factory<NumberVector<?, ?>, D, KNNResult<D>> {
/**
* Constructor.
*
diff --git a/src/de/lmu/ifi/dbs/elki/index/preprocessed/knn/package-info.java b/src/de/lmu/ifi/dbs/elki/index/preprocessed/knn/package-info.java
index 57fe5fbd..1780cdc0 100644
--- a/src/de/lmu/ifi/dbs/elki/index/preprocessed/knn/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/index/preprocessed/knn/package-info.java
@@ -5,7 +5,7 @@
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
-Copyright (C) 2011
+Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
diff --git a/src/de/lmu/ifi/dbs/elki/index/preprocessed/localpca/AbstractFilteredPCAIndex.java b/src/de/lmu/ifi/dbs/elki/index/preprocessed/localpca/AbstractFilteredPCAIndex.java
index 3def22a1..9cb2b997 100644
--- a/src/de/lmu/ifi/dbs/elki/index/preprocessed/localpca/AbstractFilteredPCAIndex.java
+++ b/src/de/lmu/ifi/dbs/elki/index/preprocessed/localpca/AbstractFilteredPCAIndex.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.preprocessed.localpca;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2011
+ Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
@@ -23,7 +23,7 @@ package de.lmu.ifi.dbs.elki.index.preprocessed.localpca;
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-import java.util.List;
+import java.util.Collection;
import de.lmu.ifi.dbs.elki.data.NumberVector;
import de.lmu.ifi.dbs.elki.data.type.TypeInformation;
@@ -100,7 +100,7 @@ public abstract class AbstractFilteredPCAIndex<NV extends NumberVector<? extends
// TODO: use a bulk operation?
for(DBID id : relation.iterDBIDs()) {
- List<DistanceResultPair<DoubleDistance>> objects = objectsForPCA(id);
+ Collection<DistanceResultPair<DoubleDistance>> objects = objectsForPCA(id);
PCAFilteredResult pcares = pca.processQueryResult(objects, relation);
@@ -137,7 +137,7 @@ public abstract class AbstractFilteredPCAIndex<NV extends NumberVector<? extends
* @return the list of the objects (i.e. the ids and the distances to the
* query object) to be considered within the PCA
*/
- protected abstract List<DistanceResultPair<DoubleDistance>> objectsForPCA(DBID id);
+ protected abstract Collection<DistanceResultPair<DoubleDistance>> objectsForPCA(DBID id);
/**
* Factory class
@@ -185,7 +185,7 @@ public abstract class AbstractFilteredPCAIndex<NV extends NumberVector<? extends
public TypeInformation getInputTypeRestriction() {
return pcaDistanceFunction.getInputTypeRestriction();
}
-
+
/**
* Parameterization class.
*
diff --git a/src/de/lmu/ifi/dbs/elki/index/preprocessed/localpca/FilteredLocalPCAIndex.java b/src/de/lmu/ifi/dbs/elki/index/preprocessed/localpca/FilteredLocalPCAIndex.java
index 18835caa..8130f6b3 100644
--- a/src/de/lmu/ifi/dbs/elki/index/preprocessed/localpca/FilteredLocalPCAIndex.java
+++ b/src/de/lmu/ifi/dbs/elki/index/preprocessed/localpca/FilteredLocalPCAIndex.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.preprocessed.localpca;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2011
+ Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
diff --git a/src/de/lmu/ifi/dbs/elki/index/preprocessed/localpca/KNNQueryFilteredPCAIndex.java b/src/de/lmu/ifi/dbs/elki/index/preprocessed/localpca/KNNQueryFilteredPCAIndex.java
index 7565ab32..8d766391 100644
--- a/src/de/lmu/ifi/dbs/elki/index/preprocessed/localpca/KNNQueryFilteredPCAIndex.java
+++ b/src/de/lmu/ifi/dbs/elki/index/preprocessed/localpca/KNNQueryFilteredPCAIndex.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.preprocessed.localpca;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2011
+ Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
@@ -23,13 +23,11 @@ package de.lmu.ifi.dbs.elki.index.preprocessed.localpca;
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-import java.util.List;
-
import de.lmu.ifi.dbs.elki.data.NumberVector;
import de.lmu.ifi.dbs.elki.database.QueryUtil;
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.knn.KNNQuery;
+import de.lmu.ifi.dbs.elki.database.query.knn.KNNResult;
import de.lmu.ifi.dbs.elki.database.relation.Relation;
import de.lmu.ifi.dbs.elki.distance.distancefunction.DistanceFunction;
import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance;
@@ -88,7 +86,7 @@ public class KNNQueryFilteredPCAIndex<NV extends NumberVector<? extends NV, ?>>
}
@Override
- protected List<DistanceResultPair<DoubleDistance>> objectsForPCA(DBID id) {
+ protected KNNResult<DoubleDistance> objectsForPCA(DBID id) {
return knnQuery.getKNNForDBID(id, k);
}
diff --git a/src/de/lmu/ifi/dbs/elki/index/preprocessed/localpca/RangeQueryFilteredPCAIndex.java b/src/de/lmu/ifi/dbs/elki/index/preprocessed/localpca/RangeQueryFilteredPCAIndex.java
index 26f08ae3..7d5da770 100644
--- a/src/de/lmu/ifi/dbs/elki/index/preprocessed/localpca/RangeQueryFilteredPCAIndex.java
+++ b/src/de/lmu/ifi/dbs/elki/index/preprocessed/localpca/RangeQueryFilteredPCAIndex.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.preprocessed.localpca;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2011
+ Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
diff --git a/src/de/lmu/ifi/dbs/elki/index/preprocessed/localpca/package-info.java b/src/de/lmu/ifi/dbs/elki/index/preprocessed/localpca/package-info.java
index f097bd14..2bd9cc7d 100644
--- a/src/de/lmu/ifi/dbs/elki/index/preprocessed/localpca/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/index/preprocessed/localpca/package-info.java
@@ -5,7 +5,7 @@
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
-Copyright (C) 2011
+Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
diff --git a/src/de/lmu/ifi/dbs/elki/index/preprocessed/package-info.java b/src/de/lmu/ifi/dbs/elki/index/preprocessed/package-info.java
index 4c482cd2..98a55d88 100644
--- a/src/de/lmu/ifi/dbs/elki/index/preprocessed/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/index/preprocessed/package-info.java
@@ -5,7 +5,7 @@
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
-Copyright (C) 2011
+Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
diff --git a/src/de/lmu/ifi/dbs/elki/index/preprocessed/preference/AbstractPreferenceVectorIndex.java b/src/de/lmu/ifi/dbs/elki/index/preprocessed/preference/AbstractPreferenceVectorIndex.java
index 13b6e28b..95c698ee 100644
--- a/src/de/lmu/ifi/dbs/elki/index/preprocessed/preference/AbstractPreferenceVectorIndex.java
+++ b/src/de/lmu/ifi/dbs/elki/index/preprocessed/preference/AbstractPreferenceVectorIndex.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.preprocessed.preference;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2011
+ Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
diff --git a/src/de/lmu/ifi/dbs/elki/index/preprocessed/preference/DiSHPreferenceVectorIndex.java b/src/de/lmu/ifi/dbs/elki/index/preprocessed/preference/DiSHPreferenceVectorIndex.java
index 8626e5b7..ade6c114 100644
--- a/src/de/lmu/ifi/dbs/elki/index/preprocessed/preference/DiSHPreferenceVectorIndex.java
+++ b/src/de/lmu/ifi/dbs/elki/index/preprocessed/preference/DiSHPreferenceVectorIndex.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.preprocessed.preference;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2011
+ Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
diff --git a/src/de/lmu/ifi/dbs/elki/index/preprocessed/preference/HiSCPreferenceVectorIndex.java b/src/de/lmu/ifi/dbs/elki/index/preprocessed/preference/HiSCPreferenceVectorIndex.java
index 849e0fd6..44ddb17c 100644
--- a/src/de/lmu/ifi/dbs/elki/index/preprocessed/preference/HiSCPreferenceVectorIndex.java
+++ b/src/de/lmu/ifi/dbs/elki/index/preprocessed/preference/HiSCPreferenceVectorIndex.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.preprocessed.preference;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2011
+ Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
@@ -25,7 +25,6 @@ package de.lmu.ifi.dbs.elki.index.preprocessed.preference;
import java.util.BitSet;
import java.util.Iterator;
-import java.util.List;
import de.lmu.ifi.dbs.elki.algorithm.clustering.subspace.HiSC;
import de.lmu.ifi.dbs.elki.data.NumberVector;
@@ -33,11 +32,9 @@ import de.lmu.ifi.dbs.elki.database.QueryUtil;
import de.lmu.ifi.dbs.elki.database.datastore.DataStoreFactory;
import de.lmu.ifi.dbs.elki.database.datastore.DataStoreUtil;
import de.lmu.ifi.dbs.elki.database.ids.DBID;
-import de.lmu.ifi.dbs.elki.database.ids.DBIDUtil;
import de.lmu.ifi.dbs.elki.database.ids.DBIDs;
-import de.lmu.ifi.dbs.elki.database.ids.ModifiableDBIDs;
-import de.lmu.ifi.dbs.elki.database.query.DistanceResultPair;
import de.lmu.ifi.dbs.elki.database.query.knn.KNNQuery;
+import de.lmu.ifi.dbs.elki.database.query.knn.KNNResult;
import de.lmu.ifi.dbs.elki.database.relation.Relation;
import de.lmu.ifi.dbs.elki.distance.distancefunction.EuclideanDistanceFunction;
import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance;
@@ -120,16 +117,8 @@ public class HiSCPreferenceVectorIndex<V extends NumberVector<?, ?>> extends Abs
msg.append("\n knns: ");
}
- List<DistanceResultPair<DoubleDistance>> knns = knnQuery.getKNNForDBID(id, k);
- ModifiableDBIDs knnIDs = DBIDUtil.newArray(knns.size());
- for(DistanceResultPair<DoubleDistance> knn : knns) {
- knnIDs.add(knn.getDBID());
- //if(logger.isDebugging()) {
- // msg.append(database.getObjectLabelQuery().get(knn.getID())).append(" ");
- //}
- }
-
- BitSet preferenceVector = determinePreferenceVector(relation, id, knnIDs, msg);
+ KNNResult<DoubleDistance> knns = knnQuery.getKNNForDBID(id, k);
+ BitSet preferenceVector = determinePreferenceVector(relation, id, knns.asDBIDs(), msg);
storage.put(id, preferenceVector);
if(progress != null) {
diff --git a/src/de/lmu/ifi/dbs/elki/index/preprocessed/preference/PreferenceVectorIndex.java b/src/de/lmu/ifi/dbs/elki/index/preprocessed/preference/PreferenceVectorIndex.java
index 1f2dd10b..c01e9ddb 100644
--- a/src/de/lmu/ifi/dbs/elki/index/preprocessed/preference/PreferenceVectorIndex.java
+++ b/src/de/lmu/ifi/dbs/elki/index/preprocessed/preference/PreferenceVectorIndex.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.preprocessed.preference;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2011
+ Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
diff --git a/src/de/lmu/ifi/dbs/elki/index/preprocessed/preference/package-info.java b/src/de/lmu/ifi/dbs/elki/index/preprocessed/preference/package-info.java
index 7676879c..69d0855b 100644
--- a/src/de/lmu/ifi/dbs/elki/index/preprocessed/preference/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/index/preprocessed/preference/package-info.java
@@ -5,7 +5,7 @@
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
-Copyright (C) 2011
+Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
diff --git a/src/de/lmu/ifi/dbs/elki/index/preprocessed/snn/SharedNearestNeighborIndex.java b/src/de/lmu/ifi/dbs/elki/index/preprocessed/snn/SharedNearestNeighborIndex.java
index 7920fc2b..7efe26e0 100644
--- a/src/de/lmu/ifi/dbs/elki/index/preprocessed/snn/SharedNearestNeighborIndex.java
+++ b/src/de/lmu/ifi/dbs/elki/index/preprocessed/snn/SharedNearestNeighborIndex.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.preprocessed.snn;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2011
+ Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
@@ -23,8 +23,8 @@ package de.lmu.ifi.dbs.elki.index.preprocessed.snn;
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+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.TreeSetDBIDs;
import de.lmu.ifi.dbs.elki.database.relation.Relation;
import de.lmu.ifi.dbs.elki.index.Index;
import de.lmu.ifi.dbs.elki.index.IndexFactory;
@@ -41,7 +41,7 @@ public interface SharedNearestNeighborIndex<O> extends Index {
* @param objid Object ID
* @return Neighbor DBIDs
*/
- public TreeSetDBIDs getNearestNeighborSet(DBID objid);
+ public ArrayDBIDs getNearestNeighborSet(DBID objid);
/**
* Get the number of neighbors
diff --git a/src/de/lmu/ifi/dbs/elki/index/preprocessed/snn/SharedNearestNeighborPreprocessor.java b/src/de/lmu/ifi/dbs/elki/index/preprocessed/snn/SharedNearestNeighborPreprocessor.java
index 43bd7e30..46f47a33 100644
--- a/src/de/lmu/ifi/dbs/elki/index/preprocessed/snn/SharedNearestNeighborPreprocessor.java
+++ b/src/de/lmu/ifi/dbs/elki/index/preprocessed/snn/SharedNearestNeighborPreprocessor.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.preprocessed.snn;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2011
+ Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
@@ -23,19 +23,16 @@ package de.lmu.ifi.dbs.elki.index.preprocessed.snn;
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-import java.util.List;
-
import de.lmu.ifi.dbs.elki.data.type.TypeInformation;
import de.lmu.ifi.dbs.elki.database.QueryUtil;
import de.lmu.ifi.dbs.elki.database.datastore.DataStoreFactory;
import de.lmu.ifi.dbs.elki.database.datastore.DataStoreUtil;
+import de.lmu.ifi.dbs.elki.database.ids.ArrayDBIDs;
+import de.lmu.ifi.dbs.elki.database.ids.ArrayModifiableDBIDs;
import de.lmu.ifi.dbs.elki.database.ids.DBID;
import de.lmu.ifi.dbs.elki.database.ids.DBIDUtil;
-import de.lmu.ifi.dbs.elki.database.ids.SetDBIDs;
-import de.lmu.ifi.dbs.elki.database.ids.TreeSetDBIDs;
-import de.lmu.ifi.dbs.elki.database.ids.TreeSetModifiableDBIDs;
-import de.lmu.ifi.dbs.elki.database.query.DistanceResultPair;
import de.lmu.ifi.dbs.elki.database.query.knn.KNNQuery;
+import de.lmu.ifi.dbs.elki.database.query.knn.KNNResult;
import de.lmu.ifi.dbs.elki.database.relation.Relation;
import de.lmu.ifi.dbs.elki.distance.distancefunction.DistanceFunction;
import de.lmu.ifi.dbs.elki.distance.distancefunction.EuclideanDistanceFunction;
@@ -75,7 +72,7 @@ import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ObjectParameter;
*/
@Title("Shared nearest neighbor Preprocessor")
@Description("Computes the k nearest neighbors of objects of a certain database.")
-public class SharedNearestNeighborPreprocessor<O, D extends Distance<D>> extends AbstractPreprocessorIndex<O, TreeSetDBIDs> implements SharedNearestNeighborIndex<O> {
+public class SharedNearestNeighborPreprocessor<O, D extends Distance<D>> extends AbstractPreprocessorIndex<O, ArrayDBIDs> implements SharedNearestNeighborIndex<O> {
/**
* Get a logger for this class.
*/
@@ -111,23 +108,24 @@ public class SharedNearestNeighborPreprocessor<O, D extends Distance<D>> extends
if(getLogger().isVerbose()) {
getLogger().verbose("Assigning nearest neighbor lists to database objects");
}
- storage = DataStoreUtil.makeStorage(relation.getDBIDs(), DataStoreFactory.HINT_HOT | DataStoreFactory.HINT_TEMP, SetDBIDs.class);
+ storage = DataStoreUtil.makeStorage(relation.getDBIDs(), DataStoreFactory.HINT_HOT | DataStoreFactory.HINT_TEMP, ArrayDBIDs.class);
KNNQuery<O, D> knnquery = QueryUtil.getKNNQuery(relation, distanceFunction, numberOfNeighbors);
FiniteProgress progress = getLogger().isVerbose() ? new FiniteProgress("assigning nearest neighbor lists", relation.size(), getLogger()) : null;
for(DBID id : relation.iterDBIDs()) {
- TreeSetModifiableDBIDs neighbors = DBIDUtil.newTreeSet(numberOfNeighbors);
- List<DistanceResultPair<D>> kNN = knnquery.getKNNForDBID(id, numberOfNeighbors);
+ ArrayModifiableDBIDs neighbors = DBIDUtil.newArray(numberOfNeighbors);
+ KNNResult<D> kNN = knnquery.getKNNForDBID(id, numberOfNeighbors);
for(int i = 0; i < kNN.size(); i++) {
final DBID nid = kNN.get(i).getDBID();
// if(!id.equals(nid)) {
neighbors.add(nid);
// }
- // Size limitation to exaclty numberOfNeighbors
+ // Size limitation to exactly numberOfNeighbors
if(neighbors.size() >= numberOfNeighbors) {
break;
}
}
+ neighbors.sort();
storage.put(id, neighbors);
if(progress != null) {
progress.incrementProcessed(getLogger());
@@ -139,7 +137,7 @@ public class SharedNearestNeighborPreprocessor<O, D extends Distance<D>> extends
}
@Override
- public TreeSetDBIDs getNearestNeighborSet(DBID objid) {
+ public ArrayDBIDs getNearestNeighborSet(DBID objid) {
if(storage == null) {
preprocess();
}
@@ -269,7 +267,7 @@ public class SharedNearestNeighborPreprocessor<O, D extends Distance<D>> extends
@Override
protected void makeOptions(Parameterization config) {
super.makeOptions(config);
- final IntParameter numberOfNeighborsP = new IntParameter(NUMBER_OF_NEIGHBORS_ID, new GreaterEqualConstraint(1), 1);
+ final IntParameter numberOfNeighborsP = new IntParameter(NUMBER_OF_NEIGHBORS_ID, new GreaterEqualConstraint(1));
if(config.grab(numberOfNeighborsP)) {
numberOfNeighbors = numberOfNeighborsP.getValue();
}
diff --git a/src/de/lmu/ifi/dbs/elki/index/preprocessed/snn/package-info.java b/src/de/lmu/ifi/dbs/elki/index/preprocessed/snn/package-info.java
index e29cd0e0..98065df6 100644
--- a/src/de/lmu/ifi/dbs/elki/index/preprocessed/snn/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/index/preprocessed/snn/package-info.java
@@ -5,7 +5,7 @@
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
-Copyright (C) 2011
+Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
diff --git a/src/de/lmu/ifi/dbs/elki/index/preprocessed/subspaceproj/AbstractSubspaceProjectionIndex.java b/src/de/lmu/ifi/dbs/elki/index/preprocessed/subspaceproj/AbstractSubspaceProjectionIndex.java
index 8aef442b..4a265fc9 100644
--- a/src/de/lmu/ifi/dbs/elki/index/preprocessed/subspaceproj/AbstractSubspaceProjectionIndex.java
+++ b/src/de/lmu/ifi/dbs/elki/index/preprocessed/subspaceproj/AbstractSubspaceProjectionIndex.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.preprocessed.subspaceproj;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2011
+ Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
diff --git a/src/de/lmu/ifi/dbs/elki/index/preprocessed/subspaceproj/FourCSubspaceIndex.java b/src/de/lmu/ifi/dbs/elki/index/preprocessed/subspaceproj/FourCSubspaceIndex.java
index 5a7fe2e0..83a9469c 100644
--- a/src/de/lmu/ifi/dbs/elki/index/preprocessed/subspaceproj/FourCSubspaceIndex.java
+++ b/src/de/lmu/ifi/dbs/elki/index/preprocessed/subspaceproj/FourCSubspaceIndex.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.preprocessed.subspaceproj;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2011
+ Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
diff --git a/src/de/lmu/ifi/dbs/elki/index/preprocessed/subspaceproj/PreDeConSubspaceIndex.java b/src/de/lmu/ifi/dbs/elki/index/preprocessed/subspaceproj/PreDeConSubspaceIndex.java
index cc05bcd1..1e83ae80 100644
--- a/src/de/lmu/ifi/dbs/elki/index/preprocessed/subspaceproj/PreDeConSubspaceIndex.java
+++ b/src/de/lmu/ifi/dbs/elki/index/preprocessed/subspaceproj/PreDeConSubspaceIndex.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.preprocessed.subspaceproj;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2011
+ Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
diff --git a/src/de/lmu/ifi/dbs/elki/index/preprocessed/subspaceproj/SubspaceProjectionIndex.java b/src/de/lmu/ifi/dbs/elki/index/preprocessed/subspaceproj/SubspaceProjectionIndex.java
index d0630aac..d5070986 100644
--- a/src/de/lmu/ifi/dbs/elki/index/preprocessed/subspaceproj/SubspaceProjectionIndex.java
+++ b/src/de/lmu/ifi/dbs/elki/index/preprocessed/subspaceproj/SubspaceProjectionIndex.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.preprocessed.subspaceproj;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2011
+ Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
diff --git a/src/de/lmu/ifi/dbs/elki/index/preprocessed/subspaceproj/package-info.java b/src/de/lmu/ifi/dbs/elki/index/preprocessed/subspaceproj/package-info.java
index b364aa09..f6e5e925 100644
--- a/src/de/lmu/ifi/dbs/elki/index/preprocessed/subspaceproj/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/index/preprocessed/subspaceproj/package-info.java
@@ -5,7 +5,7 @@
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
-Copyright (C) 2011
+Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/AbstractDirectoryEntry.java b/src/de/lmu/ifi/dbs/elki/index/tree/AbstractDirectoryEntry.java
index 2c764231..03572b35 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/AbstractDirectoryEntry.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/AbstractDirectoryEntry.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2011
+ Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/AbstractLeafEntry.java b/src/de/lmu/ifi/dbs/elki/index/tree/AbstractLeafEntry.java
index 2183888f..d2d38976 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/AbstractLeafEntry.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/AbstractLeafEntry.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2011
+ Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/AbstractNode.java b/src/de/lmu/ifi/dbs/elki/index/tree/AbstractNode.java
index 242267d6..42f4fa11 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/AbstractNode.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/AbstractNode.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2011
+ Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
@@ -28,14 +28,16 @@ import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.BitSet;
import java.util.Enumeration;
import java.util.List;
import java.util.NoSuchElementException;
-import java.util.logging.Logger;
+import de.lmu.ifi.dbs.elki.logging.Logging;
import de.lmu.ifi.dbs.elki.logging.LoggingConfiguration;
-import de.lmu.ifi.dbs.elki.persistent.AbstractPage;
+import de.lmu.ifi.dbs.elki.persistent.AbstractExternalizablePage;
import de.lmu.ifi.dbs.elki.utilities.ClassGenericsUtil;
+import de.lmu.ifi.dbs.elki.utilities.exceptions.AbortException;
/**
* Abstract superclass for nodes in an tree based index structure.
@@ -43,7 +45,7 @@ import de.lmu.ifi.dbs.elki.utilities.ClassGenericsUtil;
* @author Elke Achtert
* @param <E> the type of Entry used in the index
*/
-public abstract class AbstractNode<E extends Entry> extends AbstractPage implements Node<E> {
+public abstract class AbstractNode<E extends Entry> extends AbstractExternalizablePage implements Node<E> {
/**
* The number of entries in this node.
*/
@@ -155,7 +157,7 @@ public abstract class AbstractNode<E extends Entry> extends AbstractPage impleme
* both nodes are of the same type (leaf node or directory node) and have
* contain the same entries, <code>false</code> otherwise.
*
- * @see de.lmu.ifi.dbs.elki.persistent.AbstractPage#equals(Object)
+ * @see de.lmu.ifi.dbs.elki.persistent.AbstractExternalizablePage#equals(Object)
*/
@Override
public boolean equals(Object o) {
@@ -276,11 +278,17 @@ public abstract class AbstractNode<E extends Entry> extends AbstractPage impleme
* Returns a list of the entries.
*
* @return a list of the entries
+ *
+ * @deprecated Using this method means an extra copy - usually at the cost of
+ * performance.
*/
+ @Deprecated
public final List<E> getEntries() {
- List<E> result = new ArrayList<E>();
+ List<E> result = new ArrayList<E>(numEntries);
for(E entry : entries) {
- result.add(entry);
+ if(entry != null) {
+ result.add(entry);
+ }
}
return result;
}
@@ -298,6 +306,32 @@ public abstract class AbstractNode<E extends Entry> extends AbstractPage impleme
}
/**
+ * Remove entries according to the given mask.
+ *
+ * @param mask Mask to remove
+ */
+ public void removeMask(BitSet mask) {
+ int dest = mask.nextSetBit(0);
+ if(dest < 0) {
+ return;
+ }
+ int src = mask.nextClearBit(dest);
+ while(src < numEntries) {
+ if(!mask.get(src)) {
+ entries[dest] = entries[src];
+ dest++;
+ }
+ src++;
+ }
+ int rm = src - dest;
+ while(dest < numEntries) {
+ entries[dest] = null;
+ dest++;
+ }
+ numEntries -= rm;
+ }
+
+ /**
* Redistribute entries according to the given sorting.
*
* @param newNode Node to split to
@@ -305,7 +339,7 @@ public abstract class AbstractNode<E extends Entry> extends AbstractPage impleme
* @param splitPoint Split point
*/
public final void splitTo(AbstractNode<E> newNode, List<E> sorting, int splitPoint) {
- assert(isLeaf() == newNode.isLeaf());
+ assert (isLeaf() == newNode.isLeaf());
deleteAllEntries();
StringBuffer msg = LoggingConfiguration.DEBUG ? new StringBuffer("\n") : null;
@@ -325,7 +359,7 @@ public abstract class AbstractNode<E extends Entry> extends AbstractPage impleme
}
}
if(msg != null) {
- Logger.getLogger(this.getClass().getName()).fine(msg.toString());
+ Logging.getLogger(this.getClass().getName()).fine(msg.toString());
}
}
@@ -337,7 +371,7 @@ public abstract class AbstractNode<E extends Entry> extends AbstractPage impleme
* @param assignmentsToSecond the assignment to the new node
*/
public final void splitTo(AbstractNode<E> newNode, List<E> assignmentsToFirst, List<E> assignmentsToSecond) {
- assert(isLeaf() == newNode.isLeaf());
+ assert (isLeaf() == newNode.isLeaf());
deleteAllEntries();
StringBuffer msg = LoggingConfiguration.DEBUG ? new StringBuffer() : null;
@@ -357,7 +391,40 @@ public abstract class AbstractNode<E extends Entry> extends AbstractPage impleme
newNode.addEntry(entry);
}
if(msg != null) {
- Logger.getLogger(this.getClass().getName()).fine(msg.toString());
+ Logging.getLogger(this.getClass()).fine(msg.toString());
+ }
+ }
+
+ /**
+ * Splits the entries of this node into a new node using the given assignments
+ *
+ * @param newNode Node to split to
+ * @param assignment Assignment mask
+ */
+ public final void splitByMask(AbstractNode<E> newNode, BitSet assignment) {
+ assert (isLeaf() == newNode.isLeaf());
+ int dest = assignment.nextSetBit(0);
+ if(dest < 0) {
+ throw new AbortException("No bits set in splitting mask.");
+ }
+ int pos = dest;
+ while(pos < numEntries) {
+ if(assignment.get(pos)) {
+ // Move to new node
+ newNode.addEntry(entries[pos]);
+ }
+ else {
+ // Move to new position
+ entries[dest] = entries[pos];
+ dest++;
+ }
+ pos++;
+ }
+ final int rm = numEntries - dest;
+ while(dest < numEntries) {
+ entries[dest] = null;
+ dest++;
}
+ numEntries -= rm;
}
} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/BreadthFirstEnumeration.java b/src/de/lmu/ifi/dbs/elki/index/tree/BreadthFirstEnumeration.java
index f7f1c247..6f43de11 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/BreadthFirstEnumeration.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/BreadthFirstEnumeration.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2011
+ Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/DirectoryEntry.java b/src/de/lmu/ifi/dbs/elki/index/tree/DirectoryEntry.java
index c380dd4f..68924cae 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/DirectoryEntry.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/DirectoryEntry.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2011
+ Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/DistanceEntry.java b/src/de/lmu/ifi/dbs/elki/index/tree/DistanceEntry.java
index b7bf3e0c..3cf6dfb9 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/DistanceEntry.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/DistanceEntry.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2011
+ Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/Entry.java b/src/de/lmu/ifi/dbs/elki/index/tree/Entry.java
index 9ac01380..77c13d8e 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/Entry.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/Entry.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2011
+ Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/IndexTree.java b/src/de/lmu/ifi/dbs/elki/index/tree/IndexTree.java
index fa9c0e0a..e4cdc71f 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/IndexTree.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/IndexTree.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2011
+ Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
@@ -121,7 +121,7 @@ public abstract class IndexTree<N extends Node<E>, E extends Entry> {
*
* @return page id
*/
- public final Integer getRootID() {
+ public final int getRootID() {
return getPageID(rootEntry);
}
@@ -141,7 +141,7 @@ public abstract class IndexTree<N extends Node<E>, E extends Entry> {
* @return Whether the page ID is the root
*/
protected boolean isRoot(N page) {
- return getRootID().equals(page.getPageID());
+ return getRootID() == page.getPageID();
}
/**
@@ -150,7 +150,7 @@ public abstract class IndexTree<N extends Node<E>, E extends Entry> {
* @param entry Entry
* @return Page ID
*/
- protected Integer getPageID(Entry entry) {
+ protected int getPageID(Entry entry) {
if (entry.isLeafEntry()) {
throw new AbortException("Leafs do not have page ids!");
}
@@ -163,7 +163,7 @@ public abstract class IndexTree<N extends Node<E>, E extends Entry> {
* @param nodeID the page id of the node to be returned
* @return the node with the specified id
*/
- public N getNode(Integer nodeID) {
+ public N getNode(int nodeID) {
if(nodeID == getPageID(rootEntry)) {
return getRoot();
}
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/IndexTreePath.java b/src/de/lmu/ifi/dbs/elki/index/tree/IndexTreePath.java
index feb134e3..560bd250 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/IndexTreePath.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/IndexTreePath.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2011
+ Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/LeafEntry.java b/src/de/lmu/ifi/dbs/elki/index/tree/LeafEntry.java
index 362e2daf..c6eb1269 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/LeafEntry.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/LeafEntry.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2011
+ Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/Node.java b/src/de/lmu/ifi/dbs/elki/index/tree/Node.java
index 62892a22..c288a1fe 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/Node.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/Node.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2011
+ Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/TreeIndexFactory.java b/src/de/lmu/ifi/dbs/elki/index/tree/TreeIndexFactory.java
index b55700ec..a170ca5b 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/TreeIndexFactory.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/TreeIndexFactory.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2011
+ Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
@@ -26,9 +26,9 @@ package de.lmu.ifi.dbs.elki.index.tree;
import de.lmu.ifi.dbs.elki.database.relation.Relation;
import de.lmu.ifi.dbs.elki.index.Index;
import de.lmu.ifi.dbs.elki.index.IndexFactory;
+import de.lmu.ifi.dbs.elki.persistent.ExternalizablePage;
import de.lmu.ifi.dbs.elki.persistent.LRUCache;
import de.lmu.ifi.dbs.elki.persistent.MemoryPageFile;
-import de.lmu.ifi.dbs.elki.persistent.Page;
import de.lmu.ifi.dbs.elki.persistent.PageFile;
import de.lmu.ifi.dbs.elki.persistent.PersistentPageFile;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
@@ -124,7 +124,7 @@ public abstract class TreeIndexFactory<O, I extends Index> implements IndexFacto
* @return Page file
*/
// FIXME: make this single-shot when filename is set!
- protected <N extends Page> PageFile<N> makePageFile(Class<N> cls) {
+ protected <N extends ExternalizablePage> PageFile<N> makePageFile(Class<N> cls) {
final PageFile<N> inner;
if(fileName == null) {
inner = new MemoryPageFile<N>(pageSize);
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/TreeIndexHeader.java b/src/de/lmu/ifi/dbs/elki/index/tree/TreeIndexHeader.java
index 3bb901e3..017c3571 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/TreeIndexHeader.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/TreeIndexHeader.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2011
+ Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/TreeIndexPathComponent.java b/src/de/lmu/ifi/dbs/elki/index/tree/TreeIndexPathComponent.java
index 2309c7e5..d2800d54 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/TreeIndexPathComponent.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/TreeIndexPathComponent.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2011
+ Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/MetricalIndexTree.java b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/MetricalIndexTree.java
index 606921df..b98841aa 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/MetricalIndexTree.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/MetricalIndexTree.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.metrical;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2011
+ Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/AbstractMTree.java b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/AbstractMTree.java
index db4b5c07..5e949e0b 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/AbstractMTree.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/AbstractMTree.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2011
+ Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/AbstractMTreeFactory.java b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/AbstractMTreeFactory.java
index a7d701fa..9ae50bbe 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/AbstractMTreeFactory.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/AbstractMTreeFactory.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2011
+ Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/AbstractMTreeNode.java b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/AbstractMTreeNode.java
index 3fec4706..85a9571d 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/AbstractMTreeNode.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/AbstractMTreeNode.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2011
+ Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/MTreeDirectoryEntry.java b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/MTreeDirectoryEntry.java
index 5729115a..0b07c446 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/MTreeDirectoryEntry.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/MTreeDirectoryEntry.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2011
+ Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/MTreeEntry.java b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/MTreeEntry.java
index 0683a061..f6969b92 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/MTreeEntry.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/MTreeEntry.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2011
+ Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/MTreeLeafEntry.java b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/MTreeLeafEntry.java
index aae51378..27fbc1ba 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/MTreeLeafEntry.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/MTreeLeafEntry.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2011
+ Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/AbstractMkTree.java b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/AbstractMkTree.java
index 00cf45a7..ffd38a74 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/AbstractMkTree.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/AbstractMkTree.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.mktrees;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2011
+ Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/AbstractMkTreeUnified.java b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/AbstractMkTreeUnified.java
index f7135682..88013000 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/AbstractMkTreeUnified.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/AbstractMkTreeUnified.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.mktrees;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2011
+ Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/AbstractMkTreeUnifiedFactory.java b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/AbstractMkTreeUnifiedFactory.java
index dd1648a0..51df5077 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/AbstractMkTreeUnifiedFactory.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/AbstractMkTreeUnifiedFactory.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.mktrees;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2011
+ Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/MkTreeHeader.java b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/MkTreeHeader.java
index 809bc72b..c067a86c 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/MkTreeHeader.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/MkTreeHeader.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.mktrees;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2011
+ Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkapp/MkAppDirectoryEntry.java b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkapp/MkAppDirectoryEntry.java
index 39d420ba..ce7cf104 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkapp/MkAppDirectoryEntry.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkapp/MkAppDirectoryEntry.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.mktrees.mkapp;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2011
+ Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkapp/MkAppEntry.java b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkapp/MkAppEntry.java
index ef50e3bc..b6eabf7e 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkapp/MkAppEntry.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkapp/MkAppEntry.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.mktrees.mkapp;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2011
+ Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkapp/MkAppLeafEntry.java b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkapp/MkAppLeafEntry.java
index 961cdd92..4dbf0244 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkapp/MkAppLeafEntry.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkapp/MkAppLeafEntry.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.mktrees.mkapp;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2011
+ Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkapp/MkAppTree.java b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkapp/MkAppTree.java
index c0fe4523..5f92ba70 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkapp/MkAppTree.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkapp/MkAppTree.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.mktrees.mkapp;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2011
+ Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkapp/MkAppTreeFactory.java b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkapp/MkAppTreeFactory.java
index 540182e8..233129b4 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkapp/MkAppTreeFactory.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkapp/MkAppTreeFactory.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.mktrees.mkapp;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2011
+ Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkapp/MkAppTreeIndex.java b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkapp/MkAppTreeIndex.java
index cd7042d6..eedc52ed 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkapp/MkAppTreeIndex.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkapp/MkAppTreeIndex.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.mktrees.mkapp;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2011
+ Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkapp/MkAppTreeNode.java b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkapp/MkAppTreeNode.java
index cd1a1c3b..bc6a83a9 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkapp/MkAppTreeNode.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkapp/MkAppTreeNode.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.mktrees.mkapp;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2011
+ Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkapp/PolynomialApproximation.java b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkapp/PolynomialApproximation.java
index d32c1c0c..83e60e0e 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkapp/PolynomialApproximation.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkapp/PolynomialApproximation.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.mktrees.mkapp;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2011
+ Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkapp/package-info.java b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkapp/package-info.java
index 674ac861..0f3cfde9 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkapp/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkapp/package-info.java
@@ -5,7 +5,7 @@
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
-Copyright (C) 2011
+Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkcop/ApproximationLine.java b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkcop/ApproximationLine.java
index 0e7ccaf7..7f2aa3fe 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkcop/ApproximationLine.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkcop/ApproximationLine.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.mktrees.mkcop;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2011
+ Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkcop/ConvexHull.java b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkcop/ConvexHull.java
index 7924c13d..7cb5a16b 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkcop/ConvexHull.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkcop/ConvexHull.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.mktrees.mkcop;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2011
+ Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkcop/MkCoPDirectoryEntry.java b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkcop/MkCoPDirectoryEntry.java
index dd267d95..22b4efa4 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkcop/MkCoPDirectoryEntry.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkcop/MkCoPDirectoryEntry.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.mktrees.mkcop;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2011
+ Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkcop/MkCoPEntry.java b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkcop/MkCoPEntry.java
index cd1155c3..077fb1ec 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkcop/MkCoPEntry.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkcop/MkCoPEntry.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.mktrees.mkcop;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2011
+ Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkcop/MkCoPLeafEntry.java b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkcop/MkCoPLeafEntry.java
index 9f4da83f..0daf7950 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkcop/MkCoPLeafEntry.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkcop/MkCoPLeafEntry.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.mktrees.mkcop;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2011
+ Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkcop/MkCoPTree.java b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkcop/MkCoPTree.java
index a2f684ad..7fe67a03 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkcop/MkCoPTree.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkcop/MkCoPTree.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.mktrees.mkcop;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2011
+ Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkcop/MkCoPTreeIndex.java b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkcop/MkCoPTreeIndex.java
index d920cdab..2c4ffb06 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkcop/MkCoPTreeIndex.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkcop/MkCoPTreeIndex.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.mktrees.mkcop;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2011
+ Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkcop/MkCoPTreeNode.java b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkcop/MkCoPTreeNode.java
index 3fafb5fc..01fca2f2 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkcop/MkCoPTreeNode.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkcop/MkCoPTreeNode.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.mktrees.mkcop;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2011
+ Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkcop/MkCopTreeFactory.java b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkcop/MkCopTreeFactory.java
index 67968259..8d88ee79 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkcop/MkCopTreeFactory.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkcop/MkCopTreeFactory.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.mktrees.mkcop;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2011
+ Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkcop/package-info.java b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkcop/package-info.java
index 3679e608..516af071 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkcop/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkcop/package-info.java
@@ -5,7 +5,7 @@
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
-Copyright (C) 2011
+Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkmax/MkMaxDirectoryEntry.java b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkmax/MkMaxDirectoryEntry.java
index 0de76f2f..0781dcb1 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkmax/MkMaxDirectoryEntry.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkmax/MkMaxDirectoryEntry.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.mktrees.mkmax;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2011
+ Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkmax/MkMaxEntry.java b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkmax/MkMaxEntry.java
index 141037c7..0a7032f3 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkmax/MkMaxEntry.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkmax/MkMaxEntry.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.mktrees.mkmax;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2011
+ Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkmax/MkMaxLeafEntry.java b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkmax/MkMaxLeafEntry.java
index 0a8ee091..29221fdc 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkmax/MkMaxLeafEntry.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkmax/MkMaxLeafEntry.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.mktrees.mkmax;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2011
+ Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkmax/MkMaxTree.java b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkmax/MkMaxTree.java
index 0e637c57..5b7dc8fc 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkmax/MkMaxTree.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkmax/MkMaxTree.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.mktrees.mkmax;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2011
+ Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkmax/MkMaxTreeFactory.java b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkmax/MkMaxTreeFactory.java
index ba630c4e..7e9a7753 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkmax/MkMaxTreeFactory.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkmax/MkMaxTreeFactory.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.mktrees.mkmax;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2011
+ Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkmax/MkMaxTreeIndex.java b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkmax/MkMaxTreeIndex.java
index e3aed27e..9e1b6d6b 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkmax/MkMaxTreeIndex.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkmax/MkMaxTreeIndex.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.mktrees.mkmax;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2011
+ Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkmax/MkMaxTreeNode.java b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkmax/MkMaxTreeNode.java
index 345829f1..17f85498 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkmax/MkMaxTreeNode.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkmax/MkMaxTreeNode.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.mktrees.mkmax;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2011
+ Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkmax/package-info.java b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkmax/package-info.java
index 4ea34e49..bcde11b4 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkmax/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkmax/package-info.java
@@ -5,7 +5,7 @@
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
-Copyright (C) 2011
+Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mktab/MkTabDirectoryEntry.java b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mktab/MkTabDirectoryEntry.java
index cc431b1e..f8410ad9 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mktab/MkTabDirectoryEntry.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mktab/MkTabDirectoryEntry.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.mktrees.mktab;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2011
+ Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mktab/MkTabEntry.java b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mktab/MkTabEntry.java
index dfecc0d8..88000f5d 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mktab/MkTabEntry.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mktab/MkTabEntry.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.mktrees.mktab;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2011
+ Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mktab/MkTabLeafEntry.java b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mktab/MkTabLeafEntry.java
index ad3e999f..81446718 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mktab/MkTabLeafEntry.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mktab/MkTabLeafEntry.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.mktrees.mktab;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2011
+ Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mktab/MkTabTree.java b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mktab/MkTabTree.java
index 0014593c..750dfb72 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mktab/MkTabTree.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mktab/MkTabTree.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.mktrees.mktab;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2011
+ Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mktab/MkTabTreeFactory.java b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mktab/MkTabTreeFactory.java
index ea4fbd36..2bc6c256 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mktab/MkTabTreeFactory.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mktab/MkTabTreeFactory.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.mktrees.mktab;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2011
+ Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mktab/MkTabTreeIndex.java b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mktab/MkTabTreeIndex.java
index dc59b7cc..0eb54bd1 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mktab/MkTabTreeIndex.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mktab/MkTabTreeIndex.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.mktrees.mktab;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2011
+ Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
@@ -29,9 +29,10 @@ import java.util.List;
import de.lmu.ifi.dbs.elki.database.ids.DBID;
import de.lmu.ifi.dbs.elki.database.ids.DBIDs;
import de.lmu.ifi.dbs.elki.database.query.DatabaseQuery;
-import de.lmu.ifi.dbs.elki.database.query.DistanceResultPair;
import de.lmu.ifi.dbs.elki.database.query.distance.DistanceQuery;
import de.lmu.ifi.dbs.elki.database.query.knn.KNNQuery;
+import de.lmu.ifi.dbs.elki.database.query.knn.KNNResult;
+import de.lmu.ifi.dbs.elki.database.query.knn.KNNUtil;
import de.lmu.ifi.dbs.elki.database.query.range.RangeQuery;
import de.lmu.ifi.dbs.elki.database.query.rknn.RKNNQuery;
import de.lmu.ifi.dbs.elki.database.relation.Relation;
@@ -46,7 +47,6 @@ import de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.query.MetricalIndex
import de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.query.MetricalIndexRangeQuery;
import de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.query.MkTreeRKNNQuery;
import de.lmu.ifi.dbs.elki.persistent.PageFile;
-import de.lmu.ifi.dbs.elki.utilities.datastructures.heap.KNNList;
import de.lmu.ifi.dbs.elki.utilities.exceptions.ExceptionMessages;
/**
@@ -103,8 +103,8 @@ public class MkTabTreeIndex<O, D extends Distance<D>> extends MkTabTree<O, D> im
* @return the knn distance of the object with the specified id
*/
private List<D> knnDistances(O object) {
- List<DistanceResultPair<D>> knns = knnQuery.getKNNForObject(object, getKmax() - 1);
- return KNNList.asDistanceList(knns);
+ KNNResult<D> knns = knnQuery.getKNNForObject(object, getKmax() - 1);
+ return KNNUtil.asDistanceList(knns);
}
@Override
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mktab/MkTabTreeNode.java b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mktab/MkTabTreeNode.java
index 55dfcbde..b09ac314 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mktab/MkTabTreeNode.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mktab/MkTabTreeNode.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.mktrees.mktab;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2011
+ Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mktab/package-info.java b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mktab/package-info.java
index f03cf84a..353acaa5 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mktab/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mktab/package-info.java
@@ -5,7 +5,7 @@
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
-Copyright (C) 2011
+Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/package-info.java b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/package-info.java
index 4fbf50bb..201d57c3 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/package-info.java
@@ -7,7 +7,7 @@
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
-Copyright (C) 2011
+Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mtree/MTree.java b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mtree/MTree.java
index 4e9b4f9e..80955b8a 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mtree/MTree.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mtree/MTree.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.mtree;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2011
+ Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mtree/MTreeFactory.java b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mtree/MTreeFactory.java
index 190a009d..2567f81f 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mtree/MTreeFactory.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mtree/MTreeFactory.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.mtree;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2011
+ Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mtree/MTreeIndex.java b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mtree/MTreeIndex.java
index 2a6d8a91..9bcd1b02 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mtree/MTreeIndex.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mtree/MTreeIndex.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.mtree;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2011
+ Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mtree/MTreeNode.java b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mtree/MTreeNode.java
index 26c2ae00..017e7d6c 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mtree/MTreeNode.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mtree/MTreeNode.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.mtree;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2011
+ Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mtree/package-info.java b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mtree/package-info.java
index 4233b17b..a34162a8 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mtree/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mtree/package-info.java
@@ -5,7 +5,7 @@
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
-Copyright (C) 2011
+Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/package-info.java b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/package-info.java
index 27fc5a22..b30d1193 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/package-info.java
@@ -5,7 +5,7 @@
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
-Copyright (C) 2011
+Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
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 ab99bdd9..b591f700 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) 2011
+ Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
@@ -28,9 +28,9 @@ import java.util.Map;
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.query.DistanceResultPair;
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.database.query.knn.KNNResult;
import de.lmu.ifi.dbs.elki.distance.DistanceUtil;
import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
import de.lmu.ifi.dbs.elki.index.tree.DirectoryEntry;
@@ -82,7 +82,7 @@ public class MetricalIndexKNNQuery<O, D extends Distance<D>> extends AbstractDis
final Heap<GenericMTreeDistanceSearchCandidate<D>> pq = new UpdatableHeap<GenericMTreeDistanceSearchCandidate<D>>();
// push root
- pq.add(new GenericMTreeDistanceSearchCandidate<D>(getDistanceFactory().nullDistance(), index.getRootID(), null));
+ pq.add(new GenericMTreeDistanceSearchCandidate<D>(distanceQuery.nullDistance(), index.getRootID(), null));
D d_k = knnList.getKNNDistance();
// search in tree
@@ -102,8 +102,8 @@ public class MetricalIndexKNNQuery<O, D extends Distance<D>> extends AbstractDis
MTreeEntry<D> entry = node.getEntry(i);
DBID o_r = entry.getRoutingObjectID();
D r_or = entry.getCoveringRadius();
- D d1 = o_p != null ? distanceQuery.distance(o_p, q) : getDistanceFactory().nullDistance();
- D d2 = o_p != null ? distanceQuery.distance(o_r, o_p) : getDistanceFactory().nullDistance();
+ D d1 = o_p != null ? distanceQuery.distance(o_p, q) : distanceQuery.nullDistance();
+ D d2 = o_p != null ? distanceQuery.distance(o_r, o_p) : distanceQuery.nullDistance();
D diff = d1.compareTo(d2) > 0 ? d1.minus(d2) : d2.minus(d1);
@@ -111,7 +111,7 @@ public class MetricalIndexKNNQuery<O, D extends Distance<D>> extends AbstractDis
if(diff.compareTo(sum) <= 0) {
D d3 = distanceQuery.distance(o_r, q);
- D d_min = DistanceUtil.max(d3.minus(r_or), getDistanceFactory().nullDistance());
+ D d_min = DistanceUtil.max(d3.minus(r_or), distanceQuery.nullDistance());
if(d_min.compareTo(d_k) <= 0) {
pq.add(new GenericMTreeDistanceSearchCandidate<D>(d_min, ((DirectoryEntry)entry).getPageID(), o_r));
}
@@ -126,8 +126,8 @@ public class MetricalIndexKNNQuery<O, D extends Distance<D>> extends AbstractDis
MTreeEntry<D> entry = node.getEntry(i);
DBID o_j = entry.getRoutingObjectID();
- D d1 = o_p != null ? distanceQuery.distance(o_p, q) : getDistanceFactory().nullDistance();
- D d2 = o_p != null ? distanceQuery.distance(o_j, o_p) : getDistanceFactory().nullDistance();
+ D d1 = o_p != null ? distanceQuery.distance(o_p, q) : distanceQuery.nullDistance();
+ D d2 = o_p != null ? distanceQuery.distance(o_j, o_p) : distanceQuery.nullDistance();
D diff = d1.compareTo(d2) > 0 ? d1.minus(d2) : d2.minus(d1);
@@ -144,23 +144,23 @@ public class MetricalIndexKNNQuery<O, D extends Distance<D>> extends AbstractDis
}
@Override
- public List<DistanceResultPair<D>> getKNNForObject(O obj, int k) {
+ public KNNResult<D> getKNNForObject(O obj, int k) {
if(k < 1) {
throw new IllegalArgumentException("At least one object has to be requested!");
}
final KNNHeap<D> knnList = new KNNHeap<D>(k, distanceQuery.getDistanceFactory().infiniteDistance());
doKNNQuery(obj, knnList);
- return knnList.toSortedArrayList();
+ return knnList.toKNNList();
}
@Override
- public List<DistanceResultPair<D>> getKNNForDBID(DBID id, int k) {
+ public KNNResult<D> getKNNForDBID(DBID id, int k) {
return getKNNForObject(relation.get(id), k);
}
@Override
- public List<List<DistanceResultPair<D>>> getKNNForBulkDBIDs(ArrayDBIDs ids, int k) {
+ public List<KNNResult<D>> getKNNForBulkDBIDs(ArrayDBIDs ids, int k) {
// TODO: implement
throw new UnsupportedOperationException(ExceptionMessages.UNSUPPORTED_NOT_YET);
}
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/query/MetricalIndexRangeQuery.java b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/query/MetricalIndexRangeQuery.java
index 5854df8a..8536cc52 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/query/MetricalIndexRangeQuery.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/query/MetricalIndexRangeQuery.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) 2011
+ Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
@@ -80,8 +80,8 @@ public class MetricalIndexRangeQuery<O, D extends Distance<D>> extends AbstractD
DBID o_r = entry.getRoutingObjectID();
D r_or = entry.getCoveringRadius();
- D d1 = o_p != null ? distanceQuery.distance(o_p, q) : getDistanceFactory().nullDistance();
- D d2 = o_p != null ? entry.getParentDistance() : getDistanceFactory().nullDistance();
+ D d1 = o_p != null ? distanceQuery.distance(o_p, q) : distanceQuery.nullDistance();
+ D d2 = o_p != null ? entry.getParentDistance() : distanceQuery.nullDistance();
// o_p != null ? distanceFunction.distance(o_r, o_p) :/ distanceFunction.nullDistance();
D diff = d1.compareTo(d2) > 0 ? d1.minus(d2) : d2.minus(d1);
@@ -104,8 +104,8 @@ public class MetricalIndexRangeQuery<O, D extends Distance<D>> extends AbstractD
MTreeEntry<D> entry = node.getEntry(i);
DBID o_j = entry.getRoutingObjectID();
- D d1 = o_p != null ? distanceQuery.distance(o_p, q) : getDistanceFactory().nullDistance();
- D d2 = o_p != null ? distanceQuery.distance(o_j, o_p) : getDistanceFactory().nullDistance();
+ D d1 = o_p != null ? distanceQuery.distance(o_p, q) : distanceQuery.nullDistance();
+ D d2 = o_p != null ? distanceQuery.distance(o_j, o_p) : distanceQuery.nullDistance();
D diff = d1.compareTo(d2) > 0 ? d1.minus(d2) : d2.minus(d1);
@@ -138,8 +138,8 @@ public class MetricalIndexRangeQuery<O, D extends Distance<D>> extends AbstractD
DBID o_r = entry.getRoutingObjectID();
D r_or = entry.getCoveringRadius();
- D d1 = o_p != null ? distanceQuery.distance(o_p, q) : getDistanceFactory().nullDistance();
- D d2 = o_p != null ? entry.getParentDistance() : getDistanceFactory().nullDistance();
+ D d1 = o_p != null ? distanceQuery.distance(o_p, q) : distanceQuery.nullDistance();
+ D d2 = o_p != null ? entry.getParentDistance() : distanceQuery.nullDistance();
// o_p != null ? distanceFunction.distance(o_r, o_p) : distanceFunction.nullDistance();
D diff = d1.compareTo(d2) > 0 ? d1.minus(d2) : d2.minus(d1);
@@ -160,8 +160,8 @@ public class MetricalIndexRangeQuery<O, D extends Distance<D>> extends AbstractD
MTreeEntry<D> entry = node.getEntry(i);
DBID o_j = entry.getRoutingObjectID();
- D d1 = o_p != null ? distanceQuery.distance(o_p, q) : getDistanceFactory().nullDistance();
- D d2 = o_p != null ? distanceQuery.distance(o_j, o_p) : getDistanceFactory().nullDistance();
+ D d1 = o_p != null ? distanceQuery.distance(o_p, q) : distanceQuery.nullDistance();
+ D d2 = o_p != null ? distanceQuery.distance(o_j, o_p) : distanceQuery.nullDistance();
D diff = d1.compareTo(d2) > 0 ? d1.minus(d2) : d2.minus(d1);
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/query/MkTreeRKNNQuery.java b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/query/MkTreeRKNNQuery.java
index 38641128..370f26ad 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/query/MkTreeRKNNQuery.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/query/MkTreeRKNNQuery.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) 2011
+ Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/query/package-info.java b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/query/package-info.java
index 9fa70aab..fa7e6248 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/query/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/query/package-info.java
@@ -6,7 +6,7 @@
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
-Copyright (C) 2011
+Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/split/Assignments.java b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/split/Assignments.java
index c639f37e..5cb6c794 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/split/Assignments.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/split/Assignments.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.split;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2011
+ Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/split/MLBDistSplit.java b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/split/MLBDistSplit.java
index dc322960..f4da4a1a 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/split/MLBDistSplit.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/split/MLBDistSplit.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.split;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2011
+ Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/split/MRadSplit.java b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/split/MRadSplit.java
index c78367ed..5d6c985c 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/split/MRadSplit.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/split/MRadSplit.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.split;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2011
+ Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/split/MTreeSplit.java b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/split/MTreeSplit.java
index a5fcb349..f9a3c248 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/split/MTreeSplit.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/split/MTreeSplit.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.split;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2011
+ Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/split/package-info.java b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/split/package-info.java
index 66ead37c..ed13ae73 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/split/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/split/package-info.java
@@ -5,7 +5,7 @@
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
-Copyright (C) 2011
+Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/package-info.java b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/package-info.java
index bcfbd4a1..2ca4396c 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/package-info.java
@@ -5,7 +5,7 @@
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
-Copyright (C) 2011
+Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/package-info.java b/src/de/lmu/ifi/dbs/elki/index/tree/package-info.java
index 40adc7c4..3ba785f2 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/package-info.java
@@ -5,7 +5,7 @@
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
-Copyright (C) 2011
+Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/query/DoubleDistanceSearchCandidate.java b/src/de/lmu/ifi/dbs/elki/index/tree/query/DoubleDistanceSearchCandidate.java
index 7b1b4a03..699c8290 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/query/DoubleDistanceSearchCandidate.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/query/DoubleDistanceSearchCandidate.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.query;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2011
+ Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/query/GenericDistanceSearchCandidate.java b/src/de/lmu/ifi/dbs/elki/index/tree/query/GenericDistanceSearchCandidate.java
index 7338bdd1..dd764990 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/query/GenericDistanceSearchCandidate.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/query/GenericDistanceSearchCandidate.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.query;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2011
+ Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/query/GenericMTreeDistanceSearchCandidate.java b/src/de/lmu/ifi/dbs/elki/index/tree/query/GenericMTreeDistanceSearchCandidate.java
index b9d8ef46..e7fc0b19 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/query/GenericMTreeDistanceSearchCandidate.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/query/GenericMTreeDistanceSearchCandidate.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.query;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2011
+ Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/query/package-info.java b/src/de/lmu/ifi/dbs/elki/index/tree/query/package-info.java
index 2eb1d284..5b8f56f6 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/query/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/query/package-info.java
@@ -5,7 +5,7 @@
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
-Copyright (C) 2011
+Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/SpatialDirectoryEntry.java b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/SpatialDirectoryEntry.java
index cf83a1a2..9833e5b5 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/SpatialDirectoryEntry.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/SpatialDirectoryEntry.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.spatial;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2011
+ Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
@@ -27,7 +27,8 @@ import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
-import de.lmu.ifi.dbs.elki.data.HyperBoundingBox;
+import de.lmu.ifi.dbs.elki.data.ModifiableHyperBoundingBox;
+import de.lmu.ifi.dbs.elki.data.spatial.SpatialComparable;
import de.lmu.ifi.dbs.elki.index.tree.AbstractDirectoryEntry;
/**
@@ -45,7 +46,7 @@ public class SpatialDirectoryEntry extends AbstractDirectoryEntry implements Spa
/**
* The minimum bounding rectangle of the underlying spatial node.
*/
- private HyperBoundingBox mbr;
+ private ModifiableHyperBoundingBox mbr;
/**
* Empty constructor for serialization purposes.
@@ -60,7 +61,7 @@ public class SpatialDirectoryEntry extends AbstractDirectoryEntry implements Spa
* @param id the unique id of the underlying spatial node
* @param mbr the minimum bounding rectangle of the underlying spatial node
*/
- public SpatialDirectoryEntry(int id, HyperBoundingBox mbr) {
+ public SpatialDirectoryEntry(int id, ModifiableHyperBoundingBox mbr) {
super(id);
this.mbr = mbr;
}
@@ -89,11 +90,20 @@ public class SpatialDirectoryEntry extends AbstractDirectoryEntry implements Spa
}
/**
+ * Test whether this entry already has an MBR.
+ *
+ * @return True when an MBR exists.
+ */
+ public boolean hasMBR() {
+ return (this.mbr != null);
+ }
+
+ /**
* Sets the MBR of this entry.
*
* @param mbr the MBR to be set
*/
- public void setMBR(HyperBoundingBox mbr) {
+ public void setMBR(ModifiableHyperBoundingBox mbr) {
this.mbr = mbr;
}
@@ -122,7 +132,17 @@ public class SpatialDirectoryEntry extends AbstractDirectoryEntry implements Spa
@Override
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
super.readExternal(in);
- this.mbr = new HyperBoundingBox();
+ this.mbr = new ModifiableHyperBoundingBox();
this.mbr.readExternal(in);
}
-}
+
+ /**
+ * Extend the MBR of this node.
+ *
+ * @param responsibleMBR
+ * @return true when the MBR changed
+ */
+ public boolean extendMBR(SpatialComparable responsibleMBR) {
+ return this.mbr.extend(responsibleMBR);
+ }
+} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/SpatialEntry.java b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/SpatialEntry.java
index ffc96b40..c50a5ebf 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/SpatialEntry.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/SpatialEntry.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.spatial;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2011
+ Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/SpatialIndexTree.java b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/SpatialIndexTree.java
index 1d0094dd..3b9eaa6b 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/SpatialIndexTree.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/SpatialIndexTree.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.spatial;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2011
+ Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/SpatialNode.java b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/SpatialNode.java
index 2d0dd857..8bf25766 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/SpatialNode.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/SpatialNode.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.spatial;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2011
+ Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
@@ -23,7 +23,6 @@ package de.lmu.ifi.dbs.elki.index.tree.spatial;
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-import de.lmu.ifi.dbs.elki.data.spatial.SpatialComparable;
import de.lmu.ifi.dbs.elki.index.tree.Node;
/**
@@ -38,6 +37,6 @@ import de.lmu.ifi.dbs.elki.index.tree.Node;
* @param <N> Self reference
* @param <E> Entry type
*/
-public interface SpatialNode<N extends SpatialNode<N, E>, E extends SpatialEntry> extends Node<E>, SpatialComparable {
+public interface SpatialNode<N extends SpatialNode<N, E>, E extends SpatialEntry> extends Node<E> {
// No additional methods.
-}
+} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/SpatialPair.java b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/SpatialPair.java
index 57fb6932..f29680e7 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/SpatialPair.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/SpatialPair.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.spatial;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2011
+ Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/SpatialPointLeafEntry.java b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/SpatialPointLeafEntry.java
index c3cd20d3..0911a9c0 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/SpatialPointLeafEntry.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/SpatialPointLeafEntry.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.spatial;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2011
+ Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/package-info.java b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/package-info.java
index f7a747fe..fb5c67ee 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/package-info.java
@@ -5,7 +5,7 @@
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
-Copyright (C) 2011
+Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/AbstractRStarTree.java b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/AbstractRStarTree.java
index 4fafe1bb..e50e0cb4 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/AbstractRStarTree.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/AbstractRStarTree.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2011
+ Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
@@ -27,22 +27,17 @@ import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashMap;
+import java.util.BitSet;
import java.util.List;
-import java.util.Map;
import java.util.Stack;
import de.lmu.ifi.dbs.elki.data.HyperBoundingBox;
+import de.lmu.ifi.dbs.elki.data.ModifiableHyperBoundingBox;
import de.lmu.ifi.dbs.elki.data.spatial.SpatialComparable;
import de.lmu.ifi.dbs.elki.data.spatial.SpatialUtil;
import de.lmu.ifi.dbs.elki.database.ids.DBID;
import de.lmu.ifi.dbs.elki.database.ids.DBIDUtil;
-import de.lmu.ifi.dbs.elki.distance.distancefunction.EuclideanDistanceFunction;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance;
import de.lmu.ifi.dbs.elki.index.tree.BreadthFirstEnumeration;
-import de.lmu.ifi.dbs.elki.index.tree.DistanceEntry;
import de.lmu.ifi.dbs.elki.index.tree.IndexTreePath;
import de.lmu.ifi.dbs.elki.index.tree.LeafEntry;
import de.lmu.ifi.dbs.elki.index.tree.TreeIndexHeader;
@@ -51,16 +46,17 @@ import de.lmu.ifi.dbs.elki.index.tree.spatial.SpatialDirectoryEntry;
import de.lmu.ifi.dbs.elki.index.tree.spatial.SpatialEntry;
import de.lmu.ifi.dbs.elki.index.tree.spatial.SpatialIndexTree;
import de.lmu.ifi.dbs.elki.index.tree.spatial.SpatialPointLeafEntry;
-import de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.bulk.BulkSplit;
-import de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.util.Enlargement;
-import de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.util.InsertionStrategy;
-import de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.util.LeastOverlapInsertionStrategy;
-import de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.util.SplitStrategy;
-import de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.util.TopologicalSplitter;
+import de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.strategies.bulk.BulkSplit;
+import de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.strategies.insert.InsertionStrategy;
+import de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.strategies.insert.LeastOverlapInsertionStrategy;
+import de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.strategies.overflow.LimitedReinsertOverflowTreatment;
+import de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.strategies.overflow.OverflowTreatment;
+import de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.strategies.split.SplitStrategy;
+import de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.strategies.split.TopologicalSplitter;
+import de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.util.NodeArrayAdapter;
import de.lmu.ifi.dbs.elki.persistent.PageFile;
import de.lmu.ifi.dbs.elki.persistent.PageFileUtil;
import de.lmu.ifi.dbs.elki.utilities.exceptions.AbortException;
-import de.lmu.ifi.dbs.elki.utilities.pairs.Pair;
/**
* Abstract superclass for index structures based on a R*-Tree.
@@ -87,13 +83,6 @@ public abstract class AbstractRStarTree<N extends AbstractRStarTreeNode<N, E>, E
protected final static boolean extraIntegrityChecks = false;
/**
- * Contains a boolean for each level of this R*-Tree that indicates if there
- * was already a reinsert operation in this level during the current insert /
- * delete operation.
- */
- protected final Map<Integer, Boolean> reinsertions = new HashMap<Integer, Boolean>();
-
- /**
* The height of this R*-Tree.
*/
protected int height;
@@ -116,33 +105,88 @@ public abstract class AbstractRStarTree<N extends AbstractRStarTreeNode<N, E>, E
/**
* The split strategy
*/
- protected SplitStrategy<? super E> nodeSplitter = new TopologicalSplitter();
+ protected SplitStrategy nodeSplitter = TopologicalSplitter.STATIC;
/**
* The insertion strategy to use
*/
- protected final InsertionStrategy insertionStrategy;
+ protected InsertionStrategy insertionStrategy = LeastOverlapInsertionStrategy.STATIC;
+
+ /**
+ * Overflow treatment
+ */
+ protected OverflowTreatment overflowTreatment = LimitedReinsertOverflowTreatment.RSTAR_OVERFLOW;
+
+ /**
+ * Relative minimum fill
+ */
+ protected double relativeMinFill = 0.4;
/**
* Constructor
*
* @param pagefile Page file
- * @param bulkSplitter bulk load strategy
- * @param insertionStrategy the strategy for finding the insertion candidate.
*/
- public AbstractRStarTree(PageFile<N> pagefile, BulkSplit bulkSplitter, InsertionStrategy insertionStrategy) {
+ public AbstractRStarTree(PageFile<N> pagefile) {
super(pagefile);
+ }
+
+ /**
+ * Set the bulk loading strategy
+ *
+ * @param bulkSplitter Bulk loading strategy
+ */
+ public void setBulkStrategy(BulkSplit bulkSplitter) {
this.bulkSplitter = bulkSplitter;
+ }
+
+ /**
+ * Set the node splitting strategy.
+ *
+ * @param nodeSplitter the split strategy to set
+ */
+ public void setNodeSplitStrategy(SplitStrategy nodeSplitter) {
+ if(nodeSplitter != null) {
+ this.nodeSplitter = nodeSplitter;
+ }
+ else {
+ getLogger().warning("Ignoring setNodeSplitStrategy(null)");
+ }
+ }
+
+ /**
+ * Set insertion strategy
+ *
+ * @param insertionStrategy the insertion strategy to set
+ */
+ public void setInsertionStrategy(InsertionStrategy insertionStrategy) {
if(insertionStrategy != null) {
this.insertionStrategy = insertionStrategy;
}
else {
- getLogger().warning("No insertion strategy given - falling back to " + LeastOverlapInsertionStrategy.class.getSimpleName());
- this.insertionStrategy = new LeastOverlapInsertionStrategy();
+ getLogger().warning("Ignoring setInsertionStrategy(null)");
}
}
/**
+ * Set the overflow treatment strategy.
+ *
+ * @param overflowTreatment overflow treatment strategy
+ */
+ public void setOverflowTreatment(OverflowTreatment overflowTreatment) {
+ this.overflowTreatment = overflowTreatment;
+ }
+
+ /**
+ * Set the relative minimum fill. (Only supported before the tree was used!)
+ *
+ * @param relative Relative minimum fill
+ */
+ public void setMinimumFill(double relative) {
+ this.relativeMinFill = relative;
+ }
+
+ /**
* Returns the path to the leaf entry in the specified subtree that represents
* the data object with the specified mbr and id.
*
@@ -181,7 +225,7 @@ public abstract class AbstractRStarTree<N extends AbstractRStarTreeNode<N, E>, E
if(!initialized) {
initialize(leaf);
}
- reinsertions.clear();
+ overflowTreatment.reinitialize();
preInsert(leaf);
insertLeafEntry(leaf);
@@ -200,7 +244,7 @@ public abstract class AbstractRStarTree<N extends AbstractRStarTreeNode<N, E>, E
IndexTreePath<E> subtree = choosePath(getRootPath(), entry, 1);
if(getLogger().isDebugging()) {
- getLogger().debugFine("insertion-subtree " + subtree + "\n");
+ getLogger().debugFine("insertion-subtree " + subtree);
}
N parent = getNode(subtree.getLastPathComponent().getEntry());
@@ -257,7 +301,7 @@ public abstract class AbstractRStarTree<N extends AbstractRStarTreeNode<N, E>, E
N node = stack.pop();
if(node.isLeaf()) {
for(int i = 0; i < node.getNumEntries(); i++) {
- reinsertions.clear();
+ overflowTreatment.reinitialize(); // Intended?
this.insertLeafEntry(node.getEntry(i));
}
}
@@ -315,7 +359,7 @@ public abstract class AbstractRStarTree<N extends AbstractRStarTreeNode<N, E>, E
int cap = 0;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
- HyperBoundingBox hb = new HyperBoundingBox(new double[exampleLeaf.getDimensionality()], new double[exampleLeaf.getDimensionality()]);
+ ModifiableHyperBoundingBox hb = new ModifiableHyperBoundingBox(new double[exampleLeaf.getDimensionality()], new double[exampleLeaf.getDimensionality()]);
SpatialDirectoryEntry sl = new SpatialDirectoryEntry(0, hb);
while(baos.size() <= getPageSize()) {
sl.writeExternal(oos);
@@ -337,7 +381,7 @@ public abstract class AbstractRStarTree<N extends AbstractRStarTreeNode<N, E>, E
}
// minimum entries per directory node
- dirMinimum = (int) Math.round((dirCapacity - 1) * 0.4);
+ dirMinimum = (int) Math.round((dirCapacity - 1) * relativeMinFill);
if(dirMinimum < 2) {
dirMinimum = 2;
}
@@ -351,7 +395,7 @@ public abstract class AbstractRStarTree<N extends AbstractRStarTreeNode<N, E>, E
}
// minimum entries per leaf node
- leafMinimum = (int) Math.round((leafCapacity - 1) * 0.4);
+ leafMinimum = (int) Math.round((leafCapacity - 1) * relativeMinFill);
if(leafMinimum < 2) {
leafMinimum = 2;
}
@@ -376,33 +420,31 @@ public abstract class AbstractRStarTree<N extends AbstractRStarTreeNode<N, E>, E
* @param objects the objects to be inserted
* @return the array of leaf nodes containing the objects
*/
- protected List<N> createBulkLeafNodes(List<E> objects) {
+ protected List<E> createBulkLeafNodes(List<E> objects) {
int minEntries = leafMinimum;
int maxEntries = leafCapacity - 1;
-
- ArrayList<N> result = new ArrayList<N>();
+
+ ArrayList<E> result = new ArrayList<E>();
List<List<E>> partitions = bulkSplitter.partition(objects, minEntries, maxEntries);
-
+
for(List<E> partition : partitions) {
// create leaf node
N leafNode = createNewLeafNode();
- result.add(leafNode);
-
+
// insert data
for(E o : partition) {
leafNode.addLeafEntry(o);
}
-
// write to file
writeNode(leafNode);
-
+
+ result.add(createNewDirectoryEntry(leafNode));
+
if(getLogger().isDebugging()) {
- StringBuffer msg = new StringBuffer();
- msg.append("pageNo ").append(leafNode.getPageID()).append("\n");
- getLogger().debugFine(msg.toString());
+ getLogger().debugFine("Created leaf page "+leafNode.getPageID());
}
}
-
+
if(getLogger().isDebugging()) {
getLogger().debugFine("numDataPages = " + result.size());
}
@@ -441,13 +483,6 @@ public abstract class AbstractRStarTree<N extends AbstractRStarTreeNode<N, E>, E
abstract protected int computeHeight();
/**
- * Clears the reinsertions.
- */
- protected void clearReinsertions() {
- reinsertions.clear();
- }
-
- /**
* Returns true if in the specified node an overflow occurred, false
* otherwise.
*
@@ -486,7 +521,7 @@ public abstract class AbstractRStarTree<N extends AbstractRStarTreeNode<N, E>, E
protected IndexTreePath<E> createNewRoot(final N oldRoot, final N newNode) {
N root = createNewDirectoryNode();
writeNode(root);
-
+
// switch the ids
oldRoot.setPageID(root.getPageID());
if(!oldRoot.isLeaf()) {
@@ -495,24 +530,24 @@ public abstract class AbstractRStarTree<N extends AbstractRStarTreeNode<N, E>, E
writeNode(node);
}
}
-
+
root.setPageID(getRootID());
E oldRootEntry = createNewDirectoryEntry(oldRoot);
E newNodeEntry = createNewDirectoryEntry(newNode);
root.addDirectoryEntry(oldRootEntry);
root.addDirectoryEntry(newNodeEntry);
-
+
writeNode(root);
writeNode(oldRoot);
writeNode(newNode);
if(getLogger().isDebugging()) {
String msg = "Create new Root: ID=" + root.getPageID();
- msg += "\nchild1 " + oldRoot + " " + new HyperBoundingBox(oldRoot) + " " + new HyperBoundingBox(oldRootEntry);
- msg += "\nchild2 " + newNode + " " + new HyperBoundingBox(newNode) + " " + new HyperBoundingBox(newNodeEntry);
+ msg += "\nchild1 " + oldRoot + " " + new HyperBoundingBox(oldRootEntry);
+ msg += "\nchild2 " + newNode + " " + new HyperBoundingBox(newNodeEntry);
msg += "\n";
getLogger().debugFine(msg);
}
-
+
return new IndexTreePath<E>(new TreeIndexPathComponent<E>(getRootEntry(), null));
}
@@ -591,10 +626,11 @@ public abstract class AbstractRStarTree<N extends AbstractRStarTreeNode<N, E>, E
}
N childNode = getNode(node.getEntry(0));
+ int num = insertionStrategy.choose(node, NodeArrayAdapter.STATIC, mbr, height, subtree.getPathCount());
+ TreeIndexPathComponent<E> comp = new TreeIndexPathComponent<E>(node.getEntry(num), num);
// children are leafs
if(childNode.isLeaf()) {
if(height - subtree.getPathCount() == level) {
- TreeIndexPathComponent<E> comp = insertionStrategy.findInsertChild(node, mbr);
return subtree.pathByAddingChild(comp);
}
else {
@@ -603,7 +639,7 @@ public abstract class AbstractRStarTree<N extends AbstractRStarTreeNode<N, E>, E
}
// children are directory nodes
else {
- IndexTreePath<E> newSubtree = subtree.pathByAddingChild(getLeastEnlargement(node, mbr));
+ IndexTreePath<E> newSubtree = subtree.pathByAddingChild(comp);
// desired level is reached
if(height - subtree.getPathCount() == level) {
return newSubtree;
@@ -615,34 +651,6 @@ public abstract class AbstractRStarTree<N extends AbstractRStarTreeNode<N, E>, E
}
/**
- * Returns the path information of the entry of the specified node with the
- * least enlargement if the given mbr would be inserted into.
- *
- * @param node the node which children have to be tested
- * @param mbr the mbr of the node to be inserted
- * @return the path information of the entry with the least enlargement if the
- * given mbr would be inserted into
- */
- private TreeIndexPathComponent<E> getLeastEnlargement(N node, SpatialComparable mbr) {
- Enlargement<E> min = null;
-
- for(int i = 0; i < node.getNumEntries(); i++) {
- E entry = node.getEntry(i);
- double volume = SpatialUtil.volume(entry);
- HyperBoundingBox newMBR = SpatialUtil.union(entry, mbr);
- double inc = SpatialUtil.volume(newMBR) - volume;
- Enlargement<E> enlargement = new Enlargement<E>(new TreeIndexPathComponent<E>(entry, i), volume, inc, 0);
-
- if(min == null || min.compareTo(enlargement) > 0) {
- min = enlargement;
- }
- }
-
- assert min != null;
- return min.getPathComponent();
- }
-
- /**
* Treatment of overflow in the specified node: if the node is not the root
* node and this is the first call of overflowTreatment in the given level
* during insertion the specified node will be reinserted, otherwise the node
@@ -654,23 +662,10 @@ public abstract class AbstractRStarTree<N extends AbstractRStarTreeNode<N, E>, E
* reinsertion
*/
private N overflowTreatment(N node, IndexTreePath<E> path) {
- int level = height - path.getPathCount() + 1;
- Boolean reInsert = reinsertions.get(level);
-
- // there was still no reinsert operation at this level
- if(node.getPageID() != 0 && (reInsert == null || !reInsert)) {
- reinsertions.put(level, true);
- if(getLogger().isDebugging()) {
- getLogger().debugFine("REINSERT " + reinsertions + "\n");
- }
- reInsert(node, level, path);
+ if(overflowTreatment.handleOverflow(this, node, path)) {
return null;
}
-
- // there was already a reinsert operation at this level
- else {
- return split(node);
- }
+ return split(node);
}
/**
@@ -682,7 +677,7 @@ public abstract class AbstractRStarTree<N extends AbstractRStarTreeNode<N, E>, E
private N split(N node) {
// choose the split dimension and the split point
int minimum = node.isLeaf() ? leafMinimum : dirMinimum;
- Pair<List<E>, List<E>> split = nodeSplitter.split(node.getEntries(), minimum);
+ BitSet split = nodeSplitter.split(node, NodeArrayAdapter.STATIC, minimum);
// New node
final N newNode;
@@ -693,22 +688,12 @@ public abstract class AbstractRStarTree<N extends AbstractRStarTreeNode<N, E>, E
newNode = createNewDirectoryNode();
}
// do the split
- node.deleteAllEntries();
- node.splitTo(newNode, split.first, split.second);
+ node.splitByMask(newNode, split);
// write changes to file
writeNode(node);
writeNode(newNode);
- // if(getLogger().isDebugging()) {
- // StringBuffer msg = new StringBuffer();
- // msg.append("Split Node ").append(node.getPageID()).append(" (").append(getClass()).append(")\n");
- // msg.append(" splitAxis ").append(split.getSplitAxis()).append("\n");
- // msg.append(" splitPoint ").append(split.getSplitPoint()).append("\n");
- // msg.append(" newNode ").append(newNode.getPageID()).append("\n");
- // getLogger().debugFine(msg.toString());
- // }
-
return newNode;
}
@@ -716,29 +701,20 @@ public abstract class AbstractRStarTree<N extends AbstractRStarTreeNode<N, E>, E
* Reinserts the specified node at the specified level.
*
* @param node the node to be reinserted
- * @param level the level of the node
* @param path the path to the node
+ * @param offs the nodes indexes to reinsert
*/
- @SuppressWarnings("unchecked")
- protected void reInsert(N node, int level, IndexTreePath<E> path) {
- EuclideanDistanceFunction distFunction = EuclideanDistanceFunction.STATIC;
- DistanceEntry<DoubleDistance, E>[] reInsertEntries = new DistanceEntry[node.getNumEntries()];
+ public void reInsert(N node, IndexTreePath<E> path, int[] offs) {
+ final int level = height - (path.getPathCount() - 1);
- // compute the center distances of entries to the node and sort it
- // in decreasing order to their distances
- for(int i = 0; i < node.getNumEntries(); i++) {
- E entry = node.getEntry(i);
- DoubleDistance dist = distFunction.centerDistance(node, entry);
- reInsertEntries[i] = new DistanceEntry<DoubleDistance, E>(entry, dist, i);
+ BitSet remove = new BitSet();
+ List<E> reInsertEntries = new ArrayList<E>(offs.length);
+ for(int i = 0; i < offs.length; i++) {
+ reInsertEntries.add(node.getEntry(offs[i]));
+ remove.set(offs[i]);
}
- Arrays.sort(reInsertEntries, Collections.reverseOrder());
-
- // define, how many entries will be reinserted
- int start = (int) (0.3 * node.getNumEntries());
-
- // initialize the reinsertion operation: move the remaining entries
- // forward
- node.initReInsert(start, reInsertEntries);
+ // Remove the entries we reinsert
+ node.removeMask(remove);
writeNode(node);
// and adapt the mbrs
@@ -747,26 +723,30 @@ public abstract class AbstractRStarTree<N extends AbstractRStarTreeNode<N, E>, E
while(childPath.getParentPath() != null) {
N parent = getNode(childPath.getParentPath().getLastPathComponent().getEntry());
int indexOfChild = childPath.getLastPathComponent().getIndex();
- child.adjustEntry(parent.getEntry(indexOfChild));
- writeNode(parent);
- childPath = childPath.getParentPath();
- child = parent;
+ if(child.adjustEntry(parent.getEntry(indexOfChild))) {
+ writeNode(parent);
+ childPath = childPath.getParentPath();
+ child = parent;
+ }
+ else {
+ break;
+ // TODO: stop writing when MBR didn't change!
+ }
}
// reinsert the first entries
- for(int i = 0; i < start; i++) {
- DistanceEntry<DoubleDistance, E> re = reInsertEntries[i];
+ for(E entry : reInsertEntries) {
if(node.isLeaf()) {
if(getLogger().isDebugging()) {
- getLogger().debugFine("reinsert " + re.getEntry());
+ getLogger().debug("reinsert " + entry);
}
- insertLeafEntry(re.getEntry());
+ insertLeafEntry(entry);
}
else {
if(getLogger().isDebugging()) {
- getLogger().debugFine("reinsert " + re.getEntry() + " at " + level);
+ getLogger().debug("reinsert " + entry + " at " + level);
}
- insertDirectoryEntry(re.getEntry(), level);
+ insertDirectoryEntry(entry, level);
}
}
}
@@ -778,7 +758,7 @@ public abstract class AbstractRStarTree<N extends AbstractRStarTreeNode<N, E>, E
*/
protected void adjustTree(IndexTreePath<E> subtree) {
if(getLogger().isDebugging()) {
- getLogger().debugFine("Adjust tree " + subtree + "\n");
+ getLogger().debugFine("Adjust tree " + subtree);
}
// get the root of the subtree
@@ -826,11 +806,13 @@ public abstract class AbstractRStarTree<N extends AbstractRStarTreeNode<N, E>, E
if(!isRoot(node)) {
N parent = getNode(subtree.getParentPath().getLastPathComponent().getEntry());
E entry = parent.getEntry(subtree.getLastPathComponent().getIndex());
- lastInsertedEntry = node.adjustEntryIncremental(entry, lastInsertedEntry);
- // node.adjustEntry(parent.getEntry(index));
- // write changes in parent to file
- writeNode(parent);
- adjustTree(subtree.getParentPath());
+ boolean changed = node.adjustEntryIncremental(entry, lastInsertedEntry);
+ if(changed) {
+ // node.adjustEntry(parent.getEntry(index));
+ // write changes in parent to file
+ writeNode(parent);
+ adjustTree(subtree.getParentPath());
+ }
}
// root level is reached
else {
@@ -896,12 +878,12 @@ public abstract class AbstractRStarTree<N extends AbstractRStarTreeNode<N, E>, E
@Override
public final List<E> getLeaves() {
List<E> result = new ArrayList<E>();
-
+
if(height == 1) {
result.add(getRootEntry());
return result;
}
-
+
getLeafNodes(getRoot(), result, height);
return result;
}
@@ -949,11 +931,11 @@ public abstract class AbstractRStarTree<N extends AbstractRStarTreeNode<N, E>, E
int leafNodes = 0;
int objects = 0;
int levels = 0;
-
+
if(initialized) {
N node = getRoot();
- int dim = node.getDimensionality();
-
+ int dim = getRootEntry().getDimensionality();
+
while(!node.isLeaf()) {
if(node.getNumEntries() > 0) {
E entry = node.getEntry(0);
@@ -961,7 +943,7 @@ public abstract class AbstractRStarTree<N extends AbstractRStarTreeNode<N, E>, E
levels++;
}
}
-
+
BreadthFirstEnumeration<N, E> enumeration = new BreadthFirstEnumeration<N, E>(this, getRootPath());
while(enumeration.hasMoreElements()) {
IndexTreePath<E> indexPath = enumeration.nextElement();
@@ -988,7 +970,7 @@ public abstract class AbstractRStarTree<N extends AbstractRStarTreeNode<N, E>, E
else {
result.append(getClass().getName()).append(" is empty!\n");
}
-
+
return result.toString();
}
} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/AbstractRStarTreeFactory.java b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/AbstractRStarTreeFactory.java
index 5a0b9975..e2bb3abb 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/AbstractRStarTreeFactory.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/AbstractRStarTreeFactory.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2011
+ Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
@@ -29,12 +29,18 @@ import de.lmu.ifi.dbs.elki.data.type.TypeUtil;
import de.lmu.ifi.dbs.elki.index.Index;
import de.lmu.ifi.dbs.elki.index.tree.TreeIndexFactory;
import de.lmu.ifi.dbs.elki.index.tree.spatial.SpatialEntry;
-import de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.bulk.BulkSplit;
-import de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.util.InsertionStrategy;
-import de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.util.LeastOverlapInsertionStrategy;
+import de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.strategies.bulk.BulkSplit;
+import de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.strategies.insert.CombinedInsertionStrategy;
+import de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.strategies.insert.InsertionStrategy;
+import de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.strategies.overflow.LimitedReinsertOverflowTreatment;
+import de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.strategies.overflow.OverflowTreatment;
+import de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.strategies.split.SplitStrategy;
+import de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.strategies.split.TopologicalSplitter;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.OptionID;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.constraints.IntervalConstraint;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.constraints.IntervalConstraint.IntervalBoundary;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ClassParameter;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.DoubleParameter;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ObjectParameter;
/**
@@ -57,11 +63,26 @@ public abstract class AbstractRStarTreeFactory<O extends NumberVector<O, ?>, N e
public static OptionID INSERTION_STRATEGY_ID = OptionID.getOrCreateOptionID("rtree.insertionstrategy", "The strategy to use for object insertion.");
/**
+ * Split strategy parameter. Optional.
+ */
+ public static OptionID SPLIT_STRATEGY_ID = OptionID.getOrCreateOptionID("rtree.splitstrategy", "The strategy to use for node splitting.");
+
+ /**
* Parameter for bulk strategy
*/
public static final OptionID BULK_SPLIT_ID = OptionID.getOrCreateOptionID("spatial.bulkstrategy", "The class to perform the bulk split with.");
/**
+ * Parameter for the relative minimum fill.
+ */
+ public static final OptionID MINIMUM_FILL_ID = OptionID.getOrCreateOptionID("rtree.minimum-fill", "Minimum relative fill required for data pages.");
+
+ /**
+ * Overflow treatment.
+ */
+ public static OptionID OVERFLOW_STRATEGY_ID = OptionID.getOrCreateOptionID("rtree.overflowtreatment", "The strategy to use for handling overflows.");
+
+ /**
* Strategy to find the insertion node with.
*/
protected InsertionStrategy insertionStrategy;
@@ -72,6 +93,21 @@ public abstract class AbstractRStarTreeFactory<O extends NumberVector<O, ?>, N e
protected BulkSplit bulkSplitter;
/**
+ * The strategy for splitting nodes
+ */
+ protected SplitStrategy nodeSplitter;
+
+ /**
+ * Overflow treatment strategy
+ */
+ protected OverflowTreatment overflowTreatment;
+
+ /**
+ * Relative minimum fill
+ */
+ protected double minimumFill;
+
+ /**
* Constructor.
*
* @param fileName
@@ -79,11 +115,17 @@ public abstract class AbstractRStarTreeFactory<O extends NumberVector<O, ?>, N e
* @param cacheSize
* @param bulkSplitter the strategy to use for bulk splitting
* @param insertionStrategy the strategy to find the insertion child
+ * @param nodeSplitter the strategy to use for splitting nodes
+ * @param overflowTreatment the strategy to use for overflow treatment
+ * @param minimumFill the relative minimum fill
*/
- public AbstractRStarTreeFactory(String fileName, int pageSize, long cacheSize, BulkSplit bulkSplitter, InsertionStrategy insertionStrategy) {
+ public AbstractRStarTreeFactory(String fileName, int pageSize, long cacheSize, BulkSplit bulkSplitter, InsertionStrategy insertionStrategy, SplitStrategy nodeSplitter, OverflowTreatment overflowTreatment, double minimumFill) {
super(fileName, pageSize, cacheSize);
this.insertionStrategy = insertionStrategy;
this.bulkSplitter = bulkSplitter;
+ this.nodeSplitter = nodeSplitter;
+ this.overflowTreatment = overflowTreatment;
+ this.minimumFill = minimumFill;
}
@Override
@@ -99,18 +141,51 @@ public abstract class AbstractRStarTreeFactory<O extends NumberVector<O, ?>, N e
* @apiviz.exclude
*/
public static abstract class Parameterizer<O extends NumberVector<O, ?>> extends TreeIndexFactory.Parameterizer<O> {
+ /**
+ * Insertion strategy
+ */
+ protected InsertionStrategy insertionStrategy = null;
+
+ /**
+ * The strategy for splitting nodes
+ */
+ protected SplitStrategy nodeSplitter = null;
+
+ /**
+ * Bulk loading strategy
+ */
protected BulkSplit bulkSplitter = null;
- protected InsertionStrategy insertionStrategy = null;
+ /**
+ * Overflow treatment strategy
+ */
+ protected OverflowTreatment overflowTreatment = null;
+
+ /**
+ * Relative minimum fill
+ */
+ protected double minimumFill;
@Override
protected void makeOptions(Parameterization config) {
super.makeOptions(config);
- configBulkLoad(config);
- ClassParameter<InsertionStrategy> insertionStrategyP = new ClassParameter<InsertionStrategy>(INSERTION_STRATEGY_ID, InsertionStrategy.class, LeastOverlapInsertionStrategy.class);
+ ObjectParameter<InsertionStrategy> insertionStrategyP = new ObjectParameter<InsertionStrategy>(INSERTION_STRATEGY_ID, InsertionStrategy.class, CombinedInsertionStrategy.class);
if(config.grab(insertionStrategyP)) {
insertionStrategy = insertionStrategyP.instantiateClass(config);
}
+ ObjectParameter<SplitStrategy> splitStrategyP = new ObjectParameter<SplitStrategy>(SPLIT_STRATEGY_ID, SplitStrategy.class, TopologicalSplitter.class);
+ if(config.grab(splitStrategyP)) {
+ nodeSplitter = splitStrategyP.instantiateClass(config);
+ }
+ DoubleParameter minimumFillP = new DoubleParameter(MINIMUM_FILL_ID, new IntervalConstraint(0.0, IntervalBoundary.OPEN, 0.5, IntervalBoundary.OPEN), 0.4);
+ if (config.grab(minimumFillP)) {
+ minimumFill = minimumFillP.getValue();
+ }
+ ObjectParameter<OverflowTreatment> overflowP = new ObjectParameter<OverflowTreatment>(OVERFLOW_STRATEGY_ID, OverflowTreatment.class, LimitedReinsertOverflowTreatment.class);
+ if(config.grab(overflowP)) {
+ overflowTreatment = overflowP.instantiateClass(config);
+ }
+ configBulkLoad(config);
}
/**
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/AbstractRStarTreeNode.java b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/AbstractRStarTreeNode.java
index 330d5aa7..46e3003e 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/AbstractRStarTreeNode.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/AbstractRStarTreeNode.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2011
+ Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
@@ -29,11 +29,10 @@ import java.io.ObjectOutput;
import java.util.logging.Logger;
import de.lmu.ifi.dbs.elki.data.HyperBoundingBox;
+import de.lmu.ifi.dbs.elki.data.ModifiableHyperBoundingBox;
import de.lmu.ifi.dbs.elki.data.spatial.SpatialComparable;
import de.lmu.ifi.dbs.elki.data.spatial.SpatialUtil;
-import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
import de.lmu.ifi.dbs.elki.index.tree.AbstractNode;
-import de.lmu.ifi.dbs.elki.index.tree.DistanceEntry;
import de.lmu.ifi.dbs.elki.index.tree.spatial.SpatialDirectoryEntry;
import de.lmu.ifi.dbs.elki.index.tree.spatial.SpatialEntry;
import de.lmu.ifi.dbs.elki.index.tree.spatial.SpatialNode;
@@ -67,56 +66,22 @@ public abstract class AbstractRStarTreeNode<N extends AbstractRStarTreeNode<N, E
super(capacity, isLeaf, eclass);
}
- @Override
- public double getMin(int dimension) {
- double min = getEntry(0).getMin(dimension);
- for(int i = 1; i < getNumEntries(); i++) {
- min = Math.min(min, getEntry(i).getMin(dimension));
- }
- return min;
- }
-
- @Override
- public double getMax(int dimension) {
- double max = getEntry(0).getMax(dimension);
- for(int i = 1; i < getNumEntries(); i++) {
- max = Math.min(max, getEntry(i).getMax(dimension));
- }
- return max;
- }
-
/**
* Recomputing the MBR is rather expensive.
*
* @return MBR
*/
- public HyperBoundingBox computeMBR() {
+ public ModifiableHyperBoundingBox computeMBR() {
E firstEntry = getEntry(0);
if(firstEntry == null) {
return null;
}
- int dim = firstEntry.getDimensionality();
// Note: we deliberately get a cloned copy here, since we will modify it.
- double[] min = SpatialUtil.getMin(firstEntry);
- double[] max = SpatialUtil.getMax(firstEntry);
-
- for(int i = 1; i < getNumEntries(); i++) {
- SpatialComparable mbr = getEntry(i);
- for(int d = 1; d <= dim; d++) {
- if(min[d - 1] > mbr.getMin(d)) {
- min[d - 1] = mbr.getMin(d);
- }
- if(max[d - 1] < mbr.getMax(d)) {
- max[d - 1] = mbr.getMax(d);
- }
- }
+ ModifiableHyperBoundingBox mbr = new ModifiableHyperBoundingBox(firstEntry);
+ for(int i = 1; i < numEntries; i++) {
+ mbr.extend(getEntry(i));
}
- return new HyperBoundingBox(min, max);
- }
-
- @Override
- public int getDimensionality() {
- return getEntry(0).getDimensionality();
+ return mbr;
}
/**
@@ -124,8 +89,31 @@ public abstract class AbstractRStarTreeNode<N extends AbstractRStarTreeNode<N, E
*
* @param entry the entry representing this node
*/
- public void adjustEntry(E entry) {
- ((SpatialDirectoryEntry)entry).setMBR(computeMBR());
+ public boolean adjustEntry(E entry) {
+ final SpatialDirectoryEntry se = (SpatialDirectoryEntry) entry;
+ final ModifiableHyperBoundingBox mbr = computeMBR();
+ boolean changed = false;
+ if(se.hasMBR()) {
+ final int dim = se.getDimensionality();
+ // Test for changes
+ for(int i = 1; i <= dim; i++) {
+ if(Math.abs(se.getMin(i) - mbr.getMin(i)) > Float.MIN_NORMAL) {
+ changed = true;
+ break;
+ }
+ if(Math.abs(se.getMax(i) - mbr.getMax(i)) > Float.MIN_NORMAL) {
+ changed = true;
+ break;
+ }
+ }
+ }
+ else { // No preexisting MBR.
+ changed = true;
+ }
+ if(changed) {
+ se.setMBR(mbr);
+ }
+ return changed;
}
/**
@@ -135,33 +123,10 @@ public abstract class AbstractRStarTreeNode<N extends AbstractRStarTreeNode<N, E
* @param entry the entry representing this node
* @param responsibleMBR the MBR of the object or node which is responsible
* for the call of the method
- * @return the MBR of the new Node
- */
- public E adjustEntryIncremental(E entry, SpatialComparable responsibleMBR) {
- ((SpatialDirectoryEntry)entry).setMBR(SpatialUtil.union(entry, responsibleMBR));
- return entry;
- }
-
- /**
- * * Initializes a reinsert operation. Deletes all entries in this node and
- * adds all entries from start index on to this node's children.
- *
- * @param start the start index of the entries that will be reinserted
- * @param reInsertEntries the array of entries to be reinserted
+ * @return true when the entry has changed
*/
- protected <D extends Distance<D>> void initReInsert(int start, DistanceEntry<D, E>[] reInsertEntries) {
- deleteAllEntries();
-
- if(isLeaf()) {
- for(int i = start; i < reInsertEntries.length; i++) {
- addLeafEntry(reInsertEntries[i].getEntry());
- }
- }
- else {
- for(int i = start; i < reInsertEntries.length; i++) {
- addDirectoryEntry(reInsertEntries[i].getEntry());
- }
- }
+ public boolean adjustEntryIncremental(E entry, SpatialComparable responsibleMBR) {
+ return ((SpatialDirectoryEntry) entry).extendMBR(responsibleMBR);
}
/**
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/NonFlatRStarTree.java b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/NonFlatRStarTree.java
index 20ae3826..41882ce2 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/NonFlatRStarTree.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/NonFlatRStarTree.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2011
+ Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
@@ -26,13 +26,9 @@ package de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants;
import java.util.ArrayList;
import java.util.List;
-import de.lmu.ifi.dbs.elki.data.spatial.SpatialComparable;
import de.lmu.ifi.dbs.elki.index.tree.spatial.SpatialDirectoryEntry;
import de.lmu.ifi.dbs.elki.index.tree.spatial.SpatialEntry;
-import de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.bulk.BulkSplit;
-import de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.util.InsertionStrategy;
import de.lmu.ifi.dbs.elki.persistent.PageFile;
-import de.lmu.ifi.dbs.elki.utilities.exceptions.AbortException;
/**
* Abstract superclass for all non-flat R*-Tree variants.
@@ -47,11 +43,9 @@ public abstract class NonFlatRStarTree<N extends AbstractRStarTreeNode<N, E>, E
* Constructor.
*
* @param pagefile Page file
- * @param bulkSplitter bulk load strategy
- * @param insertionStrategy the strategy to find the child to insert to
*/
- public NonFlatRStarTree(PageFile<N> pagefile, BulkSplit bulkSplitter, InsertionStrategy insertionStrategy) {
- super(pagefile, bulkSplitter, insertionStrategy);
+ public NonFlatRStarTree(PageFile<N> pagefile) {
+ super(pagefile);
}
/**
@@ -128,7 +122,7 @@ public abstract class NonFlatRStarTree<N extends AbstractRStarTreeNode<N, E>, E
StringBuffer msg = getLogger().isDebuggingFine() ? new StringBuffer() : null;
- // Tiny tree that fit into a single page
+ // Tiny tree that fits into a single page
if(spatialObjects.size() <= leafCapacity) {
N root = createNewLeafNode();
root.setPageID(getRootID());
@@ -146,7 +140,7 @@ public abstract class NonFlatRStarTree<N extends AbstractRStarTreeNode<N, E>, E
writeNode(root);
// create leaf nodes
- List<N> nodes = createBulkLeafNodes(spatialObjects);
+ List<E> nodes = createBulkLeafNodes(spatialObjects);
int numNodes = nodes.size();
if(msg != null) {
@@ -156,13 +150,13 @@ public abstract class NonFlatRStarTree<N extends AbstractRStarTreeNode<N, E>, E
// create directory nodes
while(nodes.size() > (dirCapacity - 1)) {
- nodes = createDirectoryNodes(nodes);
+ nodes = createBulkDirectoryNodes(nodes);
numNodes += nodes.size();
setHeight(getHeight() + 1);
}
// create root
- createRoot(root, new ArrayList<N>(nodes));
+ createRoot(root, nodes);
numNodes++;
setHeight(getHeight() + 1);
if(msg != null) {
@@ -182,30 +176,26 @@ public abstract class NonFlatRStarTree<N extends AbstractRStarTreeNode<N, E>, E
* @param nodes the nodes to be inserted
* @return the directory nodes containing the nodes
*/
- private List<N> createDirectoryNodes(List<N> nodes) {
+ private List<E> createBulkDirectoryNodes(List<E> nodes) {
int minEntries = dirMinimum;
int maxEntries = dirCapacity - 1;
- ArrayList<N> result = new ArrayList<N>();
- List<List<N>> partitions = bulkSplitter.partition(nodes, minEntries, maxEntries);
+ ArrayList<E> result = new ArrayList<E>();
+ List<List<E>> partitions = bulkSplitter.partition(nodes, minEntries, maxEntries);
- for(List<N> partition : partitions) {
+ for(List<E> partition : partitions) {
// create node
N dirNode = createNewDirectoryNode();
- writeNode(dirNode);
- result.add(dirNode);
-
// insert nodes
- for(N o : partition) {
- dirNode.addDirectoryEntry(createNewDirectoryEntry(o));
+ for(E o : partition) {
+ dirNode.addDirectoryEntry(o);
}
-
// write to file
writeNode(dirNode);
+
+ result.add(createNewDirectoryEntry(dirNode));
if(getLogger().isDebuggingFiner()) {
- StringBuffer msg = new StringBuffer();
- msg.append("\npageNo ").append(dirNode.getPageID());
- getLogger().debugFiner(msg.toString() + "\n");
+ getLogger().debugFiner("Directory page no: "+dirNode.getPageID());
}
}
@@ -221,17 +211,14 @@ public abstract class NonFlatRStarTree<N extends AbstractRStarTreeNode<N, E>, E
* @param objects the spatial objects to be inserted
* @return the root node
*/
- @SuppressWarnings("unchecked")
- private N createRoot(N root, List<? extends SpatialComparable> objects) {
+ private N createRoot(N root, List<E> objects) {
// insert data
- for(SpatialComparable object : objects) {
- if(object instanceof SpatialEntry) {
- E entry = (E) object;
+ for(E entry : objects) {
+ if (entry.isLeafEntry()) {
root.addLeafEntry(entry);
- throw new AbortException("Unexpected spatial comparable encountered.");
}
else {
- root.addDirectoryEntry(createNewDirectoryEntry((N) object));
+ root.addDirectoryEntry(entry);
}
}
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/bulk/ZCurveBulkSplit.java b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/bulk/ZCurveBulkSplit.java
deleted file mode 100644
index 61e07960..00000000
--- a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/bulk/ZCurveBulkSplit.java
+++ /dev/null
@@ -1,184 +0,0 @@
-package de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.bulk;
-
-/*
- 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.Comparator;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import de.lmu.ifi.dbs.elki.data.spatial.SpatialComparable;
-import de.lmu.ifi.dbs.elki.logging.Logging;
-import de.lmu.ifi.dbs.elki.math.spacefillingcurves.ZCurve;
-
-/**
- * Bulk split that orders object by their Z curve position, then splits them
- * into pages accordingly.
- *
- * @author Elke Achtert
- */
-public class ZCurveBulkSplit extends AbstractBulkSplit {
- /**
- * Logger.
- */
- private static final Logging logger = Logging.getLogger(ZCurveBulkSplit.class);
-
- /**
- * Constructor
- */
- public ZCurveBulkSplit() {
- // Nothing to do
- }
-
- /**
- * Partitions the specified feature vectors
- *
- * @param spatialObjects the spatial objects to be partitioned
- * @param minEntries the minimum number of entries in a partition
- * @param maxEntries the maximum number of entries in a partition
- * @param <N> object type
- * @return the partition of the specified spatial objects
- */
- @Override
- public <N extends SpatialComparable> List<List<N>> partition(List<N> spatialObjects, int minEntries, int maxEntries) {
- List<List<N>> partitions = new ArrayList<List<N>>();
- List<N> objects = new ArrayList<N>(spatialObjects);
-
- // one dimensional special case
- if(spatialObjects.size() > 0 && spatialObjects.get(0).getDimensionality() == 1) {
- // TODO: move this Comparator into shared code.
- Collections.sort(objects, new Comparator<SpatialComparable>() {
- @Override
- public int compare(SpatialComparable o1, SpatialComparable o2) {
- return Double.compare(o1.getMin(1), o2.getMin(1));
- }
- });
-
- // build partitions
- // reinitialize array with correct size. Array will not use more space
- // than necessary.
- int numberPartitions = (int) Math.ceil(1d * spatialObjects.size() / maxEntries);
- partitions = new ArrayList<List<N>>(numberPartitions);
- List<N> onePartition = null;
- for(N o : objects) {
- if(onePartition == null || onePartition.size() >= maxEntries) {
- onePartition = new ArrayList<N>(maxEntries);
- partitions.add(onePartition);
- }
- onePartition.add(o);
- }
-
- // okay, check last partition for underfill
- // only check if there is more than 1 partition
- if(partitions.size() > 1) {
- List<N> last = partitions.get(partitions.size() - 1);
- List<N> nextToLast = partitions.get(partitions.size() - 2);
- while(last.size() < minEntries) {
- last.add(0, nextToLast.remove(nextToLast.size() - 1));
- }
- }
- return partitions;
- }
-
- // get z-values
- List<double[]> valuesList = new ArrayList<double[]>();
- for(SpatialComparable o : spatialObjects) {
- double[] values = new double[o.getDimensionality()];
- for(int d = 0; d < o.getDimensionality(); d++) {
- values[d] = o.getMin(d + 1);
- }
- valuesList.add(values);
- }
- if(logger.isDebugging()) {
- logger.debugFine(valuesList.toString());
- }
- List<byte[]> zValuesList = ZCurve.zValues(valuesList);
-
- // map z-values
- final Map<SpatialComparable, byte[]> zValues = new HashMap<SpatialComparable, byte[]>();
- for(int i = 0; i < spatialObjects.size(); i++) {
- SpatialComparable o = spatialObjects.get(i);
- byte[] zValue = zValuesList.get(i);
- zValues.put(o, zValue);
- }
-
- // create a comparator
- Comparator<SpatialComparable> comparator = new Comparator<SpatialComparable>() {
- @Override
- public int compare(SpatialComparable o1, SpatialComparable o2) {
- byte[] z1 = zValues.get(o1);
- byte[] z2 = zValues.get(o2);
-
- for(int i = 0; i < z1.length; i++) {
- byte z1_i = z1[i];
- byte z2_i = z2[i];
- if(z1_i < z2_i) {
- return -1;
- }
- else if(z1_i > z2_i) {
- return +1;
- }
- }
- if(o1 instanceof Comparable) {
- try {
- @SuppressWarnings("unchecked")
- final Comparable<Object> comparable = (Comparable<Object>) o1;
- return comparable.compareTo(o2);
- }
- catch(ClassCastException e) {
- // ignore
- }
- }
- return 0;
- }
- };
- Collections.sort(objects, comparator);
-
- // insert into partition
- while(objects.size() > 0) {
- StringBuffer msg = new StringBuffer();
- int splitPoint = chooseBulkSplitPoint(objects.size(), minEntries, maxEntries);
- List<N> partition1 = new ArrayList<N>();
- for(int i = 0; i < splitPoint; i++) {
- N o = objects.remove(0);
- partition1.add(o);
- }
- partitions.add(partition1);
-
- // copy array
- if(logger.isDebugging()) {
- msg.append("\ncurrent partition " + partition1);
- msg.append("\nremaining objects # ").append(objects.size());
- logger.debugFine(msg.toString());
- }
- }
-
- if(logger.isDebugging()) {
- logger.debugFine("partitions " + partitions);
- }
- return partitions;
- }
-}
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/deliclu/DeLiCluDirectoryEntry.java b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/deliclu/DeLiCluDirectoryEntry.java
index a620ff62..10f25ec0 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/deliclu/DeLiCluDirectoryEntry.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/deliclu/DeLiCluDirectoryEntry.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.deliclu;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2011
+ Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
@@ -23,7 +23,7 @@ package de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.deliclu;
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-import de.lmu.ifi.dbs.elki.data.HyperBoundingBox;
+import de.lmu.ifi.dbs.elki.data.ModifiableHyperBoundingBox;
import de.lmu.ifi.dbs.elki.index.tree.spatial.SpatialDirectoryEntry;
/**
@@ -64,7 +64,7 @@ public class DeLiCluDirectoryEntry extends SpatialDirectoryEntry implements DeLi
* @param hasHandled indicates if this entry has handled nodes
* @param hasUnhandled indicates if this entry has unhandled nodes
*/
- public DeLiCluDirectoryEntry(int id, HyperBoundingBox mbr, boolean hasHandled, boolean hasUnhandled) {
+ public DeLiCluDirectoryEntry(int id, ModifiableHyperBoundingBox mbr, boolean hasHandled, boolean hasUnhandled) {
super(id, mbr);
this.hasHandled = hasHandled;
this.hasUnhandled = hasUnhandled;
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/deliclu/DeLiCluEntry.java b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/deliclu/DeLiCluEntry.java
index 3dbde624..19cf8a32 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/deliclu/DeLiCluEntry.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/deliclu/DeLiCluEntry.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.deliclu;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2011
+ Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/deliclu/DeLiCluLeafEntry.java b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/deliclu/DeLiCluLeafEntry.java
index b2ec9f9a..c7cfc493 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/deliclu/DeLiCluLeafEntry.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/deliclu/DeLiCluLeafEntry.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.deliclu;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2011
+ Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/deliclu/DeLiCluNode.java b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/deliclu/DeLiCluNode.java
index 689507cb..bf993c01 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/deliclu/DeLiCluNode.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/deliclu/DeLiCluNode.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.deliclu;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2011
+ Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
@@ -88,13 +88,14 @@ public class DeLiCluNode extends AbstractRStarTreeNode<DeLiCluNode, DeLiCluEntry
}
@Override
- public void adjustEntry(DeLiCluEntry entry) {
- super.adjustEntry(entry);
+ public boolean adjustEntry(DeLiCluEntry entry) {
+ boolean changed = super.adjustEntry(entry);
// adjust hasHandled and hasUnhandled flag
boolean hasHandled = hasHandled();
boolean hasUnhandled = hasUnhandled();
entry.setHasHandled(hasHandled);
entry.setHasUnhandled(hasUnhandled);
+ return changed;
}
/**
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/deliclu/DeLiCluTree.java b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/deliclu/DeLiCluTree.java
index ac873815..6f4f782d 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/deliclu/DeLiCluTree.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/deliclu/DeLiCluTree.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.deliclu;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2011
+ Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
@@ -31,8 +31,6 @@ import de.lmu.ifi.dbs.elki.index.tree.BreadthFirstEnumeration;
import de.lmu.ifi.dbs.elki.index.tree.Entry;
import de.lmu.ifi.dbs.elki.index.tree.spatial.SpatialEntry;
import de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.NonFlatRStarTree;
-import de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.bulk.BulkSplit;
-import de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.util.InsertionStrategy;
import de.lmu.ifi.dbs.elki.logging.Logging;
import de.lmu.ifi.dbs.elki.persistent.PageFile;
@@ -61,11 +59,9 @@ public class DeLiCluTree extends NonFlatRStarTree<DeLiCluNode, DeLiCluEntry> {
* Constructor.
*
* @param pagefile Page file
- * @param bulkSplitter bulk load strategy
- * @param insertionStrategy the strategy to find the insertion child
*/
- public DeLiCluTree(PageFile<DeLiCluNode> pagefile, BulkSplit bulkSplitter, InsertionStrategy insertionStrategy) {
- super(pagefile, bulkSplitter, insertionStrategy);
+ public DeLiCluTree(PageFile<DeLiCluNode> pagefile) {
+ super(pagefile);
}
/**
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/deliclu/DeLiCluTreeFactory.java b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/deliclu/DeLiCluTreeFactory.java
index dd9532a2..3f9627a9 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/deliclu/DeLiCluTreeFactory.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/deliclu/DeLiCluTreeFactory.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.deliclu;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2011
+ Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
@@ -26,8 +26,10 @@ package de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.deliclu;
import de.lmu.ifi.dbs.elki.data.NumberVector;
import de.lmu.ifi.dbs.elki.database.relation.Relation;
import de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.AbstractRStarTreeFactory;
-import de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.bulk.BulkSplit;
-import de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.util.InsertionStrategy;
+import de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.strategies.bulk.BulkSplit;
+import de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.strategies.insert.InsertionStrategy;
+import de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.strategies.overflow.OverflowTreatment;
+import de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.strategies.split.SplitStrategy;
import de.lmu.ifi.dbs.elki.persistent.PageFile;
/**
@@ -49,15 +51,24 @@ public class DeLiCluTreeFactory<O extends NumberVector<O, ?>> extends AbstractRS
* @param cacheSize
* @param bulkSplitter Bulk loading strategy
* @param insertionStrategy the strategy to find the insertion child
+ * @param nodeSplitter the strategy for splitting nodes.
+ * @param overflowTreatment the strategy to use for overflow treatment
+ * @param minimumFill the relative minimum fill
*/
- public DeLiCluTreeFactory(String fileName, int pageSize, long cacheSize, BulkSplit bulkSplitter, InsertionStrategy insertionStrategy) {
- super(fileName, pageSize, cacheSize, bulkSplitter, insertionStrategy);
+ public DeLiCluTreeFactory(String fileName, int pageSize, long cacheSize, BulkSplit bulkSplitter, InsertionStrategy insertionStrategy, SplitStrategy nodeSplitter, OverflowTreatment overflowTreatment, double minimumFill) {
+ super(fileName, pageSize, cacheSize, bulkSplitter, insertionStrategy, nodeSplitter, overflowTreatment, minimumFill);
}
@Override
public DeLiCluTreeIndex<O> instantiate(Relation<O> relation) {
PageFile<DeLiCluNode> pagefile = makePageFile(getNodeClass());
- return new DeLiCluTreeIndex<O>(relation, pagefile, bulkSplitter, insertionStrategy);
+ DeLiCluTreeIndex<O> index = new DeLiCluTreeIndex<O>(relation, pagefile);
+ index.setBulkStrategy(bulkSplitter);
+ index.setInsertionStrategy(insertionStrategy);
+ index.setNodeSplitStrategy(nodeSplitter);
+ index.setOverflowTreatment(overflowTreatment);
+ index.setMinimumFill(minimumFill);
+ return index;
}
protected Class<DeLiCluNode> getNodeClass() {
@@ -74,7 +85,7 @@ public class DeLiCluTreeFactory<O extends NumberVector<O, ?>> extends AbstractRS
public static class Parameterizer<O extends NumberVector<O, ?>> extends AbstractRStarTreeFactory.Parameterizer<O> {
@Override
protected DeLiCluTreeFactory<O> makeInstance() {
- return new DeLiCluTreeFactory<O>(fileName, pageSize, cacheSize, bulkSplitter, insertionStrategy);
+ return new DeLiCluTreeFactory<O>(fileName, pageSize, cacheSize, bulkSplitter, insertionStrategy, nodeSplitter, overflowTreatment, minimumFill);
}
}
} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/deliclu/DeLiCluTreeIndex.java b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/deliclu/DeLiCluTreeIndex.java
index 062ddfb2..dd523ef8 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/deliclu/DeLiCluTreeIndex.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/deliclu/DeLiCluTreeIndex.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.deliclu;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2011
+ Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
@@ -39,9 +39,7 @@ import de.lmu.ifi.dbs.elki.index.KNNIndex;
import de.lmu.ifi.dbs.elki.index.RangeIndex;
import de.lmu.ifi.dbs.elki.index.tree.IndexTreePath;
import de.lmu.ifi.dbs.elki.index.tree.TreeIndexPathComponent;
-import de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.bulk.BulkSplit;
import de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.query.RStarTreeUtil;
-import de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.util.InsertionStrategy;
import de.lmu.ifi.dbs.elki.logging.Logging;
import de.lmu.ifi.dbs.elki.persistent.PageFile;
import de.lmu.ifi.dbs.elki.utilities.exceptions.AbortException;
@@ -64,11 +62,9 @@ public class DeLiCluTreeIndex<O extends NumberVector<?, ?>> extends DeLiCluTree
*
* @param relation Relation to index
* @param pagefile Page file
- * @param bulkSplitter bulk load strategy
- * @param insertionStrategy the strategy to find the insertion child
*/
- public DeLiCluTreeIndex(Relation<O> relation, PageFile<DeLiCluNode> pagefile, BulkSplit bulkSplitter, InsertionStrategy insertionStrategy) {
- super(pagefile, bulkSplitter, insertionStrategy);
+ public DeLiCluTreeIndex(Relation<O> relation, PageFile<DeLiCluNode> pagefile) {
+ super(pagefile);
this.relation = relation;
this.initialize();
}
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/deliclu/package-info.java b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/deliclu/package-info.java
index 8ebaab8c..b6c0af9b 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/deliclu/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/deliclu/package-info.java
@@ -5,7 +5,7 @@
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
-Copyright (C) 2011
+Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/package-info.java b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/package-info.java
index e658ebf5..2774fbe1 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/package-info.java
@@ -5,7 +5,7 @@
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
-Copyright (C) 2011
+Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/query/DoubleDistanceRStarTreeKNNQuery.java b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/query/DoubleDistanceRStarTreeKNNQuery.java
index 7d39c08f..9174dc94 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/query/DoubleDistanceRStarTreeKNNQuery.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/query/DoubleDistanceRStarTreeKNNQuery.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.query;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2011
+ Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
@@ -36,10 +36,10 @@ import de.lmu.ifi.dbs.elki.database.ids.DBID;
import de.lmu.ifi.dbs.elki.database.ids.DBIDUtil;
import de.lmu.ifi.dbs.elki.database.ids.DBIDs;
import de.lmu.ifi.dbs.elki.database.ids.ModifiableDBIDs;
-import de.lmu.ifi.dbs.elki.database.query.DistanceResultPair;
import de.lmu.ifi.dbs.elki.database.query.DoubleDistanceResultPair;
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.database.query.knn.KNNResult;
import de.lmu.ifi.dbs.elki.distance.distancefunction.SpatialPrimitiveDoubleDistanceFunction;
import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance;
import de.lmu.ifi.dbs.elki.index.tree.DirectoryEntry;
@@ -50,16 +50,24 @@ import de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.AbstractRStarTree;
import de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.AbstractRStarTreeNode;
import de.lmu.ifi.dbs.elki.utilities.datastructures.heap.Heap;
import de.lmu.ifi.dbs.elki.utilities.datastructures.heap.KNNHeap;
-import de.lmu.ifi.dbs.elki.utilities.datastructures.heap.UpdatableHeap;
+import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
/**
* Instance of a KNN query for a particular spatial index.
*
+ * Reference:
+ * <p>
+ * G. R. Hjaltason, H. Samet<br />
+ * Ranking in spatial databases<br />
+ * In: 4th Symposium on Advances in Spatial Databases, SSD'95
+ * </p>
+ *
* @author Erich Schubert
*
* @apiviz.uses AbstractRStarTree
* @apiviz.uses SpatialPrimitiveDoubleDistanceFunction
*/
+@Reference(authors = "G. R. Hjaltason, H. Samet", title = "Ranking in spatial databases", booktitle = "Advances in Spatial Databases - 4th Symposium, SSD'95", url = "http://dx.doi.org/10.1007/3-540-60159-7_6")
public class DoubleDistanceRStarTreeKNNQuery<O extends SpatialComparable> extends AbstractDistanceKNNQuery<O, DoubleDistance> {
/**
* The index to use
@@ -93,7 +101,7 @@ public class DoubleDistanceRStarTreeKNNQuery<O extends SpatialComparable> extend
* @param knnList the knn list containing the result
*/
protected void doKNNQuery(O object, KNNHeap<DoubleDistance> knnList) {
- final Heap<DoubleDistanceSearchCandidate> pq = new UpdatableHeap<DoubleDistanceSearchCandidate>();
+ final Heap<DoubleDistanceSearchCandidate> pq = new Heap<DoubleDistanceSearchCandidate>(Math.min(knnList.getK() * 2, 20));
// push root
pq.add(new DoubleDistanceSearchCandidate(0.0, tree.getRootID()));
@@ -106,32 +114,42 @@ public class DoubleDistanceRStarTreeKNNQuery<O extends SpatialComparable> extend
if(pqNode.mindist > maxDist) {
return;
}
+ maxDist = expandNode(object, knnList, pq, maxDist, pqNode.nodeID);
+ }
+ }
- AbstractRStarTreeNode<?, ?> node = tree.getNode(pqNode.nodeID);
- // data node
- if(node.isLeaf()) {
- for(int i = 0; i < node.getNumEntries(); i++) {
- SpatialEntry entry = node.getEntry(i);
- double distance = distanceFunction.doubleMinDist(entry, object);
- tree.distanceCalcs++;
- if(distance <= maxDist) {
- knnList.add(new DoubleDistanceResultPair(distance, ((LeafEntry) entry).getDBID()));
- maxDist = knnList.getKNNDistance().doubleValue();
- }
+ private double expandNode(O object, KNNHeap<DoubleDistance> knnList, final Heap<DoubleDistanceSearchCandidate> pq, double maxDist, final Integer nodeID) {
+ AbstractRStarTreeNode<?, ?> node = tree.getNode(nodeID);
+ // data node
+ if(node.isLeaf()) {
+ for(int i = 0; i < node.getNumEntries(); i++) {
+ SpatialEntry entry = node.getEntry(i);
+ double distance = distanceFunction.doubleMinDist(entry, object);
+ tree.distanceCalcs++;
+ if(distance <= maxDist) {
+ knnList.add(new DoubleDistanceResultPair(distance, ((LeafEntry) entry).getDBID()));
+ maxDist = knnList.getKNNDistance().doubleValue();
}
}
- // directory node
- else {
- for(int i = 0; i < node.getNumEntries(); i++) {
- SpatialEntry entry = node.getEntry(i);
- double distance = distanceFunction.doubleMinDist(entry, object);
- tree.distanceCalcs++;
+ }
+ // directory node
+ else {
+ for(int i = 0; i < node.getNumEntries(); i++) {
+ SpatialEntry entry = node.getEntry(i);
+ double distance = distanceFunction.doubleMinDist(entry, object);
+ tree.distanceCalcs++;
+ // Greedy expand, bypassing the queue
+ if(distance <= 0) {
+ expandNode(object, knnList, pq, maxDist, ((DirectoryEntry) entry).getPageID());
+ }
+ else {
if(distance <= maxDist) {
- pq.add(new DoubleDistanceSearchCandidate(distance, ((DirectoryEntry)entry).getPageID()));
+ pq.add(new DoubleDistanceSearchCandidate(distance, ((DirectoryEntry) entry).getPageID()));
}
}
}
}
+ return maxDist;
}
/**
@@ -161,7 +179,9 @@ public class DoubleDistanceRStarTreeKNNQuery<O extends SpatialComparable> extend
}
else {
ModifiableDBIDs ids = DBIDUtil.newArray(knnLists.size());
- ids.addAll(knnLists.keySet());
+ for(DBID id : knnLists.keySet()) {
+ ids.add(id);
+ }
List<DoubleDistanceEntry> entries = getSortedEntries(node, ids);
for(DoubleDistanceEntry distEntry : entries) {
double minDist = distEntry.distance;
@@ -171,7 +191,7 @@ public class DoubleDistanceRStarTreeKNNQuery<O extends SpatialComparable> extend
if(minDist <= knn_q_maxDist) {
SpatialEntry entry = distEntry.entry;
- AbstractRStarTreeNode<?, ?> child = tree.getNode(((DirectoryEntry)entry).getPageID());
+ AbstractRStarTreeNode<?, ?> child = tree.getNode(((DirectoryEntry) entry).getPageID());
batchNN(child, knnLists);
break;
}
@@ -210,7 +230,7 @@ public class DoubleDistanceRStarTreeKNNQuery<O extends SpatialComparable> extend
* Optimized double distance entry implementation.
*
* @author Erich Schubert
- *
+ *
* @apiviz.hidden
*/
class DoubleDistanceEntry implements Comparable<DoubleDistanceEntry> {
@@ -226,7 +246,7 @@ public class DoubleDistanceRStarTreeKNNQuery<O extends SpatialComparable> extend
/**
* Constructor.
- *
+ *
* @param entry Entry
* @param distance Distance
*/
@@ -242,23 +262,23 @@ public class DoubleDistanceRStarTreeKNNQuery<O extends SpatialComparable> extend
}
@Override
- public List<DistanceResultPair<DoubleDistance>> getKNNForObject(O obj, int k) {
+ public KNNResult<DoubleDistance> getKNNForObject(O obj, int k) {
if(k < 1) {
throw new IllegalArgumentException("At least one enumeration has to be requested!");
}
final KNNHeap<DoubleDistance> knnList = new KNNHeap<DoubleDistance>(k, distanceFunction.getDistanceFactory().infiniteDistance());
doKNNQuery(obj, knnList);
- return knnList.toSortedArrayList();
+ return knnList.toKNNList();
}
@Override
- public List<DistanceResultPair<DoubleDistance>> getKNNForDBID(DBID id, int k) {
+ public KNNResult<DoubleDistance> getKNNForDBID(DBID id, int k) {
return getKNNForObject(relation.get(id), k);
}
@Override
- public List<List<DistanceResultPair<DoubleDistance>>> getKNNForBulkDBIDs(ArrayDBIDs ids, int k) {
+ public List<KNNResult<DoubleDistance>> getKNNForBulkDBIDs(ArrayDBIDs ids, int k) {
if(k < 1) {
throw new IllegalArgumentException("At least one enumeration has to be requested!");
}
@@ -271,9 +291,9 @@ public class DoubleDistanceRStarTreeKNNQuery<O extends SpatialComparable> extend
batchNN(tree.getRoot(), knnLists);
- List<List<DistanceResultPair<DoubleDistance>>> result = new ArrayList<List<DistanceResultPair<DoubleDistance>>>();
+ List<KNNResult<DoubleDistance>> result = new ArrayList<KNNResult<DoubleDistance>>();
for(DBID id : ids) {
- result.add(knnLists.get(id).toSortedArrayList());
+ result.add(knnLists.get(id).toKNNList());
}
return result;
}
@@ -283,9 +303,4 @@ public class DoubleDistanceRStarTreeKNNQuery<O extends SpatialComparable> extend
AbstractRStarTreeNode<?, ?> root = tree.getRoot();
batchNN(root, heaps);
}
-
- @Override
- public DoubleDistance getDistanceFactory() {
- return distanceQuery.getDistanceFactory();
- }
} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/query/DoubleDistanceRStarTreeRangeQuery.java b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/query/DoubleDistanceRStarTreeRangeQuery.java
index 96d1e8c5..069db6d4 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/query/DoubleDistanceRStarTreeRangeQuery.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/query/DoubleDistanceRStarTreeRangeQuery.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.query;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2011
+ Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
@@ -41,16 +41,25 @@ import de.lmu.ifi.dbs.elki.index.tree.query.DoubleDistanceSearchCandidate;
import de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.AbstractRStarTree;
import de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.AbstractRStarTreeNode;
import de.lmu.ifi.dbs.elki.utilities.datastructures.heap.Heap;
+import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
/**
* Instance of a range query for a particular spatial index.
*
+ * Reference:
+ * <p>
+ * J. Kuan, P. Lewis<br />
+ * Fast k nearest neighbour search for R-tree family<br />
+ * In Proc. Int. Conf Information, Communications and Signal Processing, ICICS
+ * 1997
+ * </p>
+ *
* @author Erich Schubert
*
* @apiviz.uses AbstractRStarTree
* @apiviz.uses SpatialPrimitiveDoubleDistanceFunction
*/
-//TODO: add bulk range queries.
+@Reference(authors = "J. Kuan, P. Lewis", title = "Fast k nearest neighbour search for R-tree family", booktitle = "Proc. Int. Conf Information, Communications and Signal Processing, ICICS 1997", url = "http://dx.doi.org/10.1109/ICICS.1997.652114")
public class DoubleDistanceRStarTreeRangeQuery<O extends SpatialComparable> extends AbstractDistanceRangeQuery<O, DoubleDistance> {
/**
* The index to use
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/query/GenericRStarTreeKNNQuery.java b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/query/GenericRStarTreeKNNQuery.java
index be3ed994..5129f5ca 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/query/GenericRStarTreeKNNQuery.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/query/GenericRStarTreeKNNQuery.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.query;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2011
+ Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
@@ -36,9 +36,9 @@ import de.lmu.ifi.dbs.elki.database.ids.DBID;
import de.lmu.ifi.dbs.elki.database.ids.DBIDUtil;
import de.lmu.ifi.dbs.elki.database.ids.DBIDs;
import de.lmu.ifi.dbs.elki.database.ids.ModifiableDBIDs;
-import de.lmu.ifi.dbs.elki.database.query.DistanceResultPair;
import de.lmu.ifi.dbs.elki.database.query.distance.SpatialDistanceQuery;
import de.lmu.ifi.dbs.elki.database.query.knn.AbstractDistanceKNNQuery;
+import de.lmu.ifi.dbs.elki.database.query.knn.KNNResult;
import de.lmu.ifi.dbs.elki.distance.DistanceUtil;
import de.lmu.ifi.dbs.elki.distance.distancefunction.SpatialPrimitiveDistanceFunction;
import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
@@ -51,16 +51,24 @@ import de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.AbstractRStarTree;
import de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.AbstractRStarTreeNode;
import de.lmu.ifi.dbs.elki.utilities.datastructures.heap.Heap;
import de.lmu.ifi.dbs.elki.utilities.datastructures.heap.KNNHeap;
-import de.lmu.ifi.dbs.elki.utilities.datastructures.heap.UpdatableHeap;
+import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
/**
* Instance of a KNN query for a particular spatial index.
*
+ * Reference:
+ * <p>
+ * G. R. Hjaltason, H. Samet<br />
+ * Ranking in spatial databases<br />
+ * In: 4th Symposium on Advances in Spatial Databases, SSD'95
+ * </p>
+ *
* @author Erich Schubert
*
* @apiviz.uses AbstractRStarTree
* @apiviz.uses SpatialPrimitiveDistanceFunction
*/
+@Reference(authors = "G. R. Hjaltason, H. Samet", title = "Ranking in spatial databases", booktitle = "Advances in Spatial Databases - 4th Symposium, SSD'95", url = "http://dx.doi.org/10.1007/3-540-60159-7_6")
public class GenericRStarTreeKNNQuery<O extends SpatialComparable, D extends Distance<D>> extends AbstractDistanceKNNQuery<O, D> {
/**
* The index to use
@@ -93,7 +101,7 @@ public class GenericRStarTreeKNNQuery<O extends SpatialComparable, D extends Dis
* @param knnList the knn list containing the result
*/
protected void doKNNQuery(O object, KNNHeap<D> knnList) {
- final Heap<GenericDistanceSearchCandidate<D>> pq = new UpdatableHeap<GenericDistanceSearchCandidate<D>>();
+ final Heap<GenericDistanceSearchCandidate<D>> pq = new Heap<GenericDistanceSearchCandidate<D>>(Math.min(knnList.getK() * 2, 20));
// push root
pq.add(new GenericDistanceSearchCandidate<D>(distanceFunction.getDistanceFactory().nullDistance(), tree.getRootID()));
@@ -106,32 +114,42 @@ public class GenericRStarTreeKNNQuery<O extends SpatialComparable, D extends Dis
if(pqNode.mindist.compareTo(maxDist) > 0) {
return;
}
+ maxDist = expandNode(object, knnList, pq, maxDist, pqNode.nodeID);
+ }
+ }
- AbstractRStarTreeNode<?, ?> node = tree.getNode(pqNode.nodeID);
- // data node
- if(node.isLeaf()) {
- for(int i = 0; i < node.getNumEntries(); i++) {
- SpatialEntry entry = node.getEntry(i);
- D distance = distanceFunction.minDist(entry, object);
- tree.distanceCalcs++;
- if(distance.compareTo(maxDist) <= 0) {
- knnList.add(distance, ((LeafEntry) entry).getDBID());
- maxDist = knnList.getKNNDistance();
- }
+ private D expandNode(O object, KNNHeap<D> knnList, final Heap<GenericDistanceSearchCandidate<D>> pq, D maxDist, final Integer nodeID) {
+ AbstractRStarTreeNode<?, ?> node = tree.getNode(nodeID);
+ // data node
+ if(node.isLeaf()) {
+ for(int i = 0; i < node.getNumEntries(); i++) {
+ SpatialEntry entry = node.getEntry(i);
+ D distance = distanceFunction.minDist(entry, object);
+ tree.distanceCalcs++;
+ if(distance.compareTo(maxDist) <= 0) {
+ knnList.add(distance, ((LeafEntry) entry).getDBID());
+ maxDist = knnList.getKNNDistance();
}
}
- // directory node
- else {
- for(int i = 0; i < node.getNumEntries(); i++) {
- SpatialEntry entry = node.getEntry(i);
- D distance = distanceFunction.minDist(entry, object);
- tree.distanceCalcs++;
+ }
+ // directory node
+ else {
+ for(int i = 0; i < node.getNumEntries(); i++) {
+ SpatialEntry entry = node.getEntry(i);
+ D distance = distanceFunction.minDist(entry, object);
+ tree.distanceCalcs++;
+ // Greedy expand, bypassing the queue
+ if(distance.isNullDistance()) {
+ expandNode(object, knnList, pq, maxDist, ((DirectoryEntry) entry).getPageID());
+ }
+ else {
if(distance.compareTo(maxDist) <= 0) {
- pq.add(new GenericDistanceSearchCandidate<D>(distance, ((DirectoryEntry)entry).getPageID()));
+ pq.add(new GenericDistanceSearchCandidate<D>(distance, ((DirectoryEntry) entry).getPageID()));
}
}
}
}
+ return maxDist;
}
/**
@@ -160,7 +178,9 @@ public class GenericRStarTreeKNNQuery<O extends SpatialComparable, D extends Dis
}
else {
ModifiableDBIDs ids = DBIDUtil.newArray(knnLists.size());
- ids.addAll(knnLists.keySet());
+ for(DBID id : knnLists.keySet()) {
+ ids.add(id);
+ }
List<DistanceEntry<D, SpatialEntry>> entries = getSortedEntries(node, ids);
for(DistanceEntry<D, SpatialEntry> distEntry : entries) {
D minDist = distEntry.getDistance();
@@ -170,7 +190,7 @@ public class GenericRStarTreeKNNQuery<O extends SpatialComparable, D extends Dis
if(minDist.compareTo(knn_q_maxDist) <= 0) {
SpatialEntry entry = distEntry.getEntry();
- AbstractRStarTreeNode<?, ?> child = tree.getNode(((DirectoryEntry)entry).getPageID());
+ AbstractRStarTreeNode<?, ?> child = tree.getNode(((DirectoryEntry) entry).getPageID());
batchNN(child, knnLists);
break;
}
@@ -211,23 +231,23 @@ public class GenericRStarTreeKNNQuery<O extends SpatialComparable, D extends Dis
}
@Override
- public List<DistanceResultPair<D>> getKNNForObject(O obj, int k) {
+ public KNNResult<D> getKNNForObject(O obj, int k) {
if(k < 1) {
throw new IllegalArgumentException("At least one enumeration has to be requested!");
}
final KNNHeap<D> knnList = new KNNHeap<D>(k, distanceFunction.getDistanceFactory().infiniteDistance());
doKNNQuery(obj, knnList);
- return knnList.toSortedArrayList();
+ return knnList.toKNNList();
}
@Override
- public List<DistanceResultPair<D>> getKNNForDBID(DBID id, int k) {
+ public KNNResult<D> getKNNForDBID(DBID id, int k) {
return getKNNForObject(relation.get(id), k);
}
@Override
- public List<List<DistanceResultPair<D>>> getKNNForBulkDBIDs(ArrayDBIDs ids, int k) {
+ public List<KNNResult<D>> getKNNForBulkDBIDs(ArrayDBIDs ids, int k) {
if(k < 1) {
throw new IllegalArgumentException("At least one enumeration has to be requested!");
}
@@ -239,15 +259,10 @@ public class GenericRStarTreeKNNQuery<O extends SpatialComparable, D extends Dis
batchNN(tree.getRoot(), knnLists);
- List<List<DistanceResultPair<D>>> result = new ArrayList<List<DistanceResultPair<D>>>();
+ List<KNNResult<D>> result = new ArrayList<KNNResult<D>>();
for(DBID id : ids) {
- result.add(knnLists.get(id).toSortedArrayList());
+ result.add(knnLists.get(id).toKNNList());
}
return result;
}
-
- @Override
- public D getDistanceFactory() {
- return distanceQuery.getDistanceFactory();
- }
} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/query/GenericRStarTreeRangeQuery.java b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/query/GenericRStarTreeRangeQuery.java
index c4d68828..d2086cb1 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/query/GenericRStarTreeRangeQuery.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/query/GenericRStarTreeRangeQuery.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.query;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2011
+ Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
@@ -41,16 +41,25 @@ import de.lmu.ifi.dbs.elki.index.tree.query.GenericDistanceSearchCandidate;
import de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.AbstractRStarTree;
import de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.AbstractRStarTreeNode;
import de.lmu.ifi.dbs.elki.utilities.datastructures.heap.Heap;
+import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
/**
* Instance of a range query for a particular spatial index.
*
+ * Reference:
+ * <p>
+ * J. Kuan, P. Lewis<br />
+ * Fast k nearest neighbour search for R-tree family<br />
+ * In Proc. Int. Conf Information, Communications and Signal Processing, ICICS
+ * 1997
+ * </p>
+ *
* @author Erich Schubert
*
* @apiviz.uses AbstractRStarTree
* @apiviz.uses SpatialPrimitiveDistanceFunction
*/
-// TODO: add bulk range queries.
+@Reference(authors = "J. Kuan, P. Lewis", title = "Fast k nearest neighbour search for R-tree family", booktitle = "Proc. Int. Conf Information, Communications and Signal Processing, ICICS 1997", url = "http://dx.doi.org/10.1109/ICICS.1997.652114")
public class GenericRStarTreeRangeQuery<O extends SpatialComparable, D extends Distance<D>> extends AbstractDistanceRangeQuery<O, D> {
/**
* The index to use
@@ -69,7 +78,7 @@ public class GenericRStarTreeRangeQuery<O extends SpatialComparable, D extends D
* @param distanceQuery Distance query to use
*/
public GenericRStarTreeRangeQuery(AbstractRStarTree<?, ?> tree, SpatialDistanceQuery<O, D> distanceQuery) {
- super( distanceQuery);
+ super(distanceQuery);
this.tree = tree;
this.distanceFunction = distanceQuery.getDistanceFunction();
}
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/query/RStarTreeUtil.java b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/query/RStarTreeUtil.java
index 8e4b36e6..477e3a36 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/query/RStarTreeUtil.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/query/RStarTreeUtil.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.query;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2011
+ Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/query/package-info.java b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/query/package-info.java
index fffaa6bf..0b47cab0 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/query/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/query/package-info.java
@@ -5,7 +5,7 @@
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
-Copyright (C) 2011
+Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/rstar/RStarTree.java b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/rstar/RStarTree.java
index 4d208e46..53b32c6b 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/rstar/RStarTree.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/rstar/RStarTree.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.rstar;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2011
+ Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
@@ -26,8 +26,6 @@ package de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.rstar;
import de.lmu.ifi.dbs.elki.index.tree.spatial.SpatialDirectoryEntry;
import de.lmu.ifi.dbs.elki.index.tree.spatial.SpatialEntry;
import de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.NonFlatRStarTree;
-import de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.bulk.BulkSplit;
-import de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.util.InsertionStrategy;
import de.lmu.ifi.dbs.elki.logging.Logging;
import de.lmu.ifi.dbs.elki.persistent.PageFile;
import de.lmu.ifi.dbs.elki.utilities.documentation.Description;
@@ -56,11 +54,9 @@ public class RStarTree extends NonFlatRStarTree<RStarTreeNode, SpatialEntry> {
* Constructor.
*
* @param pagefile Page file
- * @param bulkSplitter bulk load strategy
- * @param insertionStrategy the strategy to find the insertion child
*/
- public RStarTree(PageFile<RStarTreeNode> pagefile, BulkSplit bulkSplitter, InsertionStrategy insertionStrategy) {
- super(pagefile, bulkSplitter, insertionStrategy);
+ public RStarTree(PageFile<RStarTreeNode> pagefile) {
+ super(pagefile);
}
@Override
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/rstar/RStarTreeFactory.java b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/rstar/RStarTreeFactory.java
index f8da714c..79aac0bd 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/rstar/RStarTreeFactory.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/rstar/RStarTreeFactory.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.rstar;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2011
+ Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
@@ -27,8 +27,10 @@ import de.lmu.ifi.dbs.elki.data.NumberVector;
import de.lmu.ifi.dbs.elki.database.relation.Relation;
import de.lmu.ifi.dbs.elki.index.tree.spatial.SpatialEntry;
import de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.AbstractRStarTreeFactory;
-import de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.bulk.BulkSplit;
-import de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.util.InsertionStrategy;
+import de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.strategies.bulk.BulkSplit;
+import de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.strategies.insert.InsertionStrategy;
+import de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.strategies.overflow.OverflowTreatment;
+import de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.strategies.split.SplitStrategy;
import de.lmu.ifi.dbs.elki.persistent.PageFile;
/**
@@ -50,15 +52,24 @@ public class RStarTreeFactory<O extends NumberVector<O, ?>> extends AbstractRSta
* @param cacheSize
* @param bulkSplitter Bulk loading strategy
* @param insertionStrategy the strategy to find the insertion child
+ * @param nodeSplitter the strategy for splitting nodes.
+ * @param overflowTreatment the strategy to use for overflow treatment
+ * @param minimumFill the relative minimum fill
*/
- public RStarTreeFactory(String fileName, int pageSize, long cacheSize, BulkSplit bulkSplitter, InsertionStrategy insertionStrategy) {
- super(fileName, pageSize, cacheSize, bulkSplitter, insertionStrategy);
+ public RStarTreeFactory(String fileName, int pageSize, long cacheSize, BulkSplit bulkSplitter, InsertionStrategy insertionStrategy, SplitStrategy nodeSplitter, OverflowTreatment overflowTreatment, double minimumFill) {
+ super(fileName, pageSize, cacheSize, bulkSplitter, insertionStrategy, nodeSplitter, overflowTreatment, minimumFill);
}
@Override
public RStarTreeIndex<O> instantiate(Relation<O> relation) {
PageFile<RStarTreeNode> pagefile = makePageFile(getNodeClass());
- return new RStarTreeIndex<O>(relation, pagefile, bulkSplitter, insertionStrategy);
+ RStarTreeIndex<O> index = new RStarTreeIndex<O>(relation, pagefile);
+ index.setBulkStrategy(bulkSplitter);
+ index.setInsertionStrategy(insertionStrategy);
+ index.setNodeSplitStrategy(nodeSplitter);
+ index.setOverflowTreatment(overflowTreatment);
+ index.setMinimumFill(minimumFill);
+ return index;
}
protected Class<RStarTreeNode> getNodeClass() {
@@ -75,7 +86,7 @@ public class RStarTreeFactory<O extends NumberVector<O, ?>> extends AbstractRSta
public static class Parameterizer<O extends NumberVector<O, ?>> extends AbstractRStarTreeFactory.Parameterizer<O> {
@Override
protected RStarTreeFactory<O> makeInstance() {
- return new RStarTreeFactory<O>(fileName, pageSize, cacheSize, bulkSplitter, insertionStrategy);
+ return new RStarTreeFactory<O>(fileName, pageSize, cacheSize, bulkSplitter, insertionStrategy, nodeSplitter, overflowTreatment, minimumFill);
}
}
} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/rstar/RStarTreeIndex.java b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/rstar/RStarTreeIndex.java
index 30286ca9..46ef2628 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/rstar/RStarTreeIndex.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/rstar/RStarTreeIndex.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.rstar;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2011
+ Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
@@ -40,9 +40,7 @@ import de.lmu.ifi.dbs.elki.index.RangeIndex;
import de.lmu.ifi.dbs.elki.index.tree.IndexTreePath;
import de.lmu.ifi.dbs.elki.index.tree.spatial.SpatialEntry;
import de.lmu.ifi.dbs.elki.index.tree.spatial.SpatialPointLeafEntry;
-import de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.bulk.BulkSplit;
import de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.query.RStarTreeUtil;
-import de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.util.InsertionStrategy;
import de.lmu.ifi.dbs.elki.logging.Logging;
import de.lmu.ifi.dbs.elki.persistent.PageFile;
@@ -69,11 +67,9 @@ public class RStarTreeIndex<O extends NumberVector<?, ?>> extends RStarTree impl
*
* @param relation Relation to index
* @param pagefile Page file
- * @param bulkSplitter bulk load strategy
- * @param insertionStrategy the strategy to find the insertion child
*/
- public RStarTreeIndex(Relation<O> relation, PageFile<RStarTreeNode> pagefile, BulkSplit bulkSplitter, InsertionStrategy insertionStrategy) {
- super(pagefile, bulkSplitter, insertionStrategy);
+ public RStarTreeIndex(Relation<O> relation, PageFile<RStarTreeNode> pagefile) {
+ super(pagefile);
this.relation = relation;
this.initialize();
}
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/rstar/RStarTreeNode.java b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/rstar/RStarTreeNode.java
index 248ddfc5..b51d191a 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/rstar/RStarTreeNode.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/rstar/RStarTreeNode.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.rstar;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2011
+ Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/rstar/package-info.java b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/rstar/package-info.java
index 7bfd1b9a..e15569c5 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/rstar/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/rstar/package-info.java
@@ -5,7 +5,7 @@
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
-Copyright (C) 2011
+Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/bulk/AbstractBulkSplit.java b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/bulk/AbstractBulkSplit.java
index 999fa019..4a0304f1 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/bulk/AbstractBulkSplit.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/bulk/AbstractBulkSplit.java
@@ -1,10 +1,13 @@
-package de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.bulk;
+package de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.strategies.bulk;
+
+import java.util.ArrayList;
+import java.util.List;
/*
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2011
+ Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
@@ -23,14 +26,12 @@ package de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.bulk;
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.Parameterizable;
-
/**
* Encapsulates the required parameters for a bulk split of a spatial index.
*
* @author Elke Achtert
*/
-public abstract class AbstractBulkSplit implements BulkSplit, Parameterizable {
+public abstract class AbstractBulkSplit implements BulkSplit {
/**
* Constructor
*/
@@ -61,4 +62,30 @@ public abstract class AbstractBulkSplit implements BulkSplit, Parameterizable {
return maxEntries;
}
}
+
+ /**
+ * Perform the trivial partitioning of the given list.
+ *
+ * @param objects Objects to partition
+ * @param minEntries Minimum number of objects per page
+ * @param maxEntries Maximum number of objects per page.
+ * @return List with partitions
+ */
+ protected <T> List<List<T>> trivialPartition(List<T> objects, int minEntries, int maxEntries) {
+ // build partitions
+ final int size = objects.size();
+ final int numberPartitions = (int) Math.ceil(((double) size) / maxEntries);
+ List<List<T>> partitions = new ArrayList<List<T>>(numberPartitions);
+ int start = 0;
+ for(int pnum = 0; pnum < numberPartitions; pnum++) {
+ int end = (int) ((pnum + 1.) * size / numberPartitions);
+ if(pnum == numberPartitions - 1) {
+ end = size;
+ }
+ assert ((end - start) >= minEntries && (end - start) <= maxEntries);
+ partitions.add(objects.subList(start, end));
+ start = end;
+ }
+ return partitions;
+ }
} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/bulk/BulkSplit.java b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/bulk/BulkSplit.java
index 23c0f077..1eb88f7c 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/bulk/BulkSplit.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/bulk/BulkSplit.java
@@ -1,10 +1,10 @@
-package de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.bulk;
+package de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.strategies.bulk;
/*
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2011
+ Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
@@ -26,13 +26,14 @@ package de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.bulk;
import java.util.List;
import de.lmu.ifi.dbs.elki.data.spatial.SpatialComparable;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.Parameterizable;
/**
* Interface for a bulk split strategy.
*
* @author Erich Schubert
*/
-public interface BulkSplit {
+public interface BulkSplit extends Parameterizable {
/**
* Partitions the specified feature vectors
*
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/bulk/FileOrderBulkSplit.java b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/bulk/FileOrderBulkSplit.java
new file mode 100644
index 00000000..308c70cb
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/bulk/FileOrderBulkSplit.java
@@ -0,0 +1,67 @@
+package de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.strategies.bulk;
+
+/*
+ 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 <http://www.gnu.org/licenses/>.
+ */
+import java.util.List;
+
+import de.lmu.ifi.dbs.elki.data.spatial.SpatialComparable;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
+
+/**
+ * Trivial bulk loading - assumes that the file has been appropriately sorted
+ * before.
+ *
+ * @author Erich Schubert
+ */
+public class FileOrderBulkSplit extends AbstractBulkSplit {
+ /**
+ * Static instance
+ */
+ public static final FileOrderBulkSplit STATIC = new FileOrderBulkSplit();
+
+ /**
+ * Constructor.
+ */
+ protected FileOrderBulkSplit() {
+ super();
+ }
+
+ @Override
+ public <T extends SpatialComparable> List<List<T>> partition(List<T> spatialObjects, int minEntries, int maxEntries) {
+ return trivialPartition(spatialObjects, minEntries, maxEntries);
+ }
+
+ /**
+ * Parameterization class.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ public static class Parameterizer extends AbstractParameterizer {
+ @Override
+ protected FileOrderBulkSplit makeInstance() {
+ return FileOrderBulkSplit.STATIC;
+ }
+ }
+} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/bulk/MaxExtensionBulkSplit.java b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/bulk/MaxExtensionBulkSplit.java
index 0a830aab..90a8b622 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/bulk/MaxExtensionBulkSplit.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/bulk/MaxExtensionBulkSplit.java
@@ -1,10 +1,10 @@
-package de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.bulk;
+package de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.strategies.bulk;
/*
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2011
+ Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
@@ -31,6 +31,7 @@ import java.util.List;
import de.lmu.ifi.dbs.elki.data.spatial.SpatialComparable;
import de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.util.SpatialComparator;
import de.lmu.ifi.dbs.elki.logging.Logging;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
/**
* Split strategy for bulk-loading a spatial tree where the split axes are the
@@ -45,6 +46,11 @@ public class MaxExtensionBulkSplit extends AbstractBulkSplit {
* Logger.
*/
private static final Logging logger = Logging.getLogger(MaxExtensionBulkSplit.class);
+
+ /**
+ * Static instance
+ */
+ public static final MaxExtensionBulkSplit STATIC = new MaxExtensionBulkSplit();
/**
* Constructor
@@ -146,4 +152,18 @@ public class MaxExtensionBulkSplit extends AbstractBulkSplit {
}
return splitAxis;
}
+
+ /**
+ * Parameterization class.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ public static class Parameterizer extends AbstractParameterizer {
+ @Override
+ protected MaxExtensionBulkSplit makeInstance() {
+ return MaxExtensionBulkSplit.STATIC;
+ }
+ }
} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/bulk/OneDimSortBulkSplit.java b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/bulk/OneDimSortBulkSplit.java
new file mode 100644
index 00000000..b99ae01e
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/bulk/OneDimSortBulkSplit.java
@@ -0,0 +1,86 @@
+package de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.strategies.bulk;
+
+/*
+ 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 <http://www.gnu.org/licenses/>.
+ */
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+
+import de.lmu.ifi.dbs.elki.data.spatial.SpatialComparable;
+import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
+
+/**
+ * Simple bulk loading strategy by sorting the data along the first dimension.
+ *
+ * This is also known as Nearest-X, and attributed to:
+ * <p>
+ * Roussopoulos, N. and Leifker, D.:<br />
+ * Direct spatial search on pictorial databases using packed R-trees<br />
+ * In: ACM SIGMOD Record 14-4
+ * </p>
+ *
+ * @author Erich Schubert
+ */
+@Reference(authors = "Roussopoulos, N. and Leifker, D.", title = "Direct spatial search on pictorial databases using packed R-trees", booktitle = "ACM SIGMOD Record 14-4", url = "http://dx.doi.org/10.1145/971699.318900")
+public class OneDimSortBulkSplit extends AbstractBulkSplit {
+ /**
+ * Static instance
+ */
+ public static final AbstractBulkSplit STATIC = new OneDimSortBulkSplit();
+
+ /**
+ * Constructor.
+ */
+ protected OneDimSortBulkSplit() {
+ super();
+ }
+
+ @Override
+ public <T extends SpatialComparable> List<List<T>> partition(List<T> spatialObjects, int minEntries, int maxEntries) {
+ // Sort by first dimension
+ Collections.sort(spatialObjects, new Comparator<SpatialComparable>() {
+ @Override
+ public int compare(SpatialComparable o1, SpatialComparable o2) {
+ double min1 = (o1.getMax(1) + o1.getMin(1)) / 2;
+ double min2 = (o2.getMax(1) + o2.getMin(1)) / 2;
+ return Double.compare(min1, min2);
+ }
+ });
+ return trivialPartition(spatialObjects, minEntries, maxEntries);
+ }
+
+ /**
+ * Parameterization class.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ public static class Parameterizer extends AbstractParameterizer {
+ @Override
+ protected AbstractBulkSplit makeInstance() {
+ return OneDimSortBulkSplit.STATIC;
+ }
+ }
+} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/bulk/SortTileRecursiveBulkSplit.java b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/bulk/SortTileRecursiveBulkSplit.java
new file mode 100644
index 00000000..28e96da6
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/bulk/SortTileRecursiveBulkSplit.java
@@ -0,0 +1,115 @@
+package de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.strategies.bulk;
+
+/*
+ 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 <http://www.gnu.org/licenses/>.
+ */
+import java.util.ArrayList;
+import java.util.Comparator;
+import java.util.List;
+
+import de.lmu.ifi.dbs.elki.data.spatial.SpatialComparable;
+import de.lmu.ifi.dbs.elki.utilities.datastructures.QuickSelect;
+import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
+
+/**
+ * Sort-Tile-Recursive aims at tiling the data space with a grid-like structure
+ * for partitioning the dataset into the required number of buckets.
+ *
+ * Reference:
+ * <p>
+ * Leutenegger, S.T. and Lopez, M.A. and Edgington, J.:<br />
+ * STR: A simple and efficient algorithm for R-tree packing<br />
+ * In: Proc. 13th International Conference on Data Engineering, 1997
+ * </p>
+ *
+ * @author Erich Schubert
+ */
+@Reference(authors = "Leutenegger, S.T. and Lopez, M.A. and Edgington, J.", title = "STR: A simple and efficient algorithm for R-tree packing", booktitle = "Proc. 13th International Conference on Data Engineering, 1997", url = "http://dx.doi.org/10.1109/ICDE.1997.582015")
+public class SortTileRecursiveBulkSplit extends AbstractBulkSplit {
+ @Override
+ public <T extends SpatialComparable> List<List<T>> partition(List<T> spatialObjects, int minEntries, int maxEntries) {
+ final int dims = spatialObjects.get(0).getDimensionality();
+ final int p = (int) Math.ceil(spatialObjects.size() / (double) maxEntries);
+ List<List<T>> ret = new ArrayList<List<T>>(p);
+ strPartition(spatialObjects, 0, spatialObjects.size(), 0, dims, maxEntries, new Compare<T>(), ret);
+ return ret;
+ }
+
+ /**
+ * Recursively partition.
+ *
+ * @param objs Object list
+ * @param start Subinterval start
+ * @param end Subinteval end
+ * @param depth Iteration depth (must be less than dimensionality!)
+ * @param dims Total number of dimensions
+ * @param maxEntries Maximum page size
+ * @param c Comparison helper
+ * @param ret Output list
+ */
+ protected <T extends SpatialComparable> void strPartition(List<T> objs, int start, int end, int depth, int dims, int maxEntries, Compare<T> c, List<List<T>> ret) {
+ c.dim = depth + 1;
+ final int p = (int) Math.ceil((end - start) / (double) maxEntries);
+ final int s = (int) Math.ceil(Math.pow(p, 1.0 / (dims - depth)));
+
+ final double len = end - start; // double intentional!
+ for(int i = 0; i < s; i++) {
+ // We don't completely sort, but only ensure the quantile is invariant.
+ int s2 = start + (int) ((i * len) / s);
+ int e2 = start + (int) (((i + 1) * len) / s);
+ // LoggingUtil.warning("STR " + dim + " s2:" + s2 + " e2:" + e2);
+ if(e2 < end) {
+ QuickSelect.quickSelect(objs, c, s2, end, e2);
+ }
+ if(depth + 1 == dims) {
+ ret.add(objs.subList(s2, e2));
+ }
+ else {
+ // Descend
+ strPartition(objs, s2, e2, depth + 1, dims, maxEntries, c, ret);
+ }
+ }
+ }
+
+ /**
+ * Comparison helper.
+ *
+ * @apiviz.exclude
+ *
+ * @author Erich Schubert
+ *
+ * @param <T> Type
+ */
+ private static class Compare<T extends SpatialComparable> implements Comparator<T> {
+ /**
+ * Current dimension
+ */
+ public int dim;
+
+ @Override
+ public int compare(T o1, T o2) {
+ final double v1 = o1.getMin(dim) + o1.getMax(dim);
+ final double v2 = o2.getMin(dim) + o2.getMax(dim);
+ return Double.compare(v1, v2);
+ }
+ }
+} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/bulk/SpatialSortBulkSplit.java b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/bulk/SpatialSortBulkSplit.java
new file mode 100644
index 00000000..9c3a41a1
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/bulk/SpatialSortBulkSplit.java
@@ -0,0 +1,107 @@
+package de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.strategies.bulk;
+
+/*
+ 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 <http://www.gnu.org/licenses/>.
+ */
+import java.util.List;
+
+import de.lmu.ifi.dbs.elki.data.spatial.SpatialComparable;
+import de.lmu.ifi.dbs.elki.math.spacefillingcurves.SpatialSorter;
+import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.OptionID;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ObjectParameter;
+
+/**
+ * Bulk loading by spatially sorting the objects, then partitioning the sorted
+ * list appropriately.
+ *
+ * Based conceptually on:
+ * <p>
+ * On packing R-trees<br/>
+ * Kamel, I. and Faloutsos, C.<br/>
+ * Proc. 2of the second international conference on Information and knowledge
+ * management
+ * </p>
+ *
+ * @apiviz.composedOf SpatialSorter
+ *
+ * @author Erich Schubert
+ */
+@Reference(title = "On packing R-trees", authors = "Kamel, I. and Faloutsos, C.", booktitle = "Proc. 2of the second international conference on Information and knowledge management", url = "http://dx.doi.org/10.1145/170088.170403")
+public class SpatialSortBulkSplit extends AbstractBulkSplit {
+ /**
+ * Sorting class
+ */
+ final SpatialSorter sorter;
+
+ /**
+ * Constructor.
+ *
+ * @param sorter Sorting strategy
+ */
+ protected SpatialSortBulkSplit(SpatialSorter sorter) {
+ super();
+ this.sorter = sorter;
+ }
+
+ @Override
+ public <T extends SpatialComparable> List<List<T>> partition(List<T> spatialObjects, int minEntries, int maxEntries) {
+ sorter.sort(spatialObjects);
+ return super.trivialPartition(spatialObjects, minEntries, maxEntries);
+ }
+
+ /**
+ * Parametization class
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ public static class Parameterizer extends AbstractParameterizer {
+ /**
+ * Option ID for spatial sorting
+ */
+ public static final OptionID SORTER_ID = OptionID.getOrCreateOptionID("rtree.bulk.spatial-sort", "Strategy for spatial sorting in bulk loading.");
+
+ /**
+ * Sorting class
+ */
+ SpatialSorter sorter;
+
+ @Override
+ protected void makeOptions(Parameterization config) {
+ super.makeOptions(config);
+
+ ObjectParameter<SpatialSorter> sorterP = new ObjectParameter<SpatialSorter>(SORTER_ID, SpatialSorter.class);
+ if(config.grab(sorterP)) {
+ sorter = sorterP.instantiateClass(config);
+ }
+ }
+
+ @Override
+ protected SpatialSortBulkSplit makeInstance() {
+ return new SpatialSortBulkSplit(sorter);
+ }
+ }
+}
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/bulk/package-info.java b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/bulk/package-info.java
index ab849373..0d01ba83 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/bulk/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/bulk/package-info.java
@@ -5,7 +5,7 @@
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
-Copyright (C) 2011
+Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
@@ -23,4 +23,4 @@ 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/>.
*/
-package de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.bulk; \ No newline at end of file
+package de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.strategies.bulk; \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/insert/ApproximativeLeastOverlapInsertionStrategy.java b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/insert/ApproximativeLeastOverlapInsertionStrategy.java
new file mode 100644
index 00000000..418e92c5
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/insert/ApproximativeLeastOverlapInsertionStrategy.java
@@ -0,0 +1,168 @@
+package de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.strategies.insert;
+/*
+ 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 <http://www.gnu.org/licenses/>.
+ */
+
+import java.util.Collections;
+
+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.utilities.datastructures.arraylike.ArrayAdapter;
+import de.lmu.ifi.dbs.elki.utilities.datastructures.heap.TopBoundedHeap;
+import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.OptionID;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.constraints.GreaterConstraint;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.IntParameter;
+import de.lmu.ifi.dbs.elki.utilities.pairs.DoubleIntPair;
+
+/**
+ * The choose subtree method proposed by the R*-Tree with slightly better
+ * performance for large leaf sizes (linear approximation).
+ *
+ * <p>
+ * N. Beckmann, H.-P. Kriegel, R. Schneider, B. Seeger:<br />
+ * The R*-tree: an efficient and robust access method for points and rectangles<br />
+ * in: Proceedings of the 1990 ACM SIGMOD International Conference on Management
+ * of Data, Atlantic City, NJ, May 23-25, 1990
+ * </p>
+ *
+ * @author Erich Schubert
+ * @author Franz Graf
+ * @author Marisa Petri
+ */
+@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 ApproximativeLeastOverlapInsertionStrategy extends LeastOverlapInsertionStrategy {
+ /**
+ * Number of candidates to consider
+ */
+ private int numCandidates = 32;
+
+ /**
+ * Constructor.
+ */
+ public ApproximativeLeastOverlapInsertionStrategy(int candidates) {
+ super();
+ this.numCandidates = candidates;
+ }
+
+ @Override
+ public <A> int choose(A options, ArrayAdapter<? extends SpatialComparable, A> getter, SpatialComparable obj, int height, int depth) {
+ final int size = getter.size(options);
+ assert (size > 0) : "Choose from empty set?";
+ if(size <= numCandidates) {
+ // Skip building the heap.
+ return super.choose(options, getter, obj, height, depth);
+ }
+
+ // Heap of candidates
+ TopBoundedHeap<DoubleIntPair> candidates = new TopBoundedHeap<DoubleIntPair>(numCandidates, Collections.reverseOrder());
+ for(int i = 0; i < size; i++) {
+ // Existing object and extended rectangle:
+ SpatialComparable entry = getter.get(options, i);
+ HyperBoundingBox mbr = SpatialUtil.union(entry, obj);
+ // Area increase
+ final double inc_area = SpatialUtil.volume(mbr) - SpatialUtil.volume(entry);
+ candidates.add(new DoubleIntPair(inc_area, i));
+ }
+
+ // R*-Tree: overlap increase for leaves.
+ int best = -1;
+ double least_overlap = Double.POSITIVE_INFINITY;
+ double least_areainc = Double.POSITIVE_INFINITY;
+ double least_area = Double.POSITIVE_INFINITY;
+ // least overlap increase, on reduced candidate set:
+ while(!candidates.isEmpty()) {
+ DoubleIntPair pair = candidates.poll();
+ final double inc_area = pair.first;
+
+ // Existing object and extended rectangle:
+ SpatialComparable entry = getter.get(options, pair.second);
+ HyperBoundingBox mbr = SpatialUtil.union(entry, obj);
+ // Compute relative overlap increase.
+ double overlap_wout = 0.0;
+ double overlap_with = 0.0;
+ for(int k = 0; k < size; k++) {
+ if(pair.second != k) {
+ SpatialComparable other = getter.get(options, k);
+ overlap_wout += SpatialUtil.relativeOverlap(entry, other);
+ overlap_with += SpatialUtil.relativeOverlap(mbr, other);
+ }
+ }
+ double inc_overlap = overlap_with - overlap_wout;
+ if(inc_overlap < least_overlap) {
+ final double area = SpatialUtil.volume(entry);
+ // Volume increase and overlap increase:
+ least_overlap = inc_overlap;
+ least_areainc = inc_area;
+ least_area = area;
+ best = pair.second;
+ }
+ else if(inc_overlap == least_overlap) {
+ final double area = SpatialUtil.volume(entry);
+ if(inc_area < least_areainc || (inc_area == least_areainc && area < least_area)) {
+ least_overlap = inc_overlap;
+ least_areainc = inc_area;
+ least_area = area;
+ best = pair.second;
+ }
+ }
+ }
+ assert (best > -1) : "No split found? Volume outside of double precision?";
+ return best;
+ }
+
+ /**
+ * Parameterization class.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ public static class Parameterizer extends AbstractParameterizer {
+ /**
+ * Fast-insertion parameter. Optional.
+ */
+ public static OptionID INSERTION_CANDIDATES_ID = OptionID.getOrCreateOptionID("rtree.insertion-candidates", "defines how many children are tested for finding the child generating the least overlap when inserting an object.");
+
+ /**
+ * The number of candidates to use
+ */
+ int numCandidates = 32;
+
+ @Override
+ protected void makeOptions(Parameterization config) {
+ super.makeOptions(config);
+ IntParameter insertionCandidatesP = new IntParameter(INSERTION_CANDIDATES_ID, new GreaterConstraint(0), numCandidates);
+ if(config.grab(insertionCandidatesP)) {
+ numCandidates = insertionCandidatesP.getValue();
+ }
+ }
+
+ @Override
+ protected ApproximativeLeastOverlapInsertionStrategy makeInstance() {
+ return new ApproximativeLeastOverlapInsertionStrategy(numCandidates);
+ }
+ }
+} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/insert/CombinedInsertionStrategy.java b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/insert/CombinedInsertionStrategy.java
new file mode 100644
index 00000000..c90d99b2
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/insert/CombinedInsertionStrategy.java
@@ -0,0 +1,127 @@
+package de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.strategies.insert;
+/*
+ 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 <http://www.gnu.org/licenses/>.
+ */
+
+import de.lmu.ifi.dbs.elki.data.spatial.SpatialComparable;
+import de.lmu.ifi.dbs.elki.utilities.datastructures.arraylike.ArrayAdapter;
+import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.OptionID;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ClassParameter;
+
+/**
+ * Use two different insertion strategies for directory and leaf nodes.
+ *
+ * Using two different strategies was likely first suggested in:
+ * <p>
+ * N. Beckmann, H.-P. Kriegel, R. Schneider, B. Seeger:<br />
+ * The R*-tree: an efficient and robust access method for points and rectangles<br />
+ * in: Proceedings of the 1990 ACM SIGMOD International Conference on Management
+ * of Data, Atlantic City, NJ, May 23-25, 1990
+ * </p>
+ *
+ * @author Erich Schubert
+ */
+@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 CombinedInsertionStrategy implements InsertionStrategy {
+ /**
+ * Strategy when inserting into directory nodes
+ */
+ InsertionStrategy dirStrategy;
+
+ /**
+ * Strategy when inserting into leaf nodes.
+ */
+ InsertionStrategy leafStrategy;
+
+ /**
+ * Constructor.
+ *
+ * @param dirStrategy Strategy for directory nodes
+ * @param leafStrategy Strategy for leaf nodes
+ */
+ public CombinedInsertionStrategy(InsertionStrategy dirStrategy, InsertionStrategy leafStrategy) {
+ super();
+ this.dirStrategy = dirStrategy;
+ this.leafStrategy = leafStrategy;
+ }
+
+ @Override
+ public <A> int choose(A options, ArrayAdapter<? extends SpatialComparable, A> getter, SpatialComparable obj, int height, int depth) {
+ if(depth + 1 >= height) {
+ return leafStrategy.choose(options, getter, obj, height, depth);
+ }
+ else {
+ return dirStrategy.choose(options, getter, obj, height, depth);
+ }
+ }
+
+ /**
+ * Parameterization class.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ public static class Parameterizer extends AbstractParameterizer {
+ /**
+ * Insertion strategy for directory nodes.
+ */
+ public static final OptionID DIR_STRATEGY_ID = OptionID.getOrCreateOptionID("rtree.insert-directory", "Insertion strategy for directory nodes.");
+
+ /**
+ * Insertion strategy for leaf nodes.
+ */
+ public static final OptionID LEAF_STRATEGY_ID = OptionID.getOrCreateOptionID("rtree.insert-leaf", "Insertion strategy for leaf nodes.");
+
+ /**
+ * Strategy when inserting into directory nodes
+ */
+ InsertionStrategy dirStrategy;
+
+ /**
+ * Strategy when inserting into leaf nodes.
+ */
+ InsertionStrategy leafStrategy;
+
+ @Override
+ protected void makeOptions(Parameterization config) {
+ super.makeOptions(config);
+ ClassParameter<InsertionStrategy> dirP = new ClassParameter<InsertionStrategy>(DIR_STRATEGY_ID, InsertionStrategy.class, LeastEnlargementWithAreaInsertionStrategy.class);
+ if(config.grab(dirP)) {
+ dirStrategy = dirP.instantiateClass(config);
+ }
+
+ ClassParameter<InsertionStrategy> leafP = new ClassParameter<InsertionStrategy>(LEAF_STRATEGY_ID, InsertionStrategy.class, LeastOverlapInsertionStrategy.class);
+ if(config.grab(leafP)) {
+ leafStrategy = leafP.instantiateClass(config);
+ }
+ }
+
+ @Override
+ protected CombinedInsertionStrategy makeInstance() {
+ return new CombinedInsertionStrategy(dirStrategy, leafStrategy);
+ }
+ }
+} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/util/InsertionStrategy.java b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/insert/InsertionStrategy.java
index 32f841b9..96294514 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/util/InsertionStrategy.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/insert/InsertionStrategy.java
@@ -1,10 +1,9 @@
-package de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.util;
-
+package de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.strategies.insert;
/*
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2011
+ Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
@@ -24,26 +23,24 @@ package de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.util;
*/
import de.lmu.ifi.dbs.elki.data.spatial.SpatialComparable;
-import de.lmu.ifi.dbs.elki.index.tree.Node;
-import de.lmu.ifi.dbs.elki.index.tree.TreeIndexPathComponent;
-import de.lmu.ifi.dbs.elki.index.tree.spatial.SpatialEntry;
+import de.lmu.ifi.dbs.elki.utilities.datastructures.arraylike.ArrayAdapter;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.Parameterizable;
/**
- * Interface for implementing insertion strategies, i.e. in which path of the
- * tree to insert the new element.
+ * RTree insertion strategy interface.
*
* @author Erich Schubert
*/
public interface InsertionStrategy extends Parameterizable {
/**
- * Find the child to insert into.
+ * Choose insertion rectangle.
*
- * @param <N> Node type
- * @param <E> Entry type
- * @param node Node to use
- * @param mbr MBR of entry to insert
- * @return Entry to insert into
+ * @param options Options to choose from
+ * @param getter Array adapter for options
+ * @param obj Insertion object
+ * @param height Tree height
+ * @param depth Insertion depth (depth == height - 1 indicates leaf level)
+ * @return Subtree index in array.
*/
- public <N extends Node<E>, E extends SpatialEntry> TreeIndexPathComponent<E> findInsertChild(N node, SpatialComparable mbr);
-}
+ public <A> int choose(A options, ArrayAdapter<? extends SpatialComparable, A> getter, SpatialComparable obj, int height, int depth);
+} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/insert/LeastEnlargementInsertionStrategy.java b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/insert/LeastEnlargementInsertionStrategy.java
new file mode 100644
index 00000000..eb211cb6
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/insert/LeastEnlargementInsertionStrategy.java
@@ -0,0 +1,89 @@
+package de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.strategies.insert;
+/*
+ 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 <http://www.gnu.org/licenses/>.
+ */
+
+import de.lmu.ifi.dbs.elki.data.spatial.SpatialComparable;
+import de.lmu.ifi.dbs.elki.data.spatial.SpatialUtil;
+import de.lmu.ifi.dbs.elki.utilities.datastructures.arraylike.ArrayAdapter;
+import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
+
+/**
+ * The default R-Tree insertion strategy: find rectangle with least volume
+ * enlargement.
+ *
+ * <p>
+ * Antonin Guttman:<br/>
+ * R-Trees: A Dynamic Index Structure For Spatial Searching<br />
+ * in Proceedings of the 1984 ACM SIGMOD international conference on Management
+ * of data.
+ * </p>
+ *
+ * @author Erich Schubert
+ */
+@Reference(authors = "Antonin Guttman", title = "R-Trees: A Dynamic Index Structure For Spatial Searching", booktitle = "Proceedings of the 1984 ACM SIGMOD international conference on Management of data", url = "http://dx.doi.org/10.1145/971697.602266")
+public class LeastEnlargementInsertionStrategy implements InsertionStrategy {
+ /**
+ * Static instance.
+ */
+ public static final LeastEnlargementInsertionStrategy STATIC = new LeastEnlargementInsertionStrategy();
+
+ /**
+ * Constructor.
+ */
+ public LeastEnlargementInsertionStrategy() {
+ super();
+ }
+
+ @Override
+ public <A> int choose(A options, ArrayAdapter<? extends SpatialComparable, A> getter, SpatialComparable obj, int height, int depth) {
+ final int size = getter.size(options);
+ assert (size > 0) : "Choose from empty set?";
+ double leastEnlargement = Double.POSITIVE_INFINITY;
+ int best = -1;
+ for(int i = 0; i < size; i++) {
+ SpatialComparable entry = getter.get(options, i);
+ double enlargement = SpatialUtil.enlargement(entry, obj);
+ if(enlargement < leastEnlargement) {
+ leastEnlargement = enlargement;
+ best = i;
+ }
+ }
+ assert (best > -1);
+ return best;
+ }
+
+ /**
+ * Parameterization class.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ public static class Parameterizer extends AbstractParameterizer {
+ @Override
+ protected LeastEnlargementInsertionStrategy makeInstance() {
+ return LeastEnlargementInsertionStrategy.STATIC;
+ }
+ }
+} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/insert/LeastEnlargementWithAreaInsertionStrategy.java b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/insert/LeastEnlargementWithAreaInsertionStrategy.java
new file mode 100644
index 00000000..977a132b
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/insert/LeastEnlargementWithAreaInsertionStrategy.java
@@ -0,0 +1,102 @@
+package de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.strategies.insert;
+
+/*
+ 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 <http://www.gnu.org/licenses/>.
+ */
+
+import de.lmu.ifi.dbs.elki.data.spatial.SpatialComparable;
+import de.lmu.ifi.dbs.elki.data.spatial.SpatialUtil;
+import de.lmu.ifi.dbs.elki.utilities.datastructures.arraylike.ArrayAdapter;
+import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
+
+/**
+ * A slight modification of the default R-Tree insertion strategy: find
+ * rectangle with least volume enlargement, but choose least area on ties.
+ *
+ * Proposed for non-leaf entries in:
+ * <p>
+ * N. Beckmann, H.-P. Kriegel, R. Schneider, B. Seeger:<br />
+ * The R*-tree: an efficient and robust access method for points and rectangles<br />
+ * in: Proceedings of the 1990 ACM SIGMOD International Conference on Management
+ * of Data, Atlantic City, NJ, May 23-25, 1990
+ * </p>
+ *
+ * @author Erich Schubert
+ */
+@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 LeastEnlargementWithAreaInsertionStrategy implements InsertionStrategy {
+ /**
+ * Static instance.
+ */
+ public static final LeastEnlargementWithAreaInsertionStrategy STATIC = new LeastEnlargementWithAreaInsertionStrategy();
+
+ /**
+ * Constructor.
+ */
+ public LeastEnlargementWithAreaInsertionStrategy() {
+ super();
+ }
+
+ @Override
+ public <A> int choose(A options, ArrayAdapter<? extends SpatialComparable, A> getter, SpatialComparable obj, int height, int depth) {
+ final int size = getter.size(options);
+ assert (size > 0) : "Choose from empty set?";
+ // As in R-Tree, with a slight modification for ties
+ double leastEnlargement = Double.POSITIVE_INFINITY;
+ double minArea = -1;
+ int best = -1;
+ for(int i = 0; i < size; i++) {
+ SpatialComparable entry = getter.get(options, i);
+ double enlargement = SpatialUtil.enlargement(entry, obj);
+ if(enlargement < leastEnlargement) {
+ leastEnlargement = enlargement;
+ best = i;
+ minArea = SpatialUtil.volume(entry);
+ }
+ else if(enlargement == leastEnlargement) {
+ final double area = SpatialUtil.volume(entry);
+ if(area < minArea) {
+ // Tie handling proposed by R*:
+ best = i;
+ minArea = area;
+ }
+ }
+ }
+ assert (best > -1);
+ return best;
+ }
+
+ /**
+ * Parameterization class.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ public static class Parameterizer extends AbstractParameterizer {
+ @Override
+ protected LeastEnlargementWithAreaInsertionStrategy makeInstance() {
+ return LeastEnlargementWithAreaInsertionStrategy.STATIC;
+ }
+ }
+} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/insert/LeastOverlapInsertionStrategy.java b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/insert/LeastOverlapInsertionStrategy.java
new file mode 100644
index 00000000..2eba8912
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/insert/LeastOverlapInsertionStrategy.java
@@ -0,0 +1,120 @@
+package de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.strategies.insert;
+/*
+ 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 <http://www.gnu.org/licenses/>.
+ */
+
+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.utilities.datastructures.arraylike.ArrayAdapter;
+import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
+
+/**
+ * The choose subtree method proposed by the R*-Tree for leaf nodes.
+ *
+ * <p>
+ * N. Beckmann, H.-P. Kriegel, R. Schneider, B. Seeger:<br />
+ * The R*-tree: an efficient and robust access method for points and rectangles<br />
+ * in: Proceedings of the 1990 ACM SIGMOD International Conference on Management
+ * of Data, Atlantic City, NJ, May 23-25, 1990
+ * </p>
+ *
+ * @author Erich Schubert
+ */
+@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 LeastOverlapInsertionStrategy implements InsertionStrategy {
+ /**
+ * Static instance.
+ */
+ public static final LeastOverlapInsertionStrategy STATIC = new LeastOverlapInsertionStrategy();
+
+ /**
+ * Constructor.
+ */
+ public LeastOverlapInsertionStrategy() {
+ super();
+ }
+
+ @Override
+ public <A> int choose(A options, ArrayAdapter<? extends SpatialComparable, A> getter, SpatialComparable obj, int height, int depth) {
+ final int size = getter.size(options);
+ assert (size > 0) : "Choose from empty set?";
+ // R*-Tree: overlap increase for leaves.
+ int best = -1;
+ double least_overlap = Double.POSITIVE_INFINITY;
+ double least_areainc = Double.POSITIVE_INFINITY;
+ double least_area = Double.POSITIVE_INFINITY;
+ // least overlap increase, on reduced candidate set:
+ for(int i = 0; i < size; i++) {
+ // Existing object and extended rectangle:
+ SpatialComparable entry = getter.get(options, i);
+ HyperBoundingBox mbr = SpatialUtil.union(entry, obj);
+ // Compute relative overlap increase.
+ double overlap_wout = 0.0;
+ double overlap_with = 0.0;
+ for(int k = 0; k < size; k++) {
+ if(i != k) {
+ SpatialComparable other = getter.get(options, k);
+ overlap_wout += SpatialUtil.relativeOverlap(entry, other);
+ overlap_with += SpatialUtil.relativeOverlap(mbr, other);
+ }
+ }
+ double inc_overlap = overlap_with - overlap_wout;
+ if(inc_overlap < least_overlap) {
+ final double area = SpatialUtil.volume(entry);
+ final double inc_area = SpatialUtil.volume(mbr) - area;
+ // Volume increase and overlap increase:
+ least_overlap = inc_overlap;
+ least_areainc = inc_area;
+ least_area = area;
+ best = i;
+ }
+ else if(inc_overlap == least_overlap) {
+ final double area = SpatialUtil.volume(entry);
+ final double inc_area = SpatialUtil.volume(mbr) - area;
+ if(inc_area < least_areainc || (inc_area == least_areainc && area < least_area)) {
+ least_overlap = inc_overlap;
+ least_areainc = inc_area;
+ least_area = area;
+ best = i;
+ }
+ }
+ }
+ assert (best > -1) : "No split found? Volume outside of double precision?";
+ return best;
+ }
+
+ /**
+ * Parameterization class.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ public static class Parameterizer extends AbstractParameterizer {
+ @Override
+ protected LeastOverlapInsertionStrategy makeInstance() {
+ return LeastOverlapInsertionStrategy.STATIC;
+ }
+ }
+} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/insert/package-info.java b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/insert/package-info.java
new file mode 100644
index 00000000..ad54e1e1
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/insert/package-info.java
@@ -0,0 +1,26 @@
+/**
+ * <p>Insertion strategies for R-Trees</p>
+ */
+/*
+ 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 <http://www.gnu.org/licenses/>.
+ */
+package de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.strategies.insert; \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/overflow/LimitedReinsertOverflowTreatment.java b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/overflow/LimitedReinsertOverflowTreatment.java
new file mode 100644
index 00000000..2532f351
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/overflow/LimitedReinsertOverflowTreatment.java
@@ -0,0 +1,135 @@
+package de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.strategies.overflow;
+
+/*
+ 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 <http://www.gnu.org/licenses/>.
+ */
+
+import java.util.BitSet;
+
+import de.lmu.ifi.dbs.elki.distance.distancefunction.SquaredEuclideanDistanceFunction;
+import de.lmu.ifi.dbs.elki.index.tree.IndexTreePath;
+import de.lmu.ifi.dbs.elki.index.tree.spatial.SpatialEntry;
+import de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.AbstractRStarTree;
+import de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.AbstractRStarTreeNode;
+import de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.strategies.reinsert.CloseReinsert;
+import de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.strategies.reinsert.ReinsertStrategy;
+import de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.util.NodeArrayAdapter;
+import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.OptionID;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ObjectParameter;
+
+/**
+ * Limited reinsertions, as proposed by the R*-Tree: For each real insert, allow
+ * reinsertions to happen only once per level.
+ *
+ * @author Erich Schubert
+ */
+@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 LimitedReinsertOverflowTreatment implements OverflowTreatment {
+ /**
+ * Default insert strategy used by R*-tree
+ */
+ public static final LimitedReinsertOverflowTreatment RSTAR_OVERFLOW = new LimitedReinsertOverflowTreatment(new CloseReinsert(0.3, SquaredEuclideanDistanceFunction.STATIC));
+
+ /**
+ * Bitset to keep track of levels a reinsert has been performed at.
+ */
+ private BitSet reinsertions = new BitSet();
+
+ /**
+ * Strategy for the actual reinsertions
+ */
+ private final ReinsertStrategy reinsertStrategy;
+
+ /**
+ * Constructor.
+ *
+ * @param reinsertStrategy Reinsertion strategy
+ */
+ public LimitedReinsertOverflowTreatment(ReinsertStrategy reinsertStrategy) {
+ super();
+ this.reinsertStrategy = reinsertStrategy;
+ }
+
+ @Override
+ public <N extends AbstractRStarTreeNode<N, E>, E extends SpatialEntry> boolean handleOverflow(AbstractRStarTree<N, E> tree, N node, IndexTreePath<E> path) {
+ final int level = /* tree.getHeight() - */(path.getPathCount() - 1);
+ // No reinsertions at root level
+ if(path.getPathCount() == 1) {
+ return false;
+ }
+ // Earlier reinsertions at the same level
+ if(reinsertions.get(level)) {
+ return false;
+ }
+
+ reinsertions.set(level);
+ final E entry = path.getLastPathComponent().getEntry();
+ assert (!entry.isLeafEntry()) : "Unexpected leaf entry";
+ int[] cands = reinsertStrategy.computeReinserts(node, NodeArrayAdapter.STATIC, entry);
+ if(cands == null || cands.length == 0) {
+ return false;
+ }
+ tree.reInsert(node, path, cands);
+ return true;
+ }
+
+ @Override
+ public void reinitialize() {
+ reinsertions.clear();
+ }
+
+ /**
+ * Parameterization class.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ public static class Parameterizer extends AbstractParameterizer {
+ /**
+ * Fast-insertion parameter. Optional.
+ */
+ public static OptionID REINSERT_STRATEGY_ID = OptionID.getOrCreateOptionID("rtree.reinsertion-strategy", "The strategy to select candidates for reinsertion.");
+
+ /**
+ * The actual reinsertion strategy
+ */
+ ReinsertStrategy reinsertStrategy = null;
+
+ @Override
+ protected void makeOptions(Parameterization config) {
+ super.makeOptions(config);
+ ObjectParameter<ReinsertStrategy> strategyP = new ObjectParameter<ReinsertStrategy>(REINSERT_STRATEGY_ID, ReinsertStrategy.class, CloseReinsert.class);
+ if(config.grab(strategyP)) {
+ reinsertStrategy = strategyP.instantiateClass(config);
+ }
+ }
+
+ @Override
+ protected LimitedReinsertOverflowTreatment makeInstance() {
+ return new LimitedReinsertOverflowTreatment(reinsertStrategy);
+ }
+ }
+} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/overflow/OverflowTreatment.java b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/overflow/OverflowTreatment.java
new file mode 100644
index 00000000..87d09038
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/overflow/OverflowTreatment.java
@@ -0,0 +1,53 @@
+package de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.strategies.overflow;
+
+/*
+ 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 <http://www.gnu.org/licenses/>.
+ */
+
+import de.lmu.ifi.dbs.elki.index.tree.IndexTreePath;
+import de.lmu.ifi.dbs.elki.index.tree.spatial.SpatialEntry;
+import de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.AbstractRStarTree;
+import de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.AbstractRStarTreeNode;
+
+/**
+ * Reinsertion strategy to resolve overflows in the RStarTree.
+ *
+ * @author Erich Schubert
+ */
+public interface OverflowTreatment {
+ /**
+ * Reinitialize the reinsertion treatment (for a new primary insertion).
+ */
+ public void reinitialize();
+
+ /**
+ * Handle overflow in the given node.
+ *
+ * @param <N> Node
+ * @param <E> Entry
+ * @param tree Tree
+ * @param node Node
+ * @param path Path
+ * @return true when already handled (e.g. by reinserting)
+ */
+ <N extends AbstractRStarTreeNode<N, E>, E extends SpatialEntry> boolean handleOverflow(AbstractRStarTree<N, E> tree, N node, IndexTreePath<E> path);
+} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/overflow/SplitOnlyOverflowTreatment.java b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/overflow/SplitOnlyOverflowTreatment.java
new file mode 100644
index 00000000..cfbcf6a9
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/overflow/SplitOnlyOverflowTreatment.java
@@ -0,0 +1,73 @@
+package de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.strategies.overflow;
+
+/*
+ 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 <http://www.gnu.org/licenses/>.
+ */
+
+import de.lmu.ifi.dbs.elki.index.tree.IndexTreePath;
+import de.lmu.ifi.dbs.elki.index.tree.spatial.SpatialEntry;
+import de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.AbstractRStarTree;
+import de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.AbstractRStarTreeNode;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
+
+/**
+ * Always split, as in the original R-Tree
+ *
+ * @author Erich Schubert
+ */
+public class SplitOnlyOverflowTreatment implements OverflowTreatment {
+ /**
+ * Static instance
+ */
+ public static final SplitOnlyOverflowTreatment STATIC = new SplitOnlyOverflowTreatment();
+
+ /**
+ * Constructor
+ */
+ public SplitOnlyOverflowTreatment() {
+ super();
+ }
+
+ @Override
+ public <N extends AbstractRStarTreeNode<N, E>, E extends SpatialEntry> boolean handleOverflow(AbstractRStarTree<N, E> tree, N node, IndexTreePath<E> path) {
+ return false;
+ }
+
+ @Override
+ public void reinitialize() {
+ // Nothing to do
+ }
+
+ /**
+ * Parameterization class.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ public static class Parameterizer extends AbstractParameterizer {
+ @Override
+ protected SplitOnlyOverflowTreatment makeInstance() {
+ return SplitOnlyOverflowTreatment.STATIC;
+ }
+ }
+} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/overflow/package-info.java b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/overflow/package-info.java
new file mode 100644
index 00000000..30899736
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/overflow/package-info.java
@@ -0,0 +1,26 @@
+/**
+ * <p>Overflow treatment strategies for R-Trees</p>
+ */
+/*
+ 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 <http://www.gnu.org/licenses/>.
+ */
+package de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.strategies.overflow; \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/package-info.java b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/package-info.java
new file mode 100644
index 00000000..41e2eb0b
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/package-info.java
@@ -0,0 +1,26 @@
+/**
+ * <p>Various strategies for R-Trees and variants.</p>
+ */
+/*
+ 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 <http://www.gnu.org/licenses/>.
+ */
+package de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.strategies; \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/reinsert/AbstractPartialReinsert.java b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/reinsert/AbstractPartialReinsert.java
new file mode 100644
index 00000000..e0277606
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/reinsert/AbstractPartialReinsert.java
@@ -0,0 +1,105 @@
+package de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.strategies.reinsert;
+
+/*
+ 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 <http://www.gnu.org/licenses/>.
+ */
+
+import de.lmu.ifi.dbs.elki.distance.distancefunction.SpatialPrimitiveDoubleDistanceFunction;
+import de.lmu.ifi.dbs.elki.distance.distancefunction.SquaredEuclideanDistanceFunction;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.OptionID;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.constraints.IntervalConstraint;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.DoubleParameter;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ObjectParameter;
+
+/**
+ * Abstract base class for reinsertion strategies that have a "relative amount"
+ * parameter to partially reinsert entries.
+ *
+ * @author Erich Schubert
+ */
+public abstract class AbstractPartialReinsert implements ReinsertStrategy {
+ /**
+ * Amount of entries to reinsert
+ */
+ protected double reinsertAmount = 0.3;
+
+ /**
+ * Distance function to use for measuring
+ */
+ SpatialPrimitiveDoubleDistanceFunction<?> distanceFunction;
+
+ /**
+ * Constructor.
+ *
+ * @param reinsertAmount Relative amount of objects to reinsert.
+ * @param distanceFunction Distance function to use
+ */
+ public AbstractPartialReinsert(double reinsertAmount, SpatialPrimitiveDoubleDistanceFunction<?> distanceFunction) {
+ super();
+ this.reinsertAmount = reinsertAmount;
+ this.distanceFunction = distanceFunction;
+ }
+
+ /**
+ * Parameterization class.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ public static abstract class Parameterizer extends AbstractParameterizer {
+ /**
+ * Reinsertion share
+ */
+ public static OptionID REINSERT_AMOUNT_ID = OptionID.getOrCreateOptionID("rtree.reinsertion-amount", "The amount of entries to reinsert.");
+
+ /**
+ * Reinsertion share
+ */
+ public static OptionID REINSERT_DISTANCE_ID = OptionID.getOrCreateOptionID("rtree.reinsertion-distancce", "The distance function to compute reinsertion candidates by.");
+
+ /**
+ * The actual reinsertion strategy
+ */
+ double reinsertAmount = 0.3;
+
+ /**
+ * Distance function to use for measuring
+ */
+ SpatialPrimitiveDoubleDistanceFunction<?> distanceFunction;
+
+ @Override
+ protected void makeOptions(Parameterization config) {
+ super.makeOptions(config);
+ DoubleParameter reinsertAmountP = new DoubleParameter(REINSERT_AMOUNT_ID, new IntervalConstraint(0.0, IntervalConstraint.IntervalBoundary.OPEN, 0.5, IntervalConstraint.IntervalBoundary.OPEN), 0.3);
+ if(config.grab(reinsertAmountP)) {
+ reinsertAmount = reinsertAmountP.getValue();
+ }
+ ObjectParameter<SpatialPrimitiveDoubleDistanceFunction<?>> distanceP = new ObjectParameter<SpatialPrimitiveDoubleDistanceFunction<?>>(REINSERT_DISTANCE_ID, SpatialPrimitiveDoubleDistanceFunction.class, SquaredEuclideanDistanceFunction.class);
+ if(config.grab(distanceP)) {
+ distanceFunction = distanceP.instantiateClass(config);
+ }
+ }
+ }
+}
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/reinsert/CloseReinsert.java b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/reinsert/CloseReinsert.java
new file mode 100644
index 00000000..12a4ed0f
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/reinsert/CloseReinsert.java
@@ -0,0 +1,88 @@
+package de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.strategies.reinsert;
+
+import java.util.Arrays;
+import java.util.Collections;
+
+import de.lmu.ifi.dbs.elki.data.DoubleVector;
+import de.lmu.ifi.dbs.elki.data.spatial.SpatialComparable;
+import de.lmu.ifi.dbs.elki.data.spatial.SpatialUtil;
+import de.lmu.ifi.dbs.elki.distance.distancefunction.SpatialPrimitiveDoubleDistanceFunction;
+import de.lmu.ifi.dbs.elki.utilities.datastructures.arraylike.ArrayAdapter;
+import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
+import de.lmu.ifi.dbs.elki.utilities.pairs.DoubleIntPair;
+
+/*
+ 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 <http://www.gnu.org/licenses/>.
+ */
+
+/**
+ * Reinsert objects on page overflow, starting with close objects first (even
+ * when they will likely be inserted into the same page again!)
+ *
+ * The strategy preferred by the R*-Tree
+ *
+ * @author Erich Schubert
+ */
+@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 CloseReinsert extends AbstractPartialReinsert {
+ /**
+ * Constructor.
+ *
+ * @param reinsertAmount Amount of objects to reinsert
+ * @param distanceFunction Distance function to use for reinsertion
+ */
+ public CloseReinsert(double reinsertAmount, SpatialPrimitiveDoubleDistanceFunction<?> distanceFunction) {
+ super(reinsertAmount, distanceFunction);
+ }
+
+ @Override
+ public <A> int[] computeReinserts(A entries, ArrayAdapter<? extends SpatialComparable, ? super A> getter, SpatialComparable page) {
+ DoubleIntPair[] order = new DoubleIntPair[getter.size(entries)];
+ DoubleVector centroid = new DoubleVector(SpatialUtil.centroid(page));
+ for(int i = 0; i < order.length; i++) {
+ double distance = distanceFunction.doubleMinDist(new DoubleVector(SpatialUtil.centroid(getter.get(entries, i))), centroid);
+ order[i] = new DoubleIntPair(distance, i);
+ }
+ Arrays.sort(order, Collections.reverseOrder());
+
+ int num = (int) (reinsertAmount * order.length);
+ int[] re = new int[num];
+ for(int i = 0; i < num; i++) {
+ re[i] = order[num - 1 - i].second;
+ }
+ return re;
+ }
+
+ /**
+ * Parameterization class.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ public static class Parameterizer extends AbstractPartialReinsert.Parameterizer {
+ @Override
+ protected Object makeInstance() {
+ return new CloseReinsert(reinsertAmount, distanceFunction);
+ }
+ }
+} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/reinsert/FarReinsert.java b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/reinsert/FarReinsert.java
new file mode 100644
index 00000000..771f56fb
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/reinsert/FarReinsert.java
@@ -0,0 +1,88 @@
+package de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.strategies.reinsert;
+
+import java.util.Arrays;
+import java.util.Collections;
+
+import de.lmu.ifi.dbs.elki.data.DoubleVector;
+import de.lmu.ifi.dbs.elki.data.spatial.SpatialComparable;
+import de.lmu.ifi.dbs.elki.data.spatial.SpatialUtil;
+import de.lmu.ifi.dbs.elki.distance.distancefunction.SpatialPrimitiveDoubleDistanceFunction;
+import de.lmu.ifi.dbs.elki.utilities.datastructures.arraylike.ArrayAdapter;
+import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
+import de.lmu.ifi.dbs.elki.utilities.pairs.DoubleIntPair;
+
+/*
+ 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 <http://www.gnu.org/licenses/>.
+ */
+
+/**
+ * Reinsert objects on page overflow, starting with farther objects first (even
+ * when they will likely be inserted into the same page again!)
+ *
+ * Alternative strategy mentioned in the R*-tree
+ *
+ * @author Erich Schubert
+ */
+@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 FarReinsert extends AbstractPartialReinsert {
+ /**
+ * Constructor.
+ *
+ * @param reinsertAmount Amount to reinsert
+ * @param distanceFunction Distance function
+ */
+ public FarReinsert(double reinsertAmount, SpatialPrimitiveDoubleDistanceFunction<?> distanceFunction) {
+ super(reinsertAmount, distanceFunction);
+ }
+
+ @Override
+ public <A> int[] computeReinserts(A entries, ArrayAdapter<? extends SpatialComparable, ? super A> getter, SpatialComparable page) {
+ DoubleIntPair[] order = new DoubleIntPair[getter.size(entries)];
+ DoubleVector centroid = new DoubleVector(SpatialUtil.centroid(page));
+ for(int i = 0; i < order.length; i++) {
+ double distance = distanceFunction.doubleMinDist(new DoubleVector(SpatialUtil.centroid(getter.get(entries, i))), centroid);
+ order[i] = new DoubleIntPair(distance, i);
+ }
+ Arrays.sort(order, Collections.reverseOrder());
+
+ int num = (int) (reinsertAmount * order.length);
+ int[] re = new int[num];
+ for(int i = 0; i < num; i++) {
+ re[i] = order[i].second;
+ }
+ return re;
+ }
+
+ /**
+ * Parameterization class.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ public static class Parameterizer extends AbstractPartialReinsert.Parameterizer {
+ @Override
+ protected Object makeInstance() {
+ return new CloseReinsert(reinsertAmount, distanceFunction);
+ }
+ }
+} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/reinsert/ReinsertStrategy.java b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/reinsert/ReinsertStrategy.java
new file mode 100644
index 00000000..cba96367
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/reinsert/ReinsertStrategy.java
@@ -0,0 +1,44 @@
+package de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.strategies.reinsert;
+
+/*
+ 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 <http://www.gnu.org/licenses/>.
+ */
+
+import de.lmu.ifi.dbs.elki.data.spatial.SpatialComparable;
+import de.lmu.ifi.dbs.elki.utilities.datastructures.arraylike.ArrayAdapter;
+
+/**
+ * Reinsertion strategy to resolve overflows in the RStarTree.
+ *
+ * @author Erich Schubert
+ */
+public interface ReinsertStrategy {
+ /**
+ * Perform reinsertions.
+ *
+ * @param entries Entries in overflowing node
+ * @param getter Adapter for the entries array
+ * @param page Spatial extend of the page
+ * @return index of pages to reinsert.
+ */
+ public <A> int[] computeReinserts(A entries, ArrayAdapter<? extends SpatialComparable, ? super A> getter, SpatialComparable page);
+}
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/reinsert/package-info.java b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/reinsert/package-info.java
new file mode 100644
index 00000000..f6a6f6e9
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/reinsert/package-info.java
@@ -0,0 +1,26 @@
+/**
+ * <p>Reinsertion strategies for R-Trees</p>
+ */
+/*
+ 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 <http://www.gnu.org/licenses/>.
+ */
+package de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.strategies.reinsert; \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/split/AngTanLinearSplit.java b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/split/AngTanLinearSplit.java
new file mode 100644
index 00000000..e59fe10e
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/split/AngTanLinearSplit.java
@@ -0,0 +1,193 @@
+package de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.strategies.split;
+
+/*
+ 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 <http://www.gnu.org/licenses/>.
+ */
+
+import java.util.BitSet;
+import java.util.Random;
+
+import de.lmu.ifi.dbs.elki.data.ModifiableHyperBoundingBox;
+import de.lmu.ifi.dbs.elki.data.spatial.SpatialComparable;
+import de.lmu.ifi.dbs.elki.data.spatial.SpatialUtil;
+import de.lmu.ifi.dbs.elki.logging.Logging;
+import de.lmu.ifi.dbs.elki.utilities.Util;
+import de.lmu.ifi.dbs.elki.utilities.datastructures.arraylike.ArrayAdapter;
+import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
+import de.lmu.ifi.dbs.elki.utilities.exceptions.AbortException;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
+
+/**
+ * Line-time complexity split proposed by Ang and Tan.
+ *
+ * This split strategy tries to minimize overlap only, which can however
+ * degenerate to "slices".
+ *
+ * <p>
+ * C. H. Ang and T. C. Tan:<br />
+ * New linear node splitting algorithm for R-trees<br />
+ * In: Proceedings of the 5th International Symposium on Advances in Spatial
+ * Databases
+ * </p>
+ *
+ * @author Erich Schubert
+ */
+@Reference(authors = "C. H. Ang and T. C. Tan", title = "New linear node splitting algorithm for R-trees", booktitle = "Proceedings of the 5th International Symposium on Advances in Spatial Databases", url = "http://dx.doi.org/10.1007/3-540-63238-7_38")
+public class AngTanLinearSplit implements SplitStrategy {
+ /**
+ * Logger class
+ */
+ private static final Logging logger = Logging.getLogger(AngTanLinearSplit.class);
+
+ /**
+ * Static instance.
+ */
+ public static final AngTanLinearSplit STATIC = new AngTanLinearSplit();
+
+ @Override
+ public <E extends SpatialComparable, A> BitSet split(A entries, ArrayAdapter<E, A> getter, int minEntries) {
+ final int num = getter.size(entries);
+ // We need the overall MBR for computing edge preferences
+ ModifiableHyperBoundingBox total = new ModifiableHyperBoundingBox(getter.get(entries, 0));
+ {
+ for(int i = 1; i < num; i++) {
+ total.extend(getter.get(entries, i));
+ }
+ }
+ final int dim = total.getDimensionality();
+ // Prepare the axis lists (we use bitsets)
+ BitSet[] closer = new BitSet[dim];
+ {
+ for(int d = 0; d < dim; d++) {
+ closer[d] = new BitSet();
+ }
+ for(int i = 0; i < num; i++) {
+ E e = getter.get(entries, i);
+ for(int d = 1; d <= dim; d++) {
+ double low = e.getMin(d) - total.getMin(d);
+ double hig = total.getMax(d) - e.getMax(d);
+ if(low >= hig) {
+ closer[d - 1].set(i);
+ }
+ }
+ }
+ }
+ // Find the most even split
+ {
+ int axis = -1;
+ int bestcard = Integer.MAX_VALUE;
+ BitSet bestset = null;
+ double bestover = Double.NaN;
+ for(int d = 0; d < dim; d++) {
+ BitSet cand = closer[d];
+ int card = cand.cardinality();
+ card = Math.max(card, num - card);
+ if(card == num) {
+ continue;
+ }
+ if(card < bestcard) {
+ axis = d + 1;
+ bestcard = card;
+ bestset = cand;
+ bestover = Double.NaN;
+ }
+ else if(card == bestcard) {
+ // Tie handling
+ if(Double.isNaN(bestover)) {
+ bestover = computeOverlap(entries, getter, bestset);
+ }
+ double overlap = computeOverlap(entries, getter, cand);
+ if(overlap < bestover) {
+ axis = d + 1;
+ bestcard = card;
+ bestset = cand;
+ bestover = overlap;
+ }
+ else if(overlap == bestover) {
+ double bestlen = total.getMax(axis) - total.getMin(axis);
+ double candlen = total.getMax(d + 1) - total.getMin(d + 1);
+ if(candlen < bestlen) {
+ axis = d + 1;
+ bestcard = card;
+ bestset = cand;
+ bestover = overlap;
+ }
+ }
+ }
+ }
+ if(bestset == null) {
+ logger.warning("No Ang-Tan-Split found. Probably all points are the same? Returning random split.");
+ return Util.randomBitSet(num / 2, num, new Random());
+ }
+ return bestset;
+ }
+ }
+
+ /**
+ * Compute overlap of assignment
+ *
+ * @param entries Entries
+ * @param getter Entry accessor
+ * @param assign Assignment
+ * @return Overlap amount
+ */
+ protected <E extends SpatialComparable, A> double computeOverlap(A entries, ArrayAdapter<E, A> getter, BitSet assign) {
+ ModifiableHyperBoundingBox mbr1 = null, mbr2 = null;
+ for(int i = 0; i < getter.size(entries); i++) {
+ E e = getter.get(entries, i);
+ if(assign.get(i)) {
+ if(mbr1 == null) {
+ mbr1 = new ModifiableHyperBoundingBox(e);
+ }
+ else {
+ mbr1.extend(e);
+ }
+ }
+ else {
+ if(mbr2 == null) {
+ mbr2 = new ModifiableHyperBoundingBox(e);
+ }
+ else {
+ mbr2.extend(e);
+ }
+ }
+ }
+ if(mbr1 == null || mbr2 == null) {
+ throw new AbortException("Invalid state in split: one of the sets is empty.");
+ }
+ return SpatialUtil.overlap(mbr1, mbr2);
+ }
+
+ /**
+ * Parameterization class.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ public static class Parameterizer extends AbstractParameterizer {
+ @Override
+ protected AngTanLinearSplit makeInstance() {
+ return AngTanLinearSplit.STATIC;
+ }
+ }
+} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/split/GreeneSplit.java b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/split/GreeneSplit.java
new file mode 100644
index 00000000..7401fbe5
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/split/GreeneSplit.java
@@ -0,0 +1,158 @@
+package de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.strategies.split;
+
+/*
+ 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 <http://www.gnu.org/licenses/>.
+ */
+
+import java.util.Arrays;
+import java.util.BitSet;
+
+import de.lmu.ifi.dbs.elki.data.ModifiableHyperBoundingBox;
+import de.lmu.ifi.dbs.elki.data.spatial.SpatialComparable;
+import de.lmu.ifi.dbs.elki.data.spatial.SpatialUtil;
+import de.lmu.ifi.dbs.elki.utilities.datastructures.arraylike.ArrayAdapter;
+import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
+import de.lmu.ifi.dbs.elki.utilities.pairs.DoubleIntPair;
+
+/**
+ * Quadratic-time complexity split as used by Diane Greene for the R-Tree.
+ *
+ * Seed selection is quadratic, distribution is O(n log n).
+ *
+ * This contains a slight modification to improve performance with point data:
+ * with points as seeds, the normalized separation is always 1, so we choose the
+ * raw separation then.
+ *
+ * <p>
+ * Diane Greene:<br />
+ * An implementation and performance analysis of spatial data access methods<br />
+ * In: Proceedings of the Fifth International Conference on Data Engineering
+ * </p>
+ *
+ * @author Erich Schubert
+ */
+@Reference(authors = "Diane Greene", title = "An implementation and performance analysis of spatial data access methods", booktitle = "Proceedings of the Fifth International Conference on Data Engineering", url = "http://dx.doi.org/10.1109/ICDE.1989.47268")
+public class GreeneSplit implements SplitStrategy {
+ /**
+ * Static instance.
+ */
+ public static final GreeneSplit STATIC = new GreeneSplit();
+
+ @Override
+ public <E extends SpatialComparable, A> BitSet split(A entries, ArrayAdapter<E, A> getter, int minEntries) {
+ final int num = getter.size(entries);
+ // Choose axis by best normalized separation
+ int axis = -1;
+ {
+ // PickSeeds - find the two most distant rectangles
+ double worst = Double.NEGATIVE_INFINITY;
+ int w1 = 0, w2 = 0;
+
+ // Compute individual areas
+ double[] areas = new double[num];
+ for(int e1 = 0; e1 < num - 1; e1++) {
+ final E e1i = getter.get(entries, e1);
+ areas[e1] = SpatialUtil.volume(e1i);
+ }
+ // Compute area increase
+ for(int e1 = 0; e1 < num - 1; e1++) {
+ final E e1i = getter.get(entries, e1);
+ for(int e2 = e1 + 1; e2 < num; e2++) {
+ final E e2i = getter.get(entries, e2);
+ final double areaJ = SpatialUtil.volumeUnion(e1i, e2i);
+ final double d = areaJ - areas[e1] - areas[e2];
+ if(d > worst) {
+ worst = d;
+ w1 = e1;
+ w2 = e2;
+ }
+ }
+ }
+ // Data to keep
+ // Initial mbrs and areas
+ E m1 = getter.get(entries, w1);
+ E m2 = getter.get(entries, w2);
+
+ double bestsep = Double.NEGATIVE_INFINITY;
+ double bestsep2 = Double.NEGATIVE_INFINITY;
+ for(int d = 1; d <= m1.getDimensionality(); d++) {
+ final double s1 = m1.getMin(d) - m2.getMax(d);
+ final double s2 = m2.getMin(d) - m1.getMax(d);
+ final double sm = Math.max(s1, s2);
+ final double no = Math.max(m1.getMax(d), m2.getMax(d)) - Math.min(m1.getMin(d), m2.getMin(d));
+ final double sep = sm / no;
+ if(sep > bestsep || (sep == bestsep && sm > bestsep2)) {
+ bestsep = sep;
+ bestsep2 = sm;
+ axis = d;
+ }
+ }
+ }
+ // Sort by minimum value
+ DoubleIntPair[] data = new DoubleIntPair[num];
+ for(int i = 0; i < num; i++) {
+ data[i] = new DoubleIntPair(getter.get(entries, i).getMin(axis), i);
+ }
+ Arrays.sort(data);
+ // Object assignment
+ final BitSet assignment = new BitSet(num);
+ final int half = (num + 1) / 2;
+ // Put the first half into second node
+ for(int i = 0; i < half; i++) {
+ assignment.set(data[i].second);
+ }
+ // Tie handling
+ if(num % 2 == 0) {
+ // We need to compute the bounding boxes
+ ModifiableHyperBoundingBox mbr1 = new ModifiableHyperBoundingBox(getter.get(entries, data[0].second));
+ for(int i = 1; i < half; i++) {
+ mbr1.extend(getter.get(entries, data[i].second));
+ }
+ ModifiableHyperBoundingBox mbr2 = new ModifiableHyperBoundingBox(getter.get(entries, data[num - 1].second));
+ for(int i = half + 1; i < num - 1; i++) {
+ mbr2.extend(getter.get(entries, data[i].second));
+ }
+ E e = getter.get(entries, data[half].second);
+ double inc1 = SpatialUtil.volumeUnion(mbr1, e) - SpatialUtil.volume(mbr1);
+ double inc2 = SpatialUtil.volumeUnion(mbr2, e) - SpatialUtil.volume(mbr2);
+ if(inc1 < inc2) {
+ assignment.set(data[half].second);
+ }
+ }
+ return assignment;
+ }
+
+ /**
+ * Parameterization class.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ public static class Parameterizer extends AbstractParameterizer {
+ @Override
+ protected GreeneSplit makeInstance() {
+ return GreeneSplit.STATIC;
+ }
+ }
+} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/split/RTreeLinearSplit.java b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/split/RTreeLinearSplit.java
new file mode 100644
index 00000000..296f6b3b
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/split/RTreeLinearSplit.java
@@ -0,0 +1,219 @@
+package de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.strategies.split;
+
+/*
+ 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 <http://www.gnu.org/licenses/>.
+ */
+
+import java.util.BitSet;
+
+import de.lmu.ifi.dbs.elki.data.ModifiableHyperBoundingBox;
+import de.lmu.ifi.dbs.elki.data.spatial.SpatialComparable;
+import de.lmu.ifi.dbs.elki.data.spatial.SpatialUtil;
+import de.lmu.ifi.dbs.elki.utilities.datastructures.arraylike.ArrayAdapter;
+import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
+
+/**
+ * Linear-time complexity greedy split as used by the original R-Tree.
+ *
+ * <p>
+ * Antonin Guttman:<br/>
+ * R-Trees: A Dynamic Index Structure For Spatial Searching<br />
+ * in Proceedings of the 1984 ACM SIGMOD international conference on Management
+ * of data.
+ * </p>
+ *
+ * @author Erich Schubert
+ */
+@Reference(authors = "Antonin Guttman", title = "R-Trees: A Dynamic Index Structure For Spatial Searching", booktitle = "Proceedings of the 1984 ACM SIGMOD international conference on Management of data", url = "http://dx.doi.org/10.1145/971697.602266")
+public class RTreeLinearSplit implements SplitStrategy {
+ /**
+ * Static instance.
+ */
+ public static final RTreeLinearSplit STATIC = new RTreeLinearSplit();
+
+ @Override
+ public <E extends SpatialComparable, A> BitSet split(A entries, ArrayAdapter<E, A> getter, int minEntries) {
+ final int num = getter.size(entries);
+ // Object assignment, and processed objects
+ BitSet assignment = new BitSet(num);
+ BitSet assigned = new BitSet(num);
+ // MBRs and Areas of current assignments
+ ModifiableHyperBoundingBox mbr1, mbr2;
+ double area1 = 0, area2 = 0;
+ // LinearPickSeeds - find worst pair
+ {
+ final int dim = getter.get(entries, 0).getDimensionality();
+ // Best candidates
+ double bestsep = Double.NEGATIVE_INFINITY;
+ int w1 = -1, w2 = -1;
+ // LPS1: find extreme rectangles
+ for(int d = 1; d <= dim; d++) {
+ // We need to find two candidates each, in case of el==eh!
+ double minlow = Double.POSITIVE_INFINITY;
+ double maxlow = Double.NEGATIVE_INFINITY, maxlow2 = Double.NEGATIVE_INFINITY;
+ double minhig = Double.POSITIVE_INFINITY, minhig2 = Double.POSITIVE_INFINITY;
+ double maxhig = Double.NEGATIVE_INFINITY;
+ int el = -1, el2 = -1;
+ int eh = -1, eh2 = -1;
+ for(int i = 0; i < num; i++) {
+ E ei = getter.get(entries, i);
+ final double low = ei.getMin(d);
+ final double hig = ei.getMax(d);
+ minlow = Math.min(minlow, low);
+ maxhig = Math.max(maxhig, hig);
+ if(low >= maxlow) {
+ maxlow2 = maxlow;
+ maxlow = low;
+ el2 = el;
+ el = i;
+ }
+ else if(low > maxlow2) {
+ maxlow2 = low;
+ el2 = i;
+ }
+ if(hig <= minhig) {
+ minhig2 = minhig;
+ minhig = hig;
+ eh2 = eh;
+ eh = i;
+ }
+ else if(hig < minhig2) {
+ minhig2 = hig;
+ eh2 = i;
+ }
+ }
+ // Compute normalized separation
+ final double normsep;
+ if(el != eh) {
+ normsep = minhig - maxlow / (maxhig - minlow);
+ }
+ else {
+ // Resolve tie.
+ double normsep1 = minhig - maxlow2 / (maxhig - minlow);
+ double normsep2 = minhig2 - maxlow / (maxhig - minlow);
+ if(normsep1 > normsep2) {
+ el = el2;
+ normsep = normsep1;
+ }
+ else {
+ eh = eh2;
+ normsep = normsep2;
+ }
+ }
+ assert (eh != -1 && el != -1 && (eh != el));
+ if(normsep > bestsep) {
+ bestsep = normsep;
+ w1 = el;
+ w2 = eh;
+ }
+ }
+
+ // Data to keep
+ // Mark both as used
+ assigned.set(w1);
+ assigned.set(w2);
+ // Assign second to second set
+ assignment.set(w2);
+ // Initial mbrs and areas
+ final E w1i = getter.get(entries, w1);
+ final E w2i = getter.get(entries, w2);
+ area1 = SpatialUtil.volume(w1i);
+ area2 = SpatialUtil.volume(w2i);
+ mbr1 = new ModifiableHyperBoundingBox(w1i);
+ mbr2 = new ModifiableHyperBoundingBox(w2i);
+ }
+ // Second phase, QS2+QS3
+ {
+ int in1 = 1, in2 = 1;
+ int remaining = num - 2;
+ // Choose any element, for example the next.
+ for(int next = assigned.nextClearBit(0); remaining > 0 && next < num; next = assigned.nextClearBit(next + 1)) {
+ // Shortcut when minEntries must be fulfilled
+ if(in1 + remaining <= minEntries) {
+ // No need to updated assigned, no changes to assignment.
+ break;
+ }
+ if(in2 + remaining <= minEntries) {
+ // Mark unassigned for second.
+ // Don't bother to update assigned, though
+ for(; next < num; next = assigned.nextClearBit(next + 1)) {
+ assignment.set(next);
+ }
+ break;
+ }
+ // PickNext
+ boolean preferSecond = false;
+
+ // Cost of putting object into both mbrs
+ final E next_i = getter.get(entries, next);
+ final double d1 = SpatialUtil.volumeUnion(mbr1, next_i) - area1;
+ final double d2 = SpatialUtil.volumeUnion(mbr2, next_i) - area2;
+ // Prefer smaller increase
+ preferSecond = (d2 < d1);
+ // QS3: tie handling
+ if(d1 == d2) {
+ // Prefer smaller area
+ if(area1 != area2) {
+ preferSecond = (area2 < area1);
+ }
+ else {
+ // Prefer smaller group size
+ preferSecond = (in2 < in1);
+ }
+ }
+ // Mark as used.
+ assigned.set(next);
+ remaining--;
+ // Assign
+ if(!preferSecond) {
+ in1++;
+ mbr1.extend(next_i);
+ area1 = SpatialUtil.volume(mbr1);
+ }
+ else {
+ in2++;
+ assignment.set(next);
+ mbr2.extend(next_i);
+ area2 = SpatialUtil.volume(mbr2);
+ }
+ // Loop from QS2
+ }
+ // Note: "assigned" and "remaining" likely not updated!
+ }
+ return assignment;
+ }
+
+ /**
+ * Parameterization class.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ public static class Parameterizer extends AbstractParameterizer {
+ @Override
+ protected RTreeLinearSplit makeInstance() {
+ return RTreeLinearSplit.STATIC;
+ }
+ }
+} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/split/RTreeQuadraticSplit.java b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/split/RTreeQuadraticSplit.java
new file mode 100644
index 00000000..8f61771d
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/split/RTreeQuadraticSplit.java
@@ -0,0 +1,183 @@
+package de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.strategies.split;
+
+/*
+ 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 <http://www.gnu.org/licenses/>.
+ */
+
+import java.util.BitSet;
+
+import de.lmu.ifi.dbs.elki.data.ModifiableHyperBoundingBox;
+import de.lmu.ifi.dbs.elki.data.spatial.SpatialComparable;
+import de.lmu.ifi.dbs.elki.data.spatial.SpatialUtil;
+import de.lmu.ifi.dbs.elki.utilities.datastructures.arraylike.ArrayAdapter;
+import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
+
+/**
+ * Quadratic-time complexity greedy split as used by the original R-Tree.
+ *
+ * <p>
+ * Antonin Guttman:<br/>
+ * R-Trees: A Dynamic Index Structure For Spatial Searching<br />
+ * in Proceedings of the 1984 ACM SIGMOD international conference on Management
+ * of data.
+ * </p>
+ *
+ * @author Erich Schubert
+ */
+@Reference(authors = "Antonin Guttman", title = "R-Trees: A Dynamic Index Structure For Spatial Searching", booktitle = "Proceedings of the 1984 ACM SIGMOD international conference on Management of data", url = "http://dx.doi.org/10.1145/971697.602266")
+public class RTreeQuadraticSplit implements SplitStrategy {
+ /**
+ * Static instance.
+ */
+ public static final RTreeQuadraticSplit STATIC = new RTreeQuadraticSplit();
+
+ @Override
+ public <E extends SpatialComparable, A> BitSet split(A entries, ArrayAdapter<E, A> getter, int minEntries) {
+ final int num = getter.size(entries);
+ // Object assignment, and processed objects
+ BitSet assignment = new BitSet(num);
+ BitSet assigned = new BitSet(num);
+ // MBRs and Areas of current assignments
+ ModifiableHyperBoundingBox mbr1, mbr2;
+ double area1 = 0, area2 = 0;
+ // PickSeeds - find worst pair
+ {
+ double worst = Double.NEGATIVE_INFINITY;
+ int w1 = 0, w2 = 0;
+
+ // Compute individual areas
+ double[] areas = new double[num];
+ for(int e1 = 0; e1 < num - 1; e1++) {
+ final E e1i = getter.get(entries, e1);
+ areas[e1] = SpatialUtil.volume(e1i);
+ }
+ // Compute area increase
+ for(int e1 = 0; e1 < num - 1; e1++) {
+ final E e1i = getter.get(entries, e1);
+ for(int e2 = e1 + 1; e2 < num; e2++) {
+ final E e2i = getter.get(entries, e2);
+ final double areaJ = SpatialUtil.volumeUnion(e1i, e2i);
+ final double d = areaJ - areas[e1] - areas[e2];
+ if(d > worst) {
+ worst = d;
+ w1 = e1;
+ w2 = e2;
+ }
+ }
+ }
+ // Data to keep
+ // Mark both as used
+ assigned.set(w1);
+ assigned.set(w2);
+ // Assign second to second set
+ assignment.set(w2);
+ // Initial mbrs and areas
+ area1 = areas[w1];
+ area2 = areas[w2];
+ mbr1 = new ModifiableHyperBoundingBox(getter.get(entries, w1));
+ mbr2 = new ModifiableHyperBoundingBox(getter.get(entries, w2));
+ }
+ // Second phase, QS2+QS3
+ {
+ int in1 = 1, in2 = 1;
+ int remaining = num - 2;
+ while(remaining > 0) {
+ // Shortcut when minEntries must be fulfilled
+ if(in1 + remaining <= minEntries) {
+ // No need to updated assigned, no changes to assignment.
+ break;
+ }
+ if(in2 + remaining <= minEntries) {
+ // Mark unassigned for second.
+ // Don't bother to update assigned, though
+ for(int pos = assigned.nextClearBit(0); pos < num; pos = assigned.nextClearBit(pos + 1)) {
+ assignment.set(pos);
+ }
+ break;
+ }
+ // PickNext
+ double greatestPreference = Double.NEGATIVE_INFINITY;
+ int best = -1;
+ E best_i = null;
+ boolean preferSecond = false;
+ for(int pos = assigned.nextClearBit(0); pos < num; pos = assigned.nextClearBit(pos + 1)) {
+ // Cost of putting object into both mbrs
+ final E pos_i = getter.get(entries, pos);
+ final double d1 = SpatialUtil.volumeUnion(mbr1, pos_i) - area1;
+ final double d2 = SpatialUtil.volumeUnion(mbr2, pos_i) - area2;
+ // Preference
+ final double preference = Math.abs(d1 - d2);
+ if(preference > greatestPreference) {
+ greatestPreference = preference;
+ best = pos;
+ best_i = pos_i;
+ // Prefer smaller increase
+ preferSecond = (d2 < d1);
+ }
+ }
+ // QS3: tie handling
+ if(greatestPreference == 0) {
+ // Prefer smaller area
+ if(area1 != area2) {
+ preferSecond = (area2 < area1);
+ }
+ else {
+ // Prefer smaller group size
+ preferSecond = (in2 < in1);
+ }
+ }
+ // Mark as used.
+ assigned.set(best);
+ remaining--;
+ if(!preferSecond) {
+ in1++;
+ mbr1.extend(best_i);
+ area1 = SpatialUtil.volume(mbr1);
+ }
+ else {
+ in2++;
+ assignment.set(best);
+ mbr2.extend(best_i);
+ area2 = SpatialUtil.volume(mbr2);
+ }
+ // Loop from QS2
+ }
+ // Note: "assigned" and "remaining" likely not updated!
+ }
+ return assignment;
+ }
+
+ /**
+ * Parameterization class.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ public static class Parameterizer extends AbstractParameterizer {
+ @Override
+ protected RTreeQuadraticSplit makeInstance() {
+ return RTreeQuadraticSplit.STATIC;
+ }
+ }
+} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/util/SplitStrategy.java b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/split/SplitStrategy.java
index 272dcbc6..658a63da 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/util/SplitStrategy.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/split/SplitStrategy.java
@@ -1,10 +1,10 @@
-package de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.util;
+package de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.strategies.split;
/*
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2011
+ Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
@@ -23,25 +23,25 @@ package de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.util;
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-import java.util.List;
+import java.util.BitSet;
-import de.lmu.ifi.dbs.elki.utilities.pairs.Pair;
+import de.lmu.ifi.dbs.elki.data.spatial.SpatialComparable;
+import de.lmu.ifi.dbs.elki.utilities.datastructures.arraylike.ArrayAdapter;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.Parameterizable;
/**
* Generic interface for split strategies.
*
* @author Erich Schubert
- *
- * @param <B> Base type that can be processed by this strategy
*/
-public interface SplitStrategy<B> {
+public interface SplitStrategy extends Parameterizable {
/**
* Split a page
*
- * @param <E> Actual data type
* @param entries Entries to split
+ * @param getter Adapter for the entries array
* @param minEntries Minimum number of entries in each part
- * @return Pair containing the two sets of objects
+ * @return BitSet containing the assignment.
*/
- public <E extends B> Pair<List<E>, List<E>> split(List<E> entries, int minEntries);
-}
+ public <E extends SpatialComparable, A> BitSet split(A entries, ArrayAdapter<E, A> getter, int minEntries);
+} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/split/TopologicalSplitter.java b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/split/TopologicalSplitter.java
new file mode 100644
index 00000000..1789ab22
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/split/TopologicalSplitter.java
@@ -0,0 +1,309 @@
+package de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.strategies.split;
+
+/*
+ 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 <http://www.gnu.org/licenses/>.
+ */
+
+import java.util.Arrays;
+import java.util.BitSet;
+
+import de.lmu.ifi.dbs.elki.data.HyperBoundingBox;
+import de.lmu.ifi.dbs.elki.data.ModifiableHyperBoundingBox;
+import de.lmu.ifi.dbs.elki.data.spatial.SpatialComparable;
+import de.lmu.ifi.dbs.elki.data.spatial.SpatialUtil;
+import de.lmu.ifi.dbs.elki.utilities.datastructures.arraylike.ArrayAdapter;
+import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
+import de.lmu.ifi.dbs.elki.utilities.pairs.DoubleIntPair;
+
+/**
+ * Encapsulates the required parameters for a topological split of a R*-Tree.
+ *
+ * @author Elke Achtert
+ *
+ * @apiviz.has Split
+ */
+@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 {
+ /**
+ * Static instance.
+ */
+ public static final TopologicalSplitter STATIC = new TopologicalSplitter();
+
+ /**
+ * constructor.
+ */
+ public TopologicalSplitter() {
+ // Nothing to do.
+ }
+
+ @Override
+ public <E extends SpatialComparable, A> BitSet split(A entries, ArrayAdapter<E, A> getter, int minEntries) {
+ Split<A, E> split = new Split<A, E>(entries, getter);
+ split.chooseSplitAxis(minEntries);
+ split.chooseSplitPoint(minEntries);
+
+ assert (split.splitPoint < split.size) : "Invalid split produced. Size: " + getter.size(entries) + " minEntries: " + minEntries + " split.size: " + split.size;
+ BitSet assignment = new BitSet(split.size);
+ for(int i = split.splitPoint; i < split.size; i++) {
+ assignment.set(split.bestSorting[i].second);
+ }
+ return assignment;
+ }
+
+ /**
+ * Internal data for an actual split.
+ *
+ * @author Erich Schubert
+ *
+ * @param <E> Actual entry type
+ */
+ private class Split<A, E extends SpatialComparable> {
+ /**
+ * 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.
+ */
+ DoubleIntPair[] bestSorting;
+
+ /**
+ * The entries sorted according to their max values of their MBRs.
+ */
+ DoubleIntPair[] maxSorting;
+
+ /**
+ * The entries sorted according to their min values of their MBRs.
+ */
+ DoubleIntPair[] minSorting;
+
+ /**
+ * The entries we process.
+ */
+ private A entries;
+
+ /**
+ * The getter class for the entries
+ */
+ private ArrayAdapter<E, A> getter;
+
+ /**
+ * List size
+ */
+ private int size;
+
+ /**
+ * Dimensionality
+ */
+ private int dimensionality;
+
+ /**
+ * Constructor.
+ */
+ public Split(A entries, ArrayAdapter<E, A> getter) {
+ this.entries = entries;
+ this.getter = getter;
+ this.size = getter.size(entries);
+ this.dimensionality = getter.get(entries, 0).getDimensionality();
+ initMinMaxArrays();
+ }
+
+ /**
+ * Chooses a split axis.
+ *
+ * @param minEntries number of minimum entries in the node to be split
+ */
+ void chooseSplitAxis(int minEntries) {
+ // best value for the surface
+ double minSurface = Double.MAX_VALUE;
+ int splitAxis = -1;
+
+ for(int d = 1; d <= dimensionality; d++) {
+ double sumOfAllMargins = 0;
+ fillAndSort(d);
+
+ // Note: this has a somewhat surprising evaluation order.
+ // We compute the sum as in the original paper:
+ // it says "sum of all margin-values".
+ // Except that we don't match them as you would do in a split, but
+ // Iterate over all possible splits from both sides (as well as min and
+ // max) in parallel, since union can be computed incrementally.
+ ModifiableHyperBoundingBox mbr_min_left = new ModifiableHyperBoundingBox(get(minSorting[0]));
+ ModifiableHyperBoundingBox mbr_min_right = new ModifiableHyperBoundingBox(get(minSorting[size - 1]));
+ ModifiableHyperBoundingBox mbr_max_left = new ModifiableHyperBoundingBox(get(maxSorting[0]));
+ ModifiableHyperBoundingBox mbr_max_right = new ModifiableHyperBoundingBox(get(maxSorting[size - 1]));
+
+ for(int k = 1; k < size - minEntries; k++) {
+ mbr_min_left.extend(get(minSorting[k]));
+ mbr_min_right.extend(get(minSorting[size - 1 - k]));
+ mbr_max_left.extend(get(maxSorting[k]));
+ mbr_max_right.extend(get(maxSorting[size - 1 - k]));
+ if(k >= minEntries - 1) {
+ // Yes, build the sum. This value is solely used for finding the
+ // preferred split axis!
+ // 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 = d;
+ minSurface = sumOfAllMargins;
+ }
+ }
+ if(splitAxis != dimensionality) {
+ fillAndSort(splitAxis);
+ }
+ }
+
+ /**
+ * Init the arrays we use
+ */
+ protected void initMinMaxArrays() {
+ maxSorting = new DoubleIntPair[size];
+ minSorting = new DoubleIntPair[size];
+ // Prefill
+ for(int j = 0; j < size; j++) {
+ minSorting[j] = new DoubleIntPair(0, -1);
+ maxSorting[j] = new DoubleIntPair(0, -1);
+ }
+ }
+
+ /**
+ * Fill the array with the dimension projection needed for sorting.
+ *
+ * @param dim Relevant dimension.
+ */
+ protected void fillAndSort(final int dim) {
+ // sort the entries according to their minimal and according to their
+ // maximal value in the current dimension.
+ for(int j = 0; j < size; j++) {
+ E e = get(j);
+ minSorting[j].first = e.getMin(dim);
+ minSorting[j].second = j;
+ maxSorting[j].first = e.getMax(dim);
+ maxSorting[j].second = j;
+ }
+ Arrays.sort(minSorting);
+ Arrays.sort(maxSorting);
+ }
+
+ /**
+ * Chooses a split axis.
+ *
+ * @param minEntries number of minimum entries in the node to be split
+ */
+ void chooseSplitPoint(int minEntries) {
+ // the split point (first set to minimum entries in the node)
+ splitPoint = size;
+ // best value for the overlap
+ double minOverlap = Double.POSITIVE_INFINITY;
+ // the volume of mbr1 and mbr2
+ double volume = Double.POSITIVE_INFINITY;
+ // indicates whether the sorting according to maximal or to minimal value
+ // is best for the split axis
+ bestSorting = null;
+
+ assert (size - 2 * minEntries > 0) : "Cannot split underfull nodes.";
+ // test the sorting with respect to the minimal values
+ {
+ ModifiableHyperBoundingBox mbr1 = mbr(minSorting, 0, minEntries - 1);
+ for(int i = 0; i <= size - 2 * minEntries; i++) {
+ mbr1.extend(getter.get(entries, minSorting[minEntries + i - 1].second));
+ HyperBoundingBox mbr2 = mbr(minSorting, minEntries + i, size);
+ double currentOverlap = SpatialUtil.relativeOverlap(mbr1, mbr2);
+ if(currentOverlap <= minOverlap) {
+ double vol = SpatialUtil.volume(mbr1) + SpatialUtil.volume(mbr2);
+ if(currentOverlap < minOverlap || vol < volume) {
+ minOverlap = currentOverlap;
+ volume = vol;
+ splitPoint = minEntries + i;
+ bestSorting = minSorting;
+ }
+ }
+ }
+ }
+ // test the sorting with respect to the maximal values
+ {
+ ModifiableHyperBoundingBox mbr1 = mbr(maxSorting, 0, minEntries - 1);
+ for(int i = 0; i <= size - 2 * minEntries; i++) {
+ mbr1.extend(getter.get(entries, maxSorting[minEntries + i - 1].second));
+ HyperBoundingBox mbr2 = mbr(maxSorting, minEntries + i, size);
+ double currentOverlap = SpatialUtil.relativeOverlap(mbr1, mbr2);
+ if(currentOverlap <= minOverlap) {
+ double vol = SpatialUtil.volume(mbr1) + SpatialUtil.volume(mbr2);
+ if(currentOverlap < minOverlap || vol < volume) {
+ minOverlap = currentOverlap;
+ volume = vol;
+ splitPoint = minEntries + i;
+ bestSorting = maxSorting;
+ }
+ }
+ }
+ }
+ assert (splitPoint < size) : "No split found? Volume outside of double precision?";
+ }
+
+ private E get(int off) {
+ return getter.get(entries, off);
+ }
+
+ private E get(DoubleIntPair pair) {
+ return getter.get(entries, pair.second);
+ }
+
+ /**
+ * Computes and returns the mbr of the specified nodes, only the nodes
+ * between from and to index are considered.
+ *
+ * @param sorting the array of nodes
+ * @param from the start index
+ * @param to the end index
+ * @return the mbr of the specified nodes
+ */
+ private ModifiableHyperBoundingBox mbr(final DoubleIntPair[] sorting, final int from, final int to) {
+ ModifiableHyperBoundingBox mbr = new ModifiableHyperBoundingBox(get(sorting[from]));
+ for(int i = from + 1; i < to; i++) {
+ mbr.extend(get(sorting[i]));
+ }
+ return mbr;
+ }
+ }
+
+ /**
+ * Parameterization class.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ public static class Parameterizer extends AbstractParameterizer {
+ @Override
+ protected TopologicalSplitter makeInstance() {
+ return TopologicalSplitter.STATIC;
+ }
+ }
+} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/split/package-info.java b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/split/package-info.java
new file mode 100644
index 00000000..9e8291be
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/strategies/split/package-info.java
@@ -0,0 +1,26 @@
+/**
+ * <p>Splitting strategies for R-Trees</p>
+ */
+/*
+ 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 <http://www.gnu.org/licenses/>.
+ */
+package de.lmu.ifi.dbs.elki.index.tree.spatial.rstarvariants.strategies.split; \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/util/ApproximateLeastOverlapInsertionStrategy.java b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/util/ApproximateLeastOverlapInsertionStrategy.java
deleted file mode 100644
index 1e9afdca..00000000
--- a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/util/ApproximateLeastOverlapInsertionStrategy.java
+++ /dev/null
@@ -1,150 +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.Collections;
-
-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.Node;
-import de.lmu.ifi.dbs.elki.index.tree.TreeIndexPathComponent;
-import de.lmu.ifi.dbs.elki.index.tree.spatial.SpatialEntry;
-import de.lmu.ifi.dbs.elki.utilities.datastructures.heap.TopBoundedHeap;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.OptionID;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.constraints.GreaterConstraint;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization;
-import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.IntParameter;
-import de.lmu.ifi.dbs.elki.utilities.pairs.FCPair;
-
-/**
- * Insertion strategy that exhaustively tests all childs for the least overlap
- * when inserting.
- *
- * @author Elke Achtert
- * @author Franz Graf
- * @author Marisa Petri
- */
-public class ApproximateLeastOverlapInsertionStrategy implements InsertionStrategy {
- /**
- * Defines how many children are tested for finding the child generating the
- * least overlap when inserting an object. Default 0 means all children
- */
- private int insertionCandidates = 0;
-
- /**
- * Constructor. s
- *
- * @param insertionCandidates Number of children to test.
- */
- public ApproximateLeastOverlapInsertionStrategy(int insertionCandidates) {
- super();
- this.insertionCandidates = insertionCandidates;
- }
-
- /**
- * Returns the path information of the entry of the specified node which needs
- * least overlap enlargement if the given mbr would be inserted into.
- *
- * @param node the node of which the children should be tested
- * @param mbr the mbr to be inserted into the children
- * @return the path information of the entry which needs least overlap
- * enlargement if the given mbr would be inserted into
- */
- @Override
- public <N extends Node<E>, E extends SpatialEntry> TreeIndexPathComponent<E> findInsertChild(N node, SpatialComparable mbr) {
- Enlargement<E> min = null;
-
- TopBoundedHeap<FCPair<Double, E>> entriesToTest = new TopBoundedHeap<FCPair<Double, E>>(insertionCandidates, Collections.reverseOrder());
- for(int i = 0; i < node.getNumEntries(); i++) {
- E entry_i = node.getEntry(i);
- HyperBoundingBox newMBR = SpatialUtil.unionTolerant(mbr, entry_i);
- double volume = /* entry_i.getMBR() == null ? 0 : */SpatialUtil.volume(entry_i);
- double inc_volume = SpatialUtil.volume(newMBR) - volume;
- entriesToTest.add(new FCPair<Double, E>(inc_volume, entry_i));
- }
-
- while(!entriesToTest.isEmpty()) {
- E entry_i = entriesToTest.poll().getSecond();
- int index = -1;
- HyperBoundingBox newMBR = SpatialUtil.unionTolerant(mbr, entry_i);
-
- double currOverlap = 0;
- double newOverlap = 0;
- for(int k = 0; k < node.getNumEntries(); k++) {
- E entry_k = node.getEntry(k);
- if(entry_i != entry_k) {
- currOverlap += SpatialUtil.relativeOverlap(entry_i, entry_k);
- newOverlap += SpatialUtil.relativeOverlap(newMBR, entry_k);
- }
- else {
- index = k;
- }
- }
-
- double volume = /* entry_i.getMBR() == null ? 0 : */SpatialUtil.volume(entry_i);
- double inc_volume = SpatialUtil.volume(newMBR) - volume;
- double inc_overlap = newOverlap - currOverlap;
- Enlargement<E> enlargement = new Enlargement<E>(new TreeIndexPathComponent<E>(entry_i, index), volume, inc_volume, inc_overlap);
-
- if(min == null || min.compareTo(enlargement) > 0) {
- min = enlargement;
- }
- }
-
- assert min != null;
- return min.getPathComponent();
- }
-
- /**
- * Parameterization class.
- *
- * @author Erich Schubert
- *
- * @apiviz.exclude
- */
- public static class Parameterizer extends AbstractParameterizer {
- /**
- * Fast-insertion parameter. Optional.
- */
- public static OptionID INSERTION_CANDIDATES_ID = OptionID.getOrCreateOptionID("rtree.insertion-candidates", "defines how many children are tested for finding the child generating the least overlap when inserting an object.");
-
- int insertionCandidates = 0;
-
- @Override
- protected void makeOptions(Parameterization config) {
- super.makeOptions(config);
- IntParameter insertionCandidatesP = new IntParameter(INSERTION_CANDIDATES_ID, new GreaterConstraint(0));
- if(config.grab(insertionCandidatesP)) {
- insertionCandidates = insertionCandidatesP.getValue();
- }
- }
-
- @Override
- protected ApproximateLeastOverlapInsertionStrategy makeInstance() {
- return new ApproximateLeastOverlapInsertionStrategy(insertionCandidates);
- }
- }
-} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/util/Enlargement.java b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/util/Enlargement.java
deleted file mode 100644
index 79c8c0ef..00000000
--- a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/util/Enlargement.java
+++ /dev/null
@@ -1,119 +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 de.lmu.ifi.dbs.elki.index.tree.DirectoryEntry;
-import de.lmu.ifi.dbs.elki.index.tree.TreeIndexPathComponent;
-import de.lmu.ifi.dbs.elki.index.tree.spatial.SpatialEntry;
-
-/**
- * Encapsulates the parameters for enlargement of nodes after insertion of new
- * objects.
- *
- * @author Elke Achtert
- * @param <E> Entry type
- */
-public class Enlargement<E extends SpatialEntry> implements Comparable<Enlargement<E>> {
- /**
- * The path information of the entry representing the node.
- */
- private TreeIndexPathComponent<E> pathComponent;
-
- /**
- * The volume of the node's MBR.
- */
- private double volume;
-
- /**
- * The increment of the volume.
- */
- private double volInc;
-
- /**
- * The increment of the overlap.
- */
- private double overlapInc;
-
- /**
- * Creates an new Enlargement object with the specified parameters.
- *
- * @param pathComponent the path information of the entry representing the
- * node
- * @param volume the volume of the node's MBR
- * @param volInc the increment of the volume
- * @param overlapInc the increment of the overlap
- */
- public Enlargement(TreeIndexPathComponent<E> pathComponent, double volume, double volInc, double overlapInc) {
- this.pathComponent = pathComponent;
- this.volume = volume;
- this.volInc = volInc;
- this.overlapInc = overlapInc;
- }
-
- /**
- * Compares this Enlargement with the specified Enlargement. First the
- * increment of the overlap will be compared. If both are equal the increment
- * of the volume will be compared. If also both are equal the volumes of both
- * nodes will be compared. If both are equal the ids of the nodes will be
- * compared.
- *
- * @param other the Enlargement to be compared.
- * @return a negative integer, zero, or a positive integer as this Enlargement
- * is less than, equal to, or greater than the specified Enlargement.
- */
- @Override
- public int compareTo(Enlargement<E> other) {
- if(this.overlapInc < other.overlapInc) {
- return -1;
- }
- if(this.overlapInc > other.overlapInc) {
- return +1;
- }
-
- if(this.volInc < other.volInc) {
- return -1;
- }
- if(this.volInc > other.volInc) {
- return +1;
- }
-
- if(this.volume < other.volume) {
- return -1;
- }
- if(this.volume > other.volume) {
- return +1;
- }
-
- return ((DirectoryEntry)this.pathComponent.getEntry()).getPageID() - ((DirectoryEntry)other.pathComponent.getEntry()).getPageID();
- }
-
- /**
- * Returns the path information of the entry representing the node.
- *
- * @return the path information of the entry representing the node
- */
- public TreeIndexPathComponent<E> getPathComponent() {
- return pathComponent;
- }
-} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/util/LeastOverlapInsertionStrategy.java b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/util/LeastOverlapInsertionStrategy.java
deleted file mode 100644
index 90f0c91b..00000000
--- a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/util/LeastOverlapInsertionStrategy.java
+++ /dev/null
@@ -1,87 +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 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.Node;
-import de.lmu.ifi.dbs.elki.index.tree.TreeIndexPathComponent;
-import de.lmu.ifi.dbs.elki.index.tree.spatial.SpatialEntry;
-
-/**
- * Insertion strategy that exhaustively tests all childs for the least overlap
- * when inserting.
- *
- * @author Elke Achtert
- */
-public class LeastOverlapInsertionStrategy implements InsertionStrategy {
- /**
- * Constructor.
- */
- public LeastOverlapInsertionStrategy() {
- super();
- }
-
- /**
- * Returns the path information of the entry of the specified node which needs
- * least overlap enlargement if the given mbr would be inserted into.
- *
- * @param node the node of which the children should be tested
- * @param mbr the mbr to be inserted into the children
- * @return the path information of the entry which needs least overlap
- * enlargement if the given mbr would be inserted into
- */
- @Override
- public <N extends Node<E>, E extends SpatialEntry> TreeIndexPathComponent<E> findInsertChild(N node, SpatialComparable mbr) {
- Enlargement<E> min = null;
-
- for(int i = 0; i < node.getNumEntries(); i++) {
- E entry_i = node.getEntry(i);
- HyperBoundingBox newMBR = SpatialUtil.unionTolerant(mbr, entry_i);
-
- double currOverlap = 0;
- double newOverlap = 0;
- for(int k = 0; k < node.getNumEntries(); k++) {
- if(i != k) {
- E entry_k = node.getEntry(k);
- currOverlap += SpatialUtil.relativeOverlap(entry_i, entry_k);
- newOverlap += SpatialUtil.relativeOverlap(newMBR, entry_k);
- }
- }
-
- double volume = /* entry_i.getMBR() == null ? 0 : */SpatialUtil.volume(entry_i);
- double inc_volume = SpatialUtil.volume(newMBR) - volume;
- double inc_overlap = newOverlap - currOverlap;
- Enlargement<E> enlargement = new Enlargement<E>(new TreeIndexPathComponent<E>(entry_i, i), volume, inc_volume, inc_overlap);
-
- if(min == null || min.compareTo(enlargement) > 0) {
- min = enlargement;
- }
- }
-
- assert min != null;
- return min.getPathComponent();
- }
-}
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/util/NodeArrayAdapter.java b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/util/NodeArrayAdapter.java
new file mode 100644
index 00000000..3bf35d9d
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/util/NodeArrayAdapter.java
@@ -0,0 +1,58 @@
+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) 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 <http://www.gnu.org/licenses/>.
+ */
+
+import de.lmu.ifi.dbs.elki.index.tree.AbstractNode;
+import de.lmu.ifi.dbs.elki.index.tree.spatial.SpatialEntry;
+import de.lmu.ifi.dbs.elki.utilities.datastructures.arraylike.ArrayAdapter;
+
+/**
+ * Access the entries of a node as array-like.
+ *
+ * @author Erich Schubert
+ */
+public class NodeArrayAdapter implements ArrayAdapter<SpatialEntry, AbstractNode<? extends SpatialEntry>> {
+ /**
+ * Static adapter.
+ */
+ public static NodeArrayAdapter STATIC = new NodeArrayAdapter();
+
+ /**
+ * Constructor.
+ */
+ protected NodeArrayAdapter() {
+ super();
+ // TODO Auto-generated constructor stub
+ }
+
+ @Override
+ public int size(AbstractNode<? extends SpatialEntry> array) {
+ return array.getNumEntries();
+ }
+
+ @Override
+ public SpatialEntry get(AbstractNode<? extends SpatialEntry> array, int off) throws IndexOutOfBoundsException {
+ return array.getEntry(off);
+ }
+} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/util/SpatialComparator.java b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/util/SpatialComparator.java
index fe3f322b..2f1ea9b1 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/util/SpatialComparator.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/util/SpatialComparator.java
@@ -4,7 +4,7 @@ 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
+ Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
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);
- }
- }
- }
-}
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/util/package-info.java b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/util/package-info.java
index 382faeb3..10991028 100644
--- a/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/util/package-info.java
+++ b/src/de/lmu/ifi/dbs/elki/index/tree/spatial/rstarvariants/util/package-info.java
@@ -6,7 +6,7 @@
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
-Copyright (C) 2011
+Copyright (C) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
diff --git a/src/de/lmu/ifi/dbs/elki/index/vafile/VAFile.java b/src/de/lmu/ifi/dbs/elki/index/vafile/VAFile.java
new file mode 100644
index 00000000..c426c1d6
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/index/vafile/VAFile.java
@@ -0,0 +1,518 @@
+package de.lmu.ifi.dbs.elki.index.vafile;
+
+/*
+ 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.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+import de.lmu.ifi.dbs.elki.data.NumberVector;
+import de.lmu.ifi.dbs.elki.data.type.TypeInformation;
+import de.lmu.ifi.dbs.elki.data.type.TypeUtil;
+import de.lmu.ifi.dbs.elki.database.ids.DBID;
+import de.lmu.ifi.dbs.elki.database.ids.DBIDs;
+import de.lmu.ifi.dbs.elki.database.query.DatabaseQuery;
+import de.lmu.ifi.dbs.elki.database.query.DistanceResultPair;
+import de.lmu.ifi.dbs.elki.database.query.DoubleDistanceResultPair;
+import de.lmu.ifi.dbs.elki.database.query.distance.DistanceQuery;
+import de.lmu.ifi.dbs.elki.database.query.knn.KNNQuery;
+import de.lmu.ifi.dbs.elki.database.query.knn.KNNResult;
+import de.lmu.ifi.dbs.elki.database.query.range.RangeQuery;
+import de.lmu.ifi.dbs.elki.database.relation.Relation;
+import de.lmu.ifi.dbs.elki.distance.distancefunction.DistanceFunction;
+import de.lmu.ifi.dbs.elki.distance.distancefunction.LPNormDistanceFunction;
+import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance;
+import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance;
+import de.lmu.ifi.dbs.elki.index.AbstractRefiningIndex;
+import de.lmu.ifi.dbs.elki.index.IndexFactory;
+import de.lmu.ifi.dbs.elki.index.KNNIndex;
+import de.lmu.ifi.dbs.elki.index.RangeIndex;
+import de.lmu.ifi.dbs.elki.index.tree.TreeIndexFactory;
+import de.lmu.ifi.dbs.elki.logging.Logging;
+import de.lmu.ifi.dbs.elki.utilities.DatabaseUtil;
+import de.lmu.ifi.dbs.elki.utilities.datastructures.heap.Heap;
+import de.lmu.ifi.dbs.elki.utilities.datastructures.heap.KNNHeap;
+import de.lmu.ifi.dbs.elki.utilities.datastructures.heap.TopBoundedHeap;
+import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
+import de.lmu.ifi.dbs.elki.utilities.documentation.Title;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.OptionID;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.constraints.GreaterConstraint;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization;
+import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.IntParameter;
+import de.lmu.ifi.dbs.elki.utilities.pairs.DoubleObjPair;
+
+/**
+ * Vector-approximation file (VAFile)
+ *
+ * Reference:
+ * <p>
+ * Weber, R. and Blott, S.<br>
+ * An approximation based data structure for similarity search<br />
+ * in: Report TR1997b, ETH Zentrum, Zurich, Switzerland
+ * </p>
+ *
+ * @author Thomas Bernecker
+ * @author Erich Schubert
+ */
+@Title("An approximation based data structure for similarity search")
+@Reference(authors = "Weber, R. and Blott, S.", title = "An approximation based data structure for similarity search", booktitle = "Report TR1997b, ETH Zentrum, Zurich, Switzerland", url = "http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.40.480&rep=rep1&type=pdf")
+public class VAFile<V extends NumberVector<?, ?>> extends AbstractRefiningIndex<V> implements KNNIndex<V>, RangeIndex<V> {
+ /**
+ * Logging class
+ */
+ private static final Logging log = Logging.getLogger(VAFile.class);
+
+ /**
+ * Approximation index
+ */
+ private List<VectorApproximation> vectorApprox;
+
+ /**
+ * Number of partitions.
+ */
+ private int partitions;
+
+ /**
+ * Quantile grid we use
+ */
+ private double[][] splitPositions;
+
+ /**
+ * Page size, for estimating the VA file size
+ */
+ int pageSize;
+
+ /**
+ * Number of scans we performed.
+ */
+ int scans;
+
+ /**
+ * Constructor.
+ *
+ * @param pageSize Page size of simulated index
+ * @param relation Relation to index
+ * @param partitions Number of partitions for each dimension.
+ */
+ public VAFile(int pageSize, Relation<V> relation, int partitions) {
+ super(relation);
+ this.partitions = partitions;
+ this.pageSize = pageSize;
+ this.scans = 0;
+ this.vectorApprox = new ArrayList<VectorApproximation>();
+ }
+
+ @Override
+ protected void initialize(Relation<V> relation, DBIDs ids) {
+ setPartitions(relation);
+ for(DBID id : relation.getDBIDs()) {
+ vectorApprox.add(calculateApproximation(id, relation.get(id)));
+ }
+ }
+
+ /**
+ * Initialize the data set grid by computing quantiles.
+ *
+ * @param relation Data relation
+ * @throws IllegalArgumentException
+ */
+ public void setPartitions(Relation<V> relation) throws IllegalArgumentException {
+ if((Math.log(partitions) / Math.log(2)) != (int) (Math.log(partitions) / Math.log(2))) {
+ throw new IllegalArgumentException("Number of partitions must be a power of 2!");
+ }
+
+ final int dimensions = DatabaseUtil.dimensionality(relation);
+ final int size = relation.size();
+ splitPositions = new double[dimensions][partitions + 1];
+
+ for(int d = 0; d < dimensions; d++) {
+ double[] tempdata = new double[size];
+ int j = 0;
+ for(DBID id : relation.iterDBIDs()) {
+ tempdata[j] = relation.get(id).doubleValue(d + 1);
+ j += 1;
+ }
+ Arrays.sort(tempdata);
+
+ for(int b = 0; b < partitions; b++) {
+ int start = (int) (b * size / (double) partitions);
+ splitPositions[d][b] = tempdata[start];
+ }
+ // make sure that last object will be included
+ splitPositions[d][partitions] = tempdata[size - 1] + 0.000001;
+ }
+ }
+
+ /**
+ * Calculate the VA file position given the existing borders.
+ *
+ * @param id Object ID
+ * @param dv Data vector
+ * @return Vector approximation
+ */
+ public VectorApproximation calculateApproximation(DBID id, V dv) {
+ int approximation[] = new int[dv.getDimensionality()];
+ for(int d = 0; d < splitPositions.length; d++) {
+ final double val = dv.doubleValue(d + 1);
+ final int lastBorderIndex = splitPositions[d].length - 1;
+
+ // Value is below data grid
+ if(val < splitPositions[d][0]) {
+ approximation[d] = 0;
+ if(id != null) {
+ log.warning("Vector outside of VAFile grid!");
+ }
+ } // Value is above data grid
+ else if(val > splitPositions[d][lastBorderIndex]) {
+ approximation[d] = lastBorderIndex - 1;
+ if(id != null) {
+ log.warning("Vector outside of VAFile grid!");
+ }
+ } // normal case
+ else {
+ // Search grid position
+ int pos = Arrays.binarySearch(splitPositions[d], val);
+ pos = (pos >= 0) ? pos : ((-pos) - 2);
+ approximation[d] = pos;
+ }
+ }
+ return new VectorApproximation(id, approximation);
+ }
+
+ @Override
+ public long getReadOperations() {
+ return getRandomReadOnly() + getScannedPages();
+ }
+
+ /**
+ * Get the number of random read operations only.
+ *
+ * @return Random read operations.
+ */
+ public long getRandomReadOnly() {
+ return super.getReadOperations();
+ }
+
+ /**
+ * Get the number of scanned bytes.
+ *
+ * @return Numebr of scanned bytes.
+ */
+ public long getScannedPages() {
+ int vacapacity = pageSize / VectorApproximation.byteOnDisk(splitPositions.length, partitions);
+ int vasize = (int) Math.ceil((vectorApprox.size()) / (1.0 * vacapacity));
+ return vasize * scans;
+ }
+
+ @Override
+ public long getWriteOperations() {
+ return -1;
+ }
+
+ @Override
+ public void resetPageAccess() {
+ super.resetPageAccess();
+ scans = 0;
+ // FIXME: writes
+ }
+
+ @Override
+ public String getLongName() {
+ return "VA-file index";
+ }
+
+ @Override
+ public String getShortName() {
+ return "va-file";
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public <D extends Distance<D>> KNNQuery<V, D> getKNNQuery(DistanceQuery<V, D> distanceQuery, Object... hints) {
+ for(Object hint : hints) {
+ if(hint == DatabaseQuery.HINT_BULK) {
+ // FIXME: support bulk?
+ return null;
+ }
+ }
+ DistanceFunction<? super V, ?> df = distanceQuery.getDistanceFunction();
+ if(df instanceof LPNormDistanceFunction) {
+ double p = ((LPNormDistanceFunction) df).getP();
+ DistanceQuery<V, ?> ddq = (DistanceQuery<V, ?>) distanceQuery;
+ KNNQuery<V, ?> dq = new VAFileKNNQuery((DistanceQuery<V, DoubleDistance>) ddq, p);
+ return (KNNQuery<V, D>) dq;
+ }
+ // Not supported.
+ return null;
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public <D extends Distance<D>> RangeQuery<V, D> getRangeQuery(DistanceQuery<V, D> distanceQuery, Object... hints) {
+ DistanceFunction<? super V, ?> df = distanceQuery.getDistanceFunction();
+ if(df instanceof LPNormDistanceFunction) {
+ double p = ((LPNormDistanceFunction) df).getP();
+ DistanceQuery<V, ?> ddq = (DistanceQuery<V, ?>) distanceQuery;
+ RangeQuery<V, ?> dq = new VAFileRangeQuery((DistanceQuery<V, DoubleDistance>) ddq, p);
+ return (RangeQuery<V, D>) dq;
+ }
+ // Not supported.
+ return null;
+ }
+
+ /**
+ * Range query for this index.
+ *
+ * @author Erich Schubert
+ */
+ class VAFileRangeQuery extends AbstractRefiningIndex<V>.AbstractRangeQuery<DoubleDistance> {
+ /**
+ * LP Norm p parameter.
+ */
+ final double p;
+
+ /**
+ * Constructor.
+ *
+ * @param distanceQuery Distance query object
+ * @param p LP norm p
+ */
+
+ public VAFileRangeQuery(DistanceQuery<V, DoubleDistance> distanceQuery, double p) {
+ super(distanceQuery);
+ this.p = p;
+ }
+
+ @Override
+ public List<DistanceResultPair<DoubleDistance>> getRangeForObject(V query, DoubleDistance range) {
+ final double eps = range.doubleValue();
+ // generate query approximation and lookup table
+ VectorApproximation queryApprox = calculateApproximation(null, query);
+
+ // Approximative distance function
+ VALPNormDistance vadist = new VALPNormDistance(p, splitPositions, query, queryApprox);
+
+ // Count a VA file scan
+ scans += 1;
+
+ List<DistanceResultPair<DoubleDistance>> result = new ArrayList<DistanceResultPair<DoubleDistance>>();
+ // Approximation step
+ for(int i = 0; i < vectorApprox.size(); i++) {
+ VectorApproximation va = vectorApprox.get(i);
+ double minDist = vadist.getMinDist(va);
+
+ if(minDist > eps) {
+ continue;
+ }
+
+ // TODO: we don't need to refine always (maxDist < eps), if we are
+ // interested in the DBID only! But this needs an API change.
+
+ // refine the next element
+ final double dist = refine(va.id, query).doubleValue();
+ if(dist <= eps) {
+ result.add(new DoubleDistanceResultPair(dist, va.id));
+ }
+ }
+ Collections.sort(result);
+ return result;
+ }
+ }
+
+ /**
+ * KNN query for this index.
+ *
+ * @author Erich Schubert
+ */
+ class VAFileKNNQuery extends AbstractRefiningIndex<V>.AbstractKNNQuery<DoubleDistance> {
+ /**
+ * LP Norm p parameter.
+ */
+ final double p;
+
+ /**
+ * Constructor.
+ *
+ * @param distanceQuery Distance query object
+ * @param p LP norm p
+ */
+ public VAFileKNNQuery(DistanceQuery<V, DoubleDistance> distanceQuery, double p) {
+ super(distanceQuery);
+ this.p = p;
+ }
+
+ @Override
+ public KNNResult<DoubleDistance> getKNNForObject(V query, int k) {
+ // generate query approximation and lookup table
+ VectorApproximation queryApprox = calculateApproximation(null, query);
+
+ // Approximative distance function
+ VALPNormDistance vadist = new VALPNormDistance(p, splitPositions, query, queryApprox);
+
+ // Heap for the kth smallest maximum distance
+ Heap<Double> minMaxHeap = new TopBoundedHeap<Double>(k, Collections.reverseOrder());
+ double minMaxDist = Double.POSITIVE_INFINITY;
+ // Candidates with minDist <= kth maxDist
+ ArrayList<DoubleObjPair<DBID>> candidates = new ArrayList<DoubleObjPair<DBID>>(vectorApprox.size());
+
+ // Count a VA file scan
+ scans += 1;
+
+ // Approximation step
+ for(int i = 0; i < vectorApprox.size(); i++) {
+ VectorApproximation va = vectorApprox.get(i);
+ double minDist = vadist.getMinDist(va);
+ double maxDist = vadist.getMaxDist(va);
+
+ // Skip excess candidate generation:
+ if(minDist > minMaxDist) {
+ continue;
+ }
+ candidates.add(new DoubleObjPair<DBID>(minDist, va.id));
+
+ // Update candidate pruning heap
+ minMaxHeap.add(maxDist);
+ if(minMaxHeap.size() >= k) {
+ minMaxDist = minMaxHeap.peek();
+ }
+ }
+ // sort candidates by lower bound (minDist)
+ Collections.sort(candidates);
+
+ // refinement step
+ KNNHeap<DoubleDistance> result = new KNNHeap<DoubleDistance>(k);
+
+ // log.fine("candidates size " + candidates.size());
+ // retrieve accurate distances
+ for(DoubleObjPair<DBID> va : candidates) {
+ // Stop when we are sure to have all elements
+ if(result.size() >= k) {
+ double kDist = result.getKNNDistance().doubleValue();
+ if(va.first > kDist) {
+ break;
+ }
+ }
+
+ // refine the next element
+ final double dist = refine(va.second, query).doubleValue();
+ result.add(new DoubleDistanceResultPair(dist, va.second));
+ }
+ if(log.isDebuggingFinest()) {
+ log.finest("query = (" + query + ")");
+ log.finest("database: " + vectorApprox.size() + ", candidates: " + candidates.size() + ", results: " + result.size());
+ }
+
+ return result.toKNNList();
+ }
+ }
+
+ /**
+ * Index factory class
+ *
+ * @author Erich Schubert
+ *
+ * @param <V> Vector type
+ */
+ public static class Factory<V extends NumberVector<?, ?>> implements IndexFactory<V, VAFile<V>> {
+ /**
+ * Number of partitions to use in each dimension.
+ *
+ * <pre>
+ * -vafile.partitions 8
+ * </pre>
+ */
+ public static final OptionID PARTITIONS_ID = OptionID.getOrCreateOptionID("vafile.partitions", "Number of partitions to use in each dimension.");
+
+ /**
+ * Page size
+ */
+ int pagesize = 1;
+
+ /**
+ * Number of partitions
+ */
+ int numpart = 2;
+
+ /**
+ * Constructor.
+ *
+ * @param pagesize Page size
+ * @param numpart Number of partitions
+ */
+ public Factory(int pagesize, int numpart) {
+ super();
+ this.pagesize = pagesize;
+ this.numpart = numpart;
+ }
+
+ @Override
+ public VAFile<V> instantiate(Relation<V> relation) {
+ return new VAFile<V>(pagesize, relation, numpart);
+ }
+
+ @Override
+ public TypeInformation getInputTypeRestriction() {
+ return TypeUtil.NUMBER_VECTOR_FIELD;
+ }
+
+ /**
+ * Parameterization class
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ public static class Parameterizer extends AbstractParameterizer {
+ /**
+ * Page size
+ */
+ int pagesize = 1;
+
+ /**
+ * Number of partitions
+ */
+ int numpart = 2;
+
+ @Override
+ protected void makeOptions(Parameterization config) {
+ super.makeOptions(config);
+ IntParameter pagesizeP = new IntParameter(TreeIndexFactory.PAGE_SIZE_ID, new GreaterConstraint(0), 1024);
+ if(config.grab(pagesizeP)) {
+ pagesize = pagesizeP.getValue();
+ }
+ IntParameter partitionsP = new IntParameter(Factory.PARTITIONS_ID, new GreaterConstraint(2));
+ if(config.grab(partitionsP)) {
+ numpart = partitionsP.getValue();
+ }
+ }
+
+ @Override
+ protected Factory<?> makeInstance() {
+ return new Factory<NumberVector<?, ?>>(pagesize, numpart);
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/index/vafile/VALPNormDistance.java b/src/de/lmu/ifi/dbs/elki/index/vafile/VALPNormDistance.java
new file mode 100644
index 00000000..77815c97
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/index/vafile/VALPNormDistance.java
@@ -0,0 +1,169 @@
+package de.lmu.ifi.dbs.elki.index.vafile;
+
+/*
+ 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 <http://www.gnu.org/licenses/>.
+ */
+
+import de.lmu.ifi.dbs.elki.data.NumberVector;
+
+/**
+ * Lp-Norm distance function for partially computed objects
+ *
+ * @author Erich Schubert
+ */
+public class VALPNormDistance {
+ /**
+ * Value of 1/p for lP norm
+ */
+ private final double onebyp;
+
+ /**
+ * Lookup table for grid cells
+ */
+ private double[][] lookup;
+
+ /**
+ * Approximation of the query vector
+ */
+ private VectorApproximation queryApprox;
+
+ /**
+ * Constructor.
+ *
+ * @param p Value of p
+ * @param splitPositions Split positions
+ * @param query Query vector
+ * @param queryApprox
+ */
+ public VALPNormDistance(double p, double[][] splitPositions, NumberVector<?, ?> query, VectorApproximation queryApprox) {
+ super();
+ this.onebyp = 1.0 / p;
+ this.queryApprox = queryApprox;
+ initializeLookupTable(splitPositions, query, p);
+ }
+
+ /**
+ * Get the minimum distance contribution of a single dimension
+ *
+ * @param dimension Dimension
+ * @param vp Vector position
+ * @return Increment
+ */
+ public double getPartialMinDist(int dimension, int vp) {
+ final int qp = queryApprox.getApproximation(dimension);
+ if(vp < qp) {
+ return lookup[dimension][vp + 1];
+ }
+ else if(vp > qp) {
+ return lookup[dimension][vp];
+ }
+ else {
+ return 0.0;
+ }
+ }
+
+ /**
+ * Get the minimum distance to approximated vector vec
+ *
+ * @param vec Vector approximation
+ * @return Minimum distance
+ */
+ public double getMinDist(VectorApproximation vec) {
+ final int dim = lookup.length;
+ double minDist = 0;
+ for(int d = 0; d < dim; d++) {
+ final int vp = vec.getApproximation(d);
+ minDist += getPartialMinDist(d, vp);
+ }
+ return Math.pow(minDist, onebyp);
+ }
+
+ /**
+ * Get the maximum distance contribution of a single dimension
+ *
+ * @param dimension Dimension
+ * @param vp Vector position
+ * @return Increment
+ */
+ public double getPartialMaxDist(int dimension, int vp) {
+ final int qp = queryApprox.getApproximation(dimension);
+ if(vp < qp) {
+ return lookup[dimension][vp];
+ }
+ else if(vp > qp) {
+ return lookup[dimension][vp + 1];
+ }
+ else {
+ return Math.max(lookup[dimension][vp], lookup[dimension][vp + 1]);
+ }
+ }
+
+ /**
+ * Get the maximum distance.
+ *
+ * @param vec Approximation vector
+ * @return Maximum distance of the vector
+ */
+ public double getMaxDist(VectorApproximation vec) {
+ final int dim = lookup.length;
+ double maxDist = 0;
+ for(int d = 0; d < dim; d++) {
+ final int vp = vec.getApproximation(d);
+ maxDist += getPartialMaxDist(d, vp);
+ }
+ return Math.pow(maxDist, onebyp);
+ }
+
+ /**
+ * Get the maximum distance.
+ *
+ * @param dimension Dimension
+ * @return Maximum distance in the given dimension
+ */
+ public double getPartialMaxMaxDist(int dimension) {
+ double[] data = lookup[dimension];
+ double max = data[0];
+ for(int i = 1; i < data.length; i++) {
+ max = Math.max(max, data[i]);
+ }
+ return max;
+ }
+
+ /**
+ * Initialize the lookup table
+ *
+ * @param splitPositions Split positions
+ * @param query Query vector
+ * @param p p
+ */
+ private void initializeLookupTable(double[][] splitPositions, NumberVector<?, ?> query, double p) {
+ final int dimensions = splitPositions.length;
+ final int bordercount = splitPositions[0].length;
+ lookup = new double[dimensions][bordercount];
+ for(int d = 0; d < dimensions; d++) {
+ final double val = query.doubleValue(d + 1);
+ for(int i = 0; i < bordercount; i++) {
+ lookup[d][i] = Math.pow(splitPositions[d][i] - val, p);
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/index/vafile/VectorApproximation.java b/src/de/lmu/ifi/dbs/elki/index/vafile/VectorApproximation.java
new file mode 100644
index 00000000..4b170eb8
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/index/vafile/VectorApproximation.java
@@ -0,0 +1,103 @@
+package de.lmu.ifi.dbs.elki.index.vafile;
+
+/*
+ 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.Arrays;
+
+import de.lmu.ifi.dbs.elki.database.ids.DBID;
+
+/**
+ * Object in a VA approximation.
+ *
+ * @author Thomas Bernecker
+ * @author Erich Schubert
+ */
+public class VectorApproximation {
+ /**
+ * approximation (va cell ids)
+ */
+ int[] approximation;
+
+ /**
+ * Object represented by this approximation
+ */
+ protected DBID id;
+
+ /**
+ * Constructor.
+ *
+ * @param id Object represented (may be <code>null</code> for query objects)
+ * @param approximation Approximation
+ */
+ public VectorApproximation(DBID id, int[] approximation) {
+ super();
+ this.id = id;
+ this.approximation = approximation;
+ }
+
+ /**
+ * @return the id
+ */
+ public DBID getId() {
+ return id;
+ }
+
+ /**
+ * Get the dimensionality
+ *
+ * @return Dimensionality
+ */
+ public int getDimensionality() {
+ return approximation.length;
+ }
+
+ /**
+ * Get the VA approximation
+ *
+ * @param dim Dimension
+ * @return Bin number
+ */
+ public int getApproximation(int dim) {
+ return approximation[dim];
+ }
+
+ @Override
+ public String toString() {
+ return id + " (" + Arrays.toString(approximation) + ")";
+ }
+
+ /**
+ * Computes IO costs (in bytes) needed for reading the candidates. For one
+ * object, log2(numberOfPartitions) bits have to be read per dimension.
+ *
+ * @param numberOfDimensions the number of relevant dimensions
+ * @param numberOfPartitions the number of relevant partitions
+ * @return the cost values (in bytes)
+ */
+ //nicht gleich in bytes umwandeln, sonst rundungsfehler erst nachdem *anzahl objekte
+ public static int byteOnDisk(int numberOfDimensions, int numberOfPartitions) {
+ //(partition*dimension+id) alles in Bit 32bit für 4 byte id
+ return (int) (Math.ceil(numberOfDimensions * ((Math.log(numberOfPartitions) / Math.log(2)))+32) /8);
+ }
+} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/index/vafile/package-info.java b/src/de/lmu/ifi/dbs/elki/index/vafile/package-info.java
new file mode 100644
index 00000000..f38b1dca
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/index/vafile/package-info.java
@@ -0,0 +1,27 @@
+/**
+ * <p>Vector Approximation File</p>
+ */
+/*
+ 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 <http://www.gnu.org/licenses/>.
+ */
+// TODO: add projected VA files, allow different binning and projection strategies.
+package de.lmu.ifi.dbs.elki.index.vafile; \ No newline at end of file