def search_knn(self, point, k, dist=None): """ Return the k nearest neighbors of point and their distances point must be an actual point, not a node. k is the number of results to return. The actual results can be less (if there aren't more nodes to return) or more in case of equal distances. dist is a distance function, expecting two points and returning a distance value. Distance values can be any compareable type. The result is an ordered list of (node, distance) tuples. """ if dist is None: get_dist = lambda n: n.dist(point) else: get_dist = lambda n: dist(n.data, point) results = BoundedPriorityQueue(k) self._search_node(point, k, results, get_dist) # We sort the final result by the distance in the tuple # (<KdNode>, distance) BY_VALUE = lambda kv: kv[1] return sorted(results.items(), key=BY_VALUE)
def search_knn(self, point, k, dist=None): """ Return the k nearest neighbors of point and their distances point must be an actual point, not a node. k is the number of results to return. The actual results can be less (if there aren't more nodes to return) or more in case of equal distances. dist is a distance function, expecting two points and returning a distance value. Distance values can be any compareable type. The result is an ordered list of (node, distance) tuples. """ prev = None current = self # If a distance function is provided, use it, otherwise use the default Euclidean distance (Pow((x2-x1),2) + ...) if dist is None: get_dist = lambda n: n.dist(point) else: get_dist = lambda n: dist(n.data, point) # the nodes do not keep a reference to their parents parents = {current: None} # go down the tree as we would for inserting # JO: Similar to if (current == null) # I think here we search for the test point. ######while current: ###### if point[current.axis] < current.data[current.axis]: ###### # left side ###### parents[current.left] = current ###### prev = current ###### current = current.left ###### else: ###### # right side ###### parents[current.right] = current ###### prev = current ###### current = current.right ###### ######if not prev: ###### return [] examined = set() results = BoundedPriorityQueue(k) # Go up the tree, looking for better solutions ####current = prev ####while current: # search node and update results current._search_node(point, k, results, examined, get_dist) #current = parents[current] # We sort the final result by the distance in the tuple (<KdNode>, distance) BY_VALUE = lambda kv: kv[1] print ("Visited " + str(len(examined)) + " nodes.") return sorted(results.items(), key=BY_VALUE)
def search_knn(self, point, k, dist=None): """ k is the number of results to return. The actual results can be less (if there aren't more nodes to return) or more in case of equal distances. dist is a distance function, expecting two points and returning a distance value. The result is an ordered list of (node, distance) tuples. """ if dist is None: get_dist = lambda n: n.dist(point) else: get_dist = lambda n: dist(n.data, point) results = BoundedPriorityQueue(k) self._search_node(point, k, results, get_dist) BY_VALUE = lambda kv: kv[1] return sorted(results.items(), key=BY_VALUE)
def get_test_bpq(self): bound = 5 bpq = BoundedPriorityQueue(bound) for n in self.get_test_nodes(): bpq.add(n) return bpq