Пример #1
0
 @Override
 public boolean findNearest(double[] point, double maxDistance, NnData<PointData> result) {
   boolean r =
       searchNearest(
           point, maxDistance < 0 ? Double.POSITIVE_INFINITY : Math.sqrt(maxDistance), result);
   result.distance *= result.distance; // Callee expects squared distance
   return r;
 }
Пример #2
0
  @Override
  public void findNearest(
      double[] target, double maxDistance, int numNeighbors, FastQueue<NnData<PointData>> results) {
    PriorityQueue<HeapItem> heap =
        search(
            target,
            maxDistance < 0 ? Double.POSITIVE_INFINITY : Math.sqrt(maxDistance),
            numNeighbors);

    while (!heap.isEmpty()) {
      final HeapItem heapItem = heap.poll();
      NnData<PointData> objects = new NnData<PointData>();
      objects.data = itemData[heapItem.index];
      objects.point = items[heapItem.index];
      objects.distance = heapItem.dist * heapItem.dist; // squared distance is expected
      results.add(objects);
    }

    results.reverse();
  }
Пример #3
0
  /**
   * Equivalent to the above search method to find one nearest neighbor. It is faster as it does not
   * need to allocate and use the heap data structure.
   *
   * @param target target point
   * @param maxDistance maximum distance
   * @param result information about the nearest point (output parameter)
   * @return true if a nearest point was found within maxDistance
   */
  private boolean searchNearest(
      final double[] target, double maxDistance, NnData<PointData> result) {
    if (root == null) {
      return false;
    }

    double tau = maxDistance;
    final FastQueue<Node> nodes = new FastQueue<Node>(20, Node.class, false);
    nodes.add(root);
    result.distance = Double.POSITIVE_INFINITY;
    boolean found = false;

    while (nodes.size() > 0) {
      final Node node = nodes.getTail();
      nodes.removeTail();
      final double dist = distance(items[node.index], target);

      if (dist <= tau && dist < result.distance) {
        result.distance = dist;
        result.data = itemData[node.index];
        result.point = items[node.index];
        tau = dist;
        found = true;
      }

      if (node.left != null && dist - tau <= node.threshold) {
        nodes.add(node.left);
      }

      if (node.right != null && dist + tau >= node.threshold) {
        nodes.add(node.right);
      }
    }

    return found;
  }