Kd::Tree
Crystal implementation of "K-Dimensional Tree" and "N-Nearest Neighbors" based on http://en.wikipedia.org/wiki/Kd-tree.
Installation
Add this to your application's shard.yml
:
dependencies:
kd_tree:
github: geocrystal/kd_tree
Usage
require "kd_tree"
Construct a new tree. Each point should be of the form [x, y]
, where x
and y
are numbers(Int32
, Float64
, etc):
kd = Kd::Tree(Int32).new(points)
Find the nearest point to [x, y]
. Returns an array with one point:
kd.nearest([x, y])
Find the nearest k
points to [x, y]
. Returns an array of points:
kd.nearest([x, y], k)
Example
require "kd_tree"
points = [
[2.0, 3.0],
[5.0, 4.0],
[4.0, 7.0],
[7.0, 2.0],
[8.0, 1.0],
[9.0, 6.0],
]
kd = Kd::Tree(Float64).new(points)
kd.nearest([1.0, 1.0])
# => [[2.0, 3.0]])
kd_tree.nearest([1.0, 1.0], 2)
# => [[2.0, 3.0], [5.0, 4.0]])
Performance
Using a tree with 1 million points [x, y] of Float64
on my i7-8550U CPU @ 1.80GHz:
crystal run benchmark/benchmark.cr --release
Benchmarking KD-Tree with 1 million points
build(init): 4.34 seconds
user system total real
nearest point 1 0.000017 0.000001 0.000018 ( 0.000017)
nearest point 5 0.000022 0.000000 0.000022 ( 0.000022)
nearest point 10 0.000021 0.000001 0.000022 ( 0.000022)
nearest point 50 0.000058 0.000001 0.000059 ( 0.000059)
nearest point 100 0.000087 0.000002 0.000089 ( 0.000089)
nearest point 255 0.000248 0.000005 0.000253 ( 0.000254)
nearest point 999 0.001033 0.000020 0.001053 ( 0.001055)
Contributing
- Fork it (https://github.com/geocrystal/kd_tree/fork)
- Create your feature branch (
git checkout -b my-new-feature
) - Commit your changes (
git commit -am 'Add some feature'
) - Push to the branch (
git push origin my-new-feature
) - Create a new Pull Request
Contributors
- mamantoha Anton Maminov - creator, maintainer