-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathrtreeNN.py
124 lines (110 loc) · 3.44 KB
/
rtreeNN.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
'''
rtreeNN.py
Arguements: -d <datasetFile>, -q <queryFile>, -b <Bvalue>
Author: Yi Liu
Best First algorithm to solve nearest neighbor queries
'''
# standard libraries
import time
import getopt
import sys
# private libraries
import rtreeBuilder
import Rtree
import scanNN
# the nearest distance
global distance
# the nearest neighbors
global results
# the nearest distance from a query point to a node
def nDis(node, query):
dis = 0
# component on x axis
if query[0] < node.range[0]:
dis += (node.range[0]-query[0])**2
elif query[0] > node.range[1]:
dis += (query[0]-node.range[1])**2
# component on y axis
if query[1] < node.range[2]:
dis += (node.range[2]-query[1])**2
elif query[1] > node.range[3]:
dis += (query[1]-node.range[3])**2
# if the query point is inside of the node, return 0
return dis
# in a leaf, find all points which have the least distance from the query point
def getNN(leaf, query):
global distance
global results
for point in leaf.childList:
newDis = (point.x-query[0])**2 + (point.y-query[1])**2
if newDis < distance:
distance = newDis
results.clear()
results.append(point)
elif newDis == distance:
results.append(point)
# answer a NN query using "Best First" algorithm
def bestFirst(tupleList, query):
global distance
if isinstance(tupleList[0][1], Rtree.Branch):
node = tupleList[0][1]
# remove the first element in the tuple list
del tupleList[0]
# add all children of the first node to the tuple list
for child in node.childList:
tupleList.append((nDis(child, query), child))
# sort the tuple list by distance
tupleList = sorted(tupleList, key=lambda t:t[0])
elif isinstance(tupleList[0][1], Rtree.Leaf):
node = tupleList[0][1]
# remove the first element in the tuple list
del tupleList[0]
getNN(node, query)
# in this case, the NN has been found
if distance < tupleList[0][0]:
return
# implement Best First algorithm resursively
bestFirst(tupleList, query)
# answer all the queries using "Best First" algorithm with a given r-tree
def answerNnQueries(root, queries):
global distance
global results
resultFile = 'resultNN.txt'
# the start time
timeStart = time.time()
f = open(resultFile, 'wt')
for query in queries:
# initialize global variables
distance = float('inf')
results = []
# answer query
bestFirst([(0, root)], query)
for result in results:
f.write(str(result.ident) + ' ')
f.write('\r\n')
# the end time
timeEnd = time.time()
f.close()
i = len(queries)
print('NN Queries finished. Average time: ' + str((timeEnd-timeStart)/i))
def main():
datasetFile = 'dataset.txt'
queryFile = 'queriesNN.txt'
Bvalue = None
# parse arguments
options,args = getopt.getopt(sys.argv[1:],"d:q:b:")
for opt, para in options:
if opt == '-d':
datasetFile = para
if opt == '-q':
queryFile = para
if opt == '-b':
Bvalue = int(para)
# build r-tree
root = rtreeBuilder.buildRtree(datasetFile, Bvalue)
rtreeBuilder.checkRtree(root)
# answer NN queries
queries = scanNN.readNn(queryFile)
answerNnQueries(root, queries)
if __name__ == '__main__':
main()