kd-drzewo - idea
Drzewo przedziałowe
dzielące cyklicznie po kolejnych wymiarach
kd-drzewo - Budowa
def buildTree(points, axis):
if len(points) == 1:
return Node(points[0])
median = math.median(points, itemgetter(axis))
left, right = splitBy(points, median, axis)
node = Node(median)
node.left = buildTree(leftPoints, (axis + 1) % 2)
node.right = buildTree(rightPoints, (axis + 1) %2)
return node;
kd-drzewo - budowa
Koszt:
Wyszukiwanie mediany: O(n)
Całosc:
T(n) = 2T(n/2) + O(n)
T(n) = O(n log n)
wyszukiwanie przedzialu
def processChild(child, range):
if range.fullyContains(child.range):
return root.getWholeSubtreeAsList()
elif range.intersects(child.range):
return search(child, range)
def search(root, range):
if root.leaf:
return [root.point] if range.contains(root.point)
else []
return processChild(root.left, range) +
processChild(root.right, range)
wyszukiwanie przedzialu
Koszt
T(n) = 2T(n/4)
T(n) = n^(1/2)
W ogólnosci (d -wymiarowe drzewo):
T(n) = 2^(d-1) T(n / 2^d)
T(n) = n^(1-1/d)
Problem czuły na rozwiązanie:
T(n,k) = n^(1/2) + k
Sprawdzanie przynaleznosci
punktu do zbioru
Sprowadza się do
pytania o przedział [x,y]-[x,y]
T(n) = log n
Wyszukiwanie najblizszego
sasiada
T(n) = log n
wstawianie, usuwanie
Balancing
Wstawianie, usuwanie - identycznie jak w BST
Balancing - tricky!
kd-drzewo - wady
- da się szybciej
- curse of dimensionality