如何在Haskell中实现快速,懒惰的KDTree?

时间:2013-11-21 11:32:23

标签: haskell lazy-evaluation nearest-neighbor kdtree

我正在尝试在Haskell中实现一个kdtree(参见implementation),但我试图聪明并在实现最近邻居算法时利用Haskells的懒惰(见第46行)。

虽然技术上是正确的,但是:

minimumBy (compare `on` qd q) vs == head . nearestNeighbours (kdtree 5 vs) $ q
==> True

基于kdtree的版本要慢得多(标准:5.38ms对138.44ms,有500k数据点)。我首先想到这是由于ordMerge(第59行)中的模式匹配过于严格,但我重新编写了它,并且根据我的理解bs现在应该只根据需要进行评估。

如果是这种情况,算法应该只下降到匹配的存储桶,并在检查当前最佳最近邻居是否真的是最佳候选时重新确定。

我做了一些分析,nearestNeighhbors被调用了大约800次。鉴于树深度为8和100个测试用例,这听起来很合理,不是吗?


刚刚将我的代码上传到github:https://github.com/fhaust/threesg

这应该让你开始:

git clone https://github.com/fhaust/threesg
cd threesg
cabal sandbox init
cabal install --enable-benchmarks --enable-tests
cabal test
cabal bench --benchmark-options="+RTS -K100M -RTS"

-K100M是必需的,因为测试集是从500k点创建的)


在为github创建测试集时,我注意到,在正常的分布点上,kdtree搜索比线性搜索运行得快......可能我的问题不是算法...但我的测试集:(

1 个答案:

答案 0 :(得分:0)

最后,这是一个跟踪评估顺序的问题。我在github上传了最新版本。

看看line 74:第二个列表仅在第一个列表的第一个条目与“没有更好的候选者”标准不匹配时进行评估。

Apropos标准,我做了一些benchmarking,kd-tree确实更快。

您如何看待这个解决方案?我认为代码非常简洁易读。是否存在明显的性能损失?