@Override public boolean findNearest(P point, double maxDistance, NnData<P> result) { if( maxDistance < 0 ) search1.setMaxDistance(Double.MAX_VALUE); else search1.setMaxDistance(maxDistance); KdTree.Node found = search1.findNeighbor(point); if( found == null ) return false; result.point = (P)found.point; result.index = found.index; result.distance = search1.getDistance(); return true; }
@Override public KdTree.Node findNeighbor(P target) { bestNode = null; _findClosest(target); return bestNode; }
/** * Provide multiple trees for input and see if it finds the best one */ @Test public void multiTreeSearch() { KdTree forest[] = new KdTree[2]; forest[0] = StandardKdTreeSearch1Tests.createTreeA(); forest[1] = new KdTree(2); forest[1].root = new KdTree.Node(new double[]{12,2}); KdTreeSearch1Bbf<double[]> alg = new KdTreeSearch1Bbf<>(new KdTreeEuclideanSq_F64(2),200); alg.setTrees(forest); KdTree.Node found = alg.findNeighbor(new double[]{12, 3}); // make sure it searched some nodes besides the root ones assertTrue(alg.numNodesSearched>0); // the best node should be the root node in the second forest assertSame(found, forest[1].root); }
/** * Provide an insufficient number of steps to produce an optimal solution and see if it produces the expected * result */ @Test public void checkMaxNodes() { KdTree tree = StandardKdTreeSearch1Tests.createTreeA(); KdTreeSearch1Bbf<double[]> alg = new KdTreeSearch1Bbf<>(new KdTreeEuclideanSq_F64(2),0); alg.setTree(tree); KdTree.Node found = alg.findNeighbor(new double[]{12, 2}); // The first search from the root node is not counted. In that search it will traverse down to a leaf assertTrue(found==tree.root.left.right); }
public KdForestBbfSearch(int numberOfTrees, int maxNodesSearched, KdTreeDistance<P> distance , AxisSplitter<P> splitter) { this.forest = new KdTree[ numberOfTrees ]; this.splitter = splitter; this.search1 = new KdTreeSearch1Bbf<>(distance,maxNodesSearched); this.searchN = new KdTreeSearchNBbf<>(distance,maxNodesSearched); this.constructor = new KdTreeConstructor<P>(memory,splitter); }
@Override public void setPoints(List<P> points , boolean trackIndicies ) { if( forest[0] != null ) { for( int i = 0; i < forest.length; i++ ) memory.recycleGraph(forest[i]); } for( int i = 0; i < forest.length; i++ ) forest[i] = constructor.construct(points,trackIndicies); search1.setTrees(forest); searchN.setTrees(forest); }
public KdForestBbfSearch(int numberOfTrees, int maxNodesSearched, KdTreeDistance<P> distance , AxisSplitter<P> splitter) { this.forest = new KdTree[ numberOfTrees ]; this.splitter = splitter; this.search1 = new KdTreeSearch1Bbf<>(distance,maxNodesSearched); this.searchN = new KdTreeSearchNBbf<>(distance,maxNodesSearched); this.constructor = new KdTreeConstructor<P>(memory,splitter); }
@Override public void setPoints(List<P> points , boolean trackIndicies ) { if( forest[0] != null ) { for( int i = 0; i < forest.length; i++ ) memory.recycleGraph(forest[i]); } for( int i = 0; i < forest.length; i++ ) forest[i] = constructor.construct(points,trackIndicies); search1.setTrees(forest); searchN.setTrees(forest); }
@Override public boolean findNearest(P point, double maxDistance, NnData<P> result) { if( maxDistance < 0 ) search1.setMaxDistance(Double.MAX_VALUE); else search1.setMaxDistance(maxDistance); KdTree.Node found = search1.findNeighbor(point); if( found == null ) return false; result.point = (P)found.point; result.index = found.index; result.distance = search1.getDistance(); return true; }
/** * Performs an approximate {@link NearestNeighbor} search using K-D tree. Node are searched in Best-Bin-First * order. Distance measure is Euclidean squared. * * @see KdTreeNearestNeighbor * @see KdTreeSearch1Bbf * @see AxisSplitterMedian * * @param maxNodesSearched Maximum number of nodes it will search. Controls speed and accuracy. * @param <P> Point type. * @param distance Specifies how distance is computed between two points. * @return {@link NearestNeighbor} implementation */ public static <P> NearestNeighbor<P> kdtree( KdTreeDistance<P> distance , int maxNodesSearched ) { return new KdTreeNearestNeighbor<P>(new KdTreeSearch1Bbf<>(distance,maxNodesSearched), new KdTreeSearchNBbf<>(distance,maxNodesSearched),new AxisSplitterMedian<>(distance)); }
@Override public KdTree.Node findNeighbor(P target) { bestNode = null; _findClosest(target); return bestNode; }
/** * Performs an approximate {@link NearestNeighbor} search using K-D tree. Node are searched in Best-Bin-First * order. Distance measure is Euclidean squared. * * @see KdTreeNearestNeighbor * @see KdTreeSearch1Bbf * @see AxisSplitterMedian * * @param maxNodesSearched Maximum number of nodes it will search. Controls speed and accuracy. * @param <P> Point type. * @param distance Specifies how distance is computed between two points. * @return {@link NearestNeighbor} implementation */ public static <P> NearestNeighbor<P> kdtree( KdTreeDistance<P> distance , int maxNodesSearched ) { return new KdTreeNearestNeighbor<P>(new KdTreeSearch1Bbf<>(distance,maxNodesSearched), new KdTreeSearchNBbf<>(distance,maxNodesSearched),new AxisSplitterMedian<>(distance)); }
@Override public KdTreeSearch1<double[]> createAlg() { // specify so many max nodes that it will be optimal return new KdTreeSearch1Bbf<>(new KdTreeEuclideanSq_F64(N),10000); } }