First commit
This commit is contained in:
116
knnqueries.py
Normal file
116
knnqueries.py
Normal file
@@ -0,0 +1,116 @@
|
||||
import sys
|
||||
import ast
|
||||
import heapq as hq
|
||||
from math import sqrt
|
||||
|
||||
class Point:
|
||||
def __init__(self, x, y):
|
||||
self.x = x
|
||||
self.y = y
|
||||
|
||||
class MBR:
|
||||
def __init__(self, id, xlow, xhigh, ylow, yhigh):
|
||||
self.xlow = xlow
|
||||
self.xhigh = xhigh
|
||||
self.ylow = ylow
|
||||
self.yhigh = yhigh
|
||||
self.id = id
|
||||
self.obj = False
|
||||
|
||||
def setDistance(self, qp):
|
||||
self.distance = self.findDistance(qp)
|
||||
|
||||
def findDistance(self, qp):
|
||||
dx = dy = 0
|
||||
if qp.x < self.xlow:
|
||||
dx = self.xlow - qp.x
|
||||
elif qp.x > self.xhigh:
|
||||
dx = qp.x - self.xhigh
|
||||
else:
|
||||
dx = 0
|
||||
|
||||
if qp.y < self.ylow:
|
||||
dy = self.ylow - qp.y
|
||||
elif qp.y > self.yhigh:
|
||||
dy = qp.y - self.yhigh
|
||||
else:
|
||||
dy = 0
|
||||
return sqrt(dx**2 + dy**2)
|
||||
|
||||
def makeObject(self):
|
||||
self.obj = True
|
||||
|
||||
def __lt__(self, other):
|
||||
if self.distance < other.distance:
|
||||
return True
|
||||
return False
|
||||
|
||||
class Node:
|
||||
def __init__(self, leaf, id, list_of_mbrs):
|
||||
self.leaf = leaf
|
||||
self.id = id
|
||||
self.list_of_mbrs = list_of_mbrs
|
||||
|
||||
def parseRtree(filename):
|
||||
with open(filename, 'r') as f:
|
||||
nodes = []
|
||||
for line in f:
|
||||
node = ast.literal_eval(line)
|
||||
mbrs = []
|
||||
for mbr in node[2]:
|
||||
mbrs.append(MBR(int(mbr[0]), float(mbr[1][0]), float(mbr[1][1]),
|
||||
float(mbr[1][2]), float(mbr[1][3])))
|
||||
nodes.append(Node(node[0], node[1], mbrs))
|
||||
|
||||
return nodes
|
||||
|
||||
# Read and execute all the NN queries assigned to the r tree
|
||||
def parseQuery(rtree, filename, k):
|
||||
with open(filename, 'r') as f:
|
||||
num = 0
|
||||
for line in f:
|
||||
[x, y] = line.split()
|
||||
findKNN(rtree, Point(float(x), float(y)), k, num)
|
||||
num += 1
|
||||
|
||||
# Search for the neareset k neighboors
|
||||
def findKNN(rtree, qp, k, num):
|
||||
# List to put our k nn objects
|
||||
results = []
|
||||
# Initialize a priority queue
|
||||
pq = []
|
||||
# Put the root nodes into the priority queue
|
||||
for mbr in rtree[-1].list_of_mbrs:
|
||||
mbr.setDistance(qp)
|
||||
hq.heappush(pq, mbr)
|
||||
|
||||
while len(pq) > 0 and len(results) < k:
|
||||
# Retrieve the next node and remove it from the queue
|
||||
e = hq.heappop(pq)
|
||||
|
||||
if e.obj == True:
|
||||
hq.heappush(results, e)
|
||||
continue
|
||||
|
||||
# At a leaf node
|
||||
if rtree[e.id].leaf == 0:
|
||||
for mbr in rtree[e.id].list_of_mbrs:
|
||||
mbr.setDistance(qp)
|
||||
mbr.makeObject()
|
||||
hq.heappush(pq, mbr)
|
||||
# At an intermediate node
|
||||
else:
|
||||
for node in rtree[e.id].list_of_mbrs:
|
||||
node.setDistance(qp)
|
||||
hq.heappush(pq, node)
|
||||
|
||||
print("{}:".format(num), end=' ')
|
||||
for r in range(k-1):
|
||||
nn = hq.heappop(results)
|
||||
print("{},".format(nn.id), end='')
|
||||
nn = hq.heappop(results)
|
||||
print(nn.id)
|
||||
|
||||
if __name__ == '__main__':
|
||||
rtree = parseRtree(sys.argv[1])
|
||||
parseQuery(rtree, sys.argv[2], int(sys.argv[3]))
|
||||
Reference in New Issue
Block a user