package net.mooctest;
import java.util.ArrayDeque;
import java.util.Deque;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.PriorityQueue;
import java.util.Set;
import net.mooctest.SplitFunction.SplitResult;
/**
* The main class that implements the M-Tree.
*
* @param <DATA> The type of data that will be indexed by the M-Tree. Objects of
* this type are stored in HashMaps and HashSets, so their
* {@code hashCode()} and {@code equals()} methods must be consistent.
*/
public class MTree<DATA> {
/**
* The type of the results for nearest-neighbor queries.
*/
public class ResultItem {
private ResultItem(DATA data, double distance) {
this.data = data;
this.distance = distance;
}
/** A nearest-neighbor. */
public DATA data;
/**
* The distance from the nearest-neighbor to the query data object
* parameter.
*/
public double distance;
}
// Exception classes
private static class SplitNodeReplacement extends Exception {
// A subclass of Throwable cannot be generic. :-(
// So, we have newNodes declared as Object[] instead of Node[].
private Object newNodes[];
private SplitNodeReplacement(Object... newNodes) {
this.newNodes = newNodes;
}
}
private static class RootNodeReplacement extends Exception {
// A subclass of Throwable cannot be generic. :-(
// So, we have newRoot declared as Object instead of Node.
private Object newRoot;
private RootNodeReplacement(Object newRoot) {
this.newRoot = newRoot;
}
}
private static class NodeUnderCapacity extends Exception { }
private static class DataNotFound extends Exception { }
/**
* An {@link Iterable} class which can be iterated to fetch the results of a
* nearest-neighbors query.
*
* <p>The neighbors are presented in non-decreasing order from the {@code
* queryData} argument to the {@link MTree#getNearest(Object, double, int)
* getNearest*()}
* call.
*
* <p>The query on the M-Tree is executed during the iteration, as the
* results are fetched. It means that, by the time when the <i>n</i>-th
* result is fetched, the next result may still not be known, and the
* resources allocated were only the necessary to identify the <i>n</i>
* first results.
*/
public class Query implements Iterable<ResultItem> {
private class ResultsIterator implements Iterator<ResultItem> {
private class ItemWithDistances <U> implements Comparable<ItemWithDistances<U>> {
private U item;
private double distance;
private double minDistance;
public ItemWithDistances(U item, double distance, double minDistance) {
this.item = item;
this.distance = distance;
this.minDistance = minDistance;
}
@Override
public int compareTo(ItemWithDistances<U> that) {
if(this.minDistance < that.minDistance) {
return -1;
} else if(this.minDistance > that.minDistance) {
return +1;
} else {
return 0;
}
}
}
private ResultItem nextResultItem = null;
private boolean finished = false;
private PriorityQueue<ItemWithDistances<Node>> pendingQueue = new PriorityQueue<ItemWithDistances<Node>>();
private double nextPendingMinDistance;
private PriorityQueue<ItemWithDistances<Entry>> nearestQueue = new PriorityQueue<ItemWithDistances<Entry>>();
private int yieldedCount;
private ResultsIterator() {
if(MTree.this.root == null) {
finished = true;
return;
}
double distance = MTree.this.distanceFunction.calculate(Query.this.data, MTree.this.root.data);
double minDistance = Math.max(distance - MTree.this.root.radius, 0.0);
pendingQueue.add(new ItemWithDistances<Node>(MTree.this.root, distance, minDistance));
nextPendingMinDistance = minDistance;
}
@Override
public boolean hasNext() {
if(finished) {
return false;
}
if(nextResultItem == null) {
fetchNext();
}
if(nextResultItem == null) {
finished = true;
return false;
} else {
return true;
}
}
@Override
public ResultItem next() {
if(hasNext()) {
ResultItem next = nextResultItem;
nextResultItem = null;
return next;
} else {
throw new NoSuchElementException();
}
}
@Override
public void remove() {
throw new UnsupportedOperationException();
}
private void fetchNext() {
assert !finished;
if(finished || yieldedCount >= Query.this.limit) {
finished = true;
return;
}
while(!pendingQueue.isEmpty() || !nearestQueue.isEmpty()) {
if(prepareNextNearest()) {
return;
}
assert !pendingQueue.isEmpty();
ItemWithDistances<Node> pending = pendingQueue.poll();
Node node = pending.item;
for(IndexItem child : node.children.values()) {
if(Math.abs(pending.distance - child.distanceToParent) - child.radius <= Query.this.range) {
double childDistance = MTree.this.distanceFunction.calculate(Query.this.data, child.data);
double childMinDistance = Math.max(childDistance - child.radius, 0.0);
if(childMinDistance <= Query.this.range) {
if(child instanceof MTree.Entry) {
@SuppressWarnings("unchecked")
Entry entry = (Entry)child;
nearestQueue.add(new ItemWithDistances<Entry>(entry, childDistance, childMinDistance));
} else {
@SuppressWarnings("unchecked")
Node childNode = (Node)child;
pendingQueue.add(new ItemWithDistances<Node>(childNode, childDistance, childMinDistance));
}
}
}
}
if(pendingQueue.isEmpty()) {
nextPendingMinDistance = Double.POSITIVE_INFINITY;
} else {
nextPendingMinDistance = pendingQueue.peek().minDistance;
}
}
finished = true;
}
private boolean prepareNextNearest() {
if(!nearestQueue.isEmpty()) {
ItemWithDistances<Entry> nextNearest = nearestQueue.peek();
if(nextNearest.distance <= nextPendingMinDistance) {
nearestQueue.poll();
nextResultItem = new ResultItem(nextNearest.item.data, nextNearest.distance);
++yieldedCount;
return true;
}
}
return false;
}
}
private Query(DATA data, double range, int limit) {
this.data = data;
this.range = range;
this.limit = limit;
}
@Override
public Iterator<ResultItem> iterator() {
return new ResultsIterator();
}
private DATA data;
private double range;
private int limit;
}
/**
* The default minimum capacity of nodes in an M-Tree, when not specified in
* the constructor call.
*/
public static final int DEFAULT_MIN_NODE_CAPACITY = 50;
protected int minNodeCapacity;
protected int maxNodeCapacity;
protected DistanceFunction<? super DATA> distanceFunction;
protected SplitFunction<DATA> splitFunction;
protected Node root;
/**
* Constructs an M-Tree with the specified distance function.
* @param distanceFunction The object used to calculate the distance between
* two data objects.
*/
public MTree(DistanceFunction<? super DATA> distanceFunction,
SplitFunction<DATA> splitFunction) {
this(DEFAULT_MIN_NODE_CAPACITY, distanceFunction, splitFunction);
}
/**
* Constructs an M-Tree with the specified minimum node capacity and
* distance function.
* @param minNodeCapacity The minimum capacity for the nodes of the tree.
* @param distanceFunction The object used to calculate the distance between
* two data objects.
* @param splitFunction The object used to process the split of nodes if
* they are full when a new child must be added.
*/
public MTree(int minNodeCapacity,
DistanceFunction<? super DATA> distanceFunction,
SplitFunction<DATA> splitFunction) {
this(minNodeCapacity, 2 * minNodeCapacity - 1, distanceFunction, splitFunction);
没有合适的资源?快使用搜索试试~ 我知道了~
资源推荐
资源详情
资源评论
收起资源包目录
慕课test 5星练习题 (116个子文件)
MTree$Node.class 9KB
MTree$NonLeafNodeTrait.class 8KB
MTree.class 7KB
MTree$Query$ResultsIterator.class 6KB
MTree$RootNode.class 4KB
MTree$LeafNodeTrait.class 4KB
PairTest.class 3KB
PartitionFunctions$BalancedPartition.class 3KB
MTree$RootLeafNode.class 2KB
Utils.class 2KB
DistanceFunctions.class 2KB
ComposedSplitFunction.class 2KB
MTree$Query$ResultsIterator$ItemWithDistances.class 2KB
MTree$Query.class 2KB
MTree$NonRootNodeTrait.class 2KB
DistanceFunctions$1.class 2KB
MTree$IndexItem.class 2KB
MTree$RootNodeTrait.class 2KB
PartitionFunctions$BalancedPartition$2.class 2KB
PartitionFunctions$BalancedPartition$1.class 2KB
DistanceFunctions$3.class 2KB
DistanceFunctions$4.class 2KB
PromotionFunctions$RandomPromotion.class 1KB
MTree$InternalNode.class 1KB
DistanceFunctions$4$1DoubleListEuclideanCoordinate.class 1KB
DistanceFunctions$3$1IntegerListEuclideanCoordinate.class 1KB
DistanceFunctions$1$Pair.class 1KB
MTree$LeafNode.class 1KB
MTree$NonLeafNodeTrait$1ChildWithDistance.class 1KB
MTree$NonLeafNodeTrait$1CandidateChild.class 1KB
DistanceFunctions$2.class 1KB
MTree$ResultItem.class 1010B
Pair.class 991B
MTree$Entry.class 956B
PairTest$7.class 943B
PairTest$2.class 940B
PairTest$6.class 928B
PairTest$4.class 925B
PairTest$1.class 925B
PairTest$5.class 925B
PairTest$3.class 925B
SplitFunction$SplitResult.class 917B
MTree$NodeTrait.class 892B
MTree$Leafness.class 881B
MTree$SplitNodeReplacement.class 836B
MTree$RootNodeReplacement.class 827B
MTree$NodeUnderCapacity.class 548B
MTree$DataNotFound.class 533B
SplitFunction.class 508B
PartitionFunction.class 448B
PartitionFunctions.class 411B
PromotionFunctions.class 407B
PromotionFunction.class 385B
DistanceFunctions$EuclideanCoordinate.class 285B
DistanceFunction.class 280B
MTree$Rootness.class 277B
MTree$1.class 189B
.classpath 808B
jvm.config 33B
.gitignore 182B
MTree.java.html 429KB
DistanceFunctions.java.html 74KB
PartitionFunctions.java.html 45KB
Utils.java.html 34KB
Pair.java.html 21KB
ComposedSplitFunction.java.html 16KB
PromotionFunctions.java.html 14KB
index.html 5KB
index.html 2KB
MTree.java 28KB
MTree.java 28KB
PairTest.java 14KB
PairTest.java 14KB
DistanceFunctions.java 5KB
DistanceFunctions.java 5KB
PartitionFunctions.java 3KB
PartitionFunctions.java 3KB
PairTest.java 3KB
Utils.java 2KB
Utils.java 2KB
SplitFunction.java 2KB
SplitFunction.java 2KB
ComposedSplitFunction.java 1KB
ComposedSplitFunction.java 1KB
Pair.java 1KB
Pair.java 1KB
PromotionFunctions.java 831B
PromotionFunctions.java 831B
PartitionFunction.java 795B
PartitionFunction.java 795B
PromotionFunction.java 647B
PromotionFunction.java 647B
DistanceFunction.java 243B
DistanceFunction.java 243B
createdFiles.lst 2KB
inputFiles.lst 1KB
createdFiles.lst 238B
inputFiles.lst 116B
submit.mt 44B
pro.mt 12B
共 116 条
- 1
- 2
资源评论
落叶过河
- 粉丝: 75
- 资源: 1
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
- 基于Kotlin语言的Android开发工具类集合源码
- 零延迟 DirectX 11 扩展实用程序.zip
- 基于Java的语音识别系统设计源码
- 基于Java和HTML的yang_home766个人主页设计源码
- 基于Java与前端技术的全国实时疫情信息网站设计源码
- 基于鸿蒙系统的HarmonyHttpClient设计源码,纯Java实现类似OkHttp的HttpNet框架与优雅的Retrofit注解解析
- 基于HTML和JavaScript的廖振宇图书馆前端设计源码
- 基于Java的Android开发工具集合源码
- 通过 DirectX 12 Hook (kiero) 实现通用 ImGui.zip
- 基于Java开发的YY网盘个人网盘设计源码
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功