Beispiel #1
0
 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
Beispiel #2
0
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
Beispiel #3
0
    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])
Beispiel #4
0
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
Beispiel #5
0
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
Beispiel #6
0
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
Beispiel #7
0
 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
Beispiel #8
0
 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]
Beispiel #9
0
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