def NN(self, q): IO = 0 root = self.root IO += 1 heap = common.MinHeap() heap.push((q.distance(root.box), root)) distance_upper_bound = np.inf nn_id = None while len(heap) > 0: min_distance, node = heap.pop() if isinstance(node, KDTree.LeafNode): for i in node.idx: IO += 1 p = self.points[i] dist = p.distance(q) if dist < distance_upper_bound: nn_id = i distance_upper_bound = dist else: if min_distance > distance_upper_bound: break if q.coords[0][node.split_dim] < node.split: near, far = node.less, node.greater else: near, far = node.greater, node.less IO += 2 heap.push((min_distance, near)) far_min_distance = far.box.distance(q) if far_min_distance <= distance_upper_bound: heap.push((far_min_distance, far)) return (nn_id, self.points[nn_id], distance_upper_bound), IO
def pruning(q_id, q, k, index, partition_num): partitions = common.partitions(q, index.space, partition_num) sigLists = [[] for i in range(partition_num)] upper_arc_radius_heaps = [common.MaxHeap() for i in range(partition_num)] shaded_areas = [calculate_shaded_area(partition, partition.r) for partition in partitions] h = common.MinHeap() IO = 0 h.push((0, index.root)) while len(h) > 0: e_dist, e = h.pop() if may_contains_significant_facility(e, shaded_areas): if e.is_data_node: pruneSpace(q_id, e, k, partitions, sigLists, upper_arc_radius_heaps, shaded_areas) else: for child in e.children: h.push((child.geom.distance(q), child)) IO += 1 unpruned_area_list = list() for i in range(partition_num): r_b = min(upper_arc_radius_heaps[i].first(), partitions[i].r) angles = [2 * pi / partition_num * i, 2 * pi / partition_num * (i + 1)] if r_b > 0: unpruned_area_list.append(common.sector(q, r_b, angles).buffer(0.01)) unpruned_area = reduce(lambda x, y: x.union(y), unpruned_area_list) return sigLists, unpruned_area, IO
def kNN(self, q, k): min_distance = q.distance(self.root.box) heap = common.MinHeap() heap.push((min_distance, self.root)) neighbors = [] distance_upper_bound = np.inf while len(heap) > 0: min_distance, node = heap.pop() if isinstance(node, KDTree.LeafNode): for i in node.idx: p = self.points[i] dist = p.distance(q) if dist < distance_upper_bound: if len(neighbors) == k: heappop(neighbors) heappush(neighbors, (-dist, i)) if len(neighbors) == k: distance_upper_bound = -neighbors[0][0] else: if min_distance > distance_upper_bound: break if q.coords[0][node.split_dim] < node.split: near, far = node.less, node.greater else: near, far = node.greater, node.less heap.push((min_distance, near)) far_min_distance = far.box.distance(q) if far_min_distance <= distance_upper_bound: heap.push((far_min_distance, far)) return sorted([(i, self.points[i], -d) for (d, i) in neighbors])
def kNN(index, q, k, cache, nn=None): IO = 0 knn = list() h = common.MinHeap() if nn is None: (nn_o, nn_p, nn_dist), nn_io = NN(index, q) cache[nn_o] = nn_p IO += nn_io else: nn_o, nn_p, nn_dist = nn vd = index.voronoi_diagram points = index.points h.push((nn_dist, nn_o, nn_p)) visited = {nn_o} count = 0 while count < k and len(h) > 0: dist, o, p = h.pop() knn.append((o, p, dist)) for neighbor in vd.neighbors(o): if neighbor not in visited: if neighbor in cache: neighbor_p = cache[neighbor] else: neighbor_p = points[neighbor] cache[neighbor] = neighbor_p IO += 1 visited.add(neighbor) h.push((points[neighbor].distance(q), neighbor, neighbor_p)) count += 1 return knn, IO
def bi_pruning(q_id, q, k, index, cache): IO = 0 partitions = list(common.partitions(q, index.space, 6)) region_list = list() points = index.points vd = index.voronoi_diagram visited = {q_id} H = common.MinHeap() S = [common.MaxHeap() for i in range(6)] for neighbor_id in vd.neighbors(q_id): if neighbor_id in cache: neighbor_p = cache[neighbor_id] else: neighbor_p = points[neighbor_id] cache[neighbor_id] = neighbor_p IO += 1 H.push((1, neighbor_id, neighbor_p)) visited.add(neighbor_id) while len(H) > 0: gd_p, p_id, p = H.pop() for i in range(6): if partitions[i].intersects(p): if len(S[i]) < k: dist_bound = float('inf') else: dist_bound = S[i].first()[0] dist_p = p.distance(q) if gd_p <= k and dist_p < dist_bound: S[i].push((dist_p, p_id, p)) for neighbor_id in vd.neighbors(p_id): if neighbor_id not in visited: if neighbor_id in cache: neighbor_p = cache[neighbor_id] else: neighbor_p = points[neighbor_id] cache[neighbor_id] = neighbor_p IO += 1 gd_neighbor = gd_p + 1 visited.add(neighbor_id) H.push((gd_neighbor, neighbor_id, neighbor_p)) for i in range(6): s = sorted(S[i]) if len(s) >= k: r = s[k - 1][0] elif len(s) > 0: r = s[-1][0] else: r = 0 if r > 0: region_list.append( common.sector(q, r, partitions[i].angles).buffer(0.01)) region = reduce(lambda x, y: x.union(y), region_list) return region, IO
def mono_pruning(q_id, q, k, index, cache): IO = 0 partitions = list(common.partitions(q, index.space, 6)) region_list = list() points = index.points vd = index.voronoi_diagram visited = {q_id} H = common.MinHeap() S = [common.MaxHeap() for i in range(6)] for neighbor_id in vd.neighbors(q_id): if neighbor_id in cache: neighbor_p = cache[neighbor_id] else: neighbor_p = points[neighbor_id] cache[neighbor_id] = neighbor_p IO += 1 H.push((1, neighbor_id, neighbor_p)) visited.add(neighbor_id) while len(H) > 0: gd_p, p_id, p = H.pop() for i in range(6): if partitions[i].intersects(p): if len(S[i]) < k: dist_bound = float('inf') else: dist_bound = S[i].first()[0] dist_p = p.distance(q) if gd_p <= k and dist_p < dist_bound: S[i].push((dist_p, p_id, p)) for neighbor_id in vd.neighbors(p_id): if neighbor_id not in visited: if neighbor_id in cache: neighbor_p = cache[neighbor_id] else: neighbor_p = points[neighbor_id] cache[neighbor_id] = neighbor_p IO += 1 gd_neighbor = gd_p + 1 visited.add(neighbor_id) H.push((gd_neighbor, neighbor_id, neighbor_p)) candidate_idx = set() candidates = list() for i in range(6): s = sorted(S[i]) if len(s) >= k: s = s[:k] for dist, p_id, p in s: if p_id not in candidate_idx: candidate_idx.add(p_id) candidates.append((p_id, p, dist)) return candidates, IO
def kNN(self, q, k): knn = list() h = common.MinHeap() nn_o, nn_p, nn_dist = self.NN(q) vd = self.voronoi_diagram points = self.points h.push((nn_dist, nn_o)) visited = {nn_o} count = 0 while count < k and len(h) > 0: dist, o = h.pop() p = points[o] knn.append((o, p, dist)) for neighbor in vd.neighbors(o): if neighbor not in visited: visited.add(neighbor) h.push((points[neighbor].distance(q), neighbor)) count += 1 return knn
def nearest(self, q, k=1): min_heap = common.MinHeap() knn = common.MaxHeap() min_heap.push((0, self.root)) while len(min_heap) > 0: node_min_dist, node = min_heap.pop() if len(knn) >= k and node_min_dist > knn.first()[0]: break if node.is_leaf_node: for c in node.children: c_min_dist = c.geom.distance(q) if len(knn) < k or c_min_dist < knn.first()[0]: knn.push((c_min_dist, c)) if len(knn) > k: knn.pop() else: for c in node.children: c_min_dist = c.geom.distance(q) if len(knn) < k or c_min_dist < knn.first()[0]: min_heap.push((c_min_dist, c)) return [(e[1].obj, e[1].geom, e[0]) for e in knn.values]
def NN(index, q): IO = 0 h = common.MinHeap() h.push((0, index.root)) IO += 1 best_dist = float('inf') nn = None while len(h) > 0: e_dist, e = h.pop() if e.is_leaf_node: for child in e.children: IO += 1 c_dist = child.geom.distance(q) if c_dist < best_dist: nn = child best_dist = c_dist if index.voronoi_diagram.cell(nn.obj).intersects(q): return (nn.obj, nn.geom, best_dist), IO else: for child in e.children: IO += 1 c_dist = child.geom.distance(q) h.push((c_dist, child)) return (nn.obj, nn.geom, best_dist), IO