动态最临近点算法求助

2022-10-14 19:19:57 +08:00
 wdc63

当前项目有实现以下算法的需求:

1 二维点集的最临近点查询,一次只需查询一个临近点

2 查询返回后需要实时删除得到的临近点

3 在未来某个时间需要重新插入前面被删除的对象

4 点集数不超过 50000 ,点由两个单精度浮点数定义,取值范围-500 ,500

5 对初次建立数据结构或者索引的时间或内存没有特别的需求,只要不太夸张就行。

使用 c#开发,非 unity ,整个项目对性能十分敏感,已经测试了 codeandcats 的 kdtree 开源库( https://github.com/codeandcats/KdTree ),实测很慢,对于 10000 个点进行 10000 次查询(同时进行删除操作)要花费 300ms-1800ms ,而我看到的类似 c++库 10 万点集进行十万次查询只需要个位数毫秒。codeandcats 的算法中很多浪费,例如返回的节点是新建的,因此在删除的时候需要遍历 kdtree 对比找到相应的节点。

类似的还有 ericreg 的 kdtree ,号称比前者快 7.5 倍,但是没有实现删除功能。希望性能能达到 10000 个点的查询和动态删增能达到 1 万次低于 5ms 。

也搜索过各种 rtree quadtree octree 等等,没有发现能完整实现需要功能的开源库。目前不太想自己重新造轮子,请问各位大佬有没有满足上述需求,性能较好的 c#可用的库。如果没有请各位大佬按上述需求指一条最优的算法解决方案。

1015 次点击
所在节点    程序员
3 条回复
nightwitch
2022-10-14 21:07:03 +08:00
有现成的 c++库的话且满足需求的话,包装一下导出 dll 给 c #用呗
wdc63
2022-10-14 22:59:04 +08:00
@nightwitch C++基础太弱,之前尝试过一个简单 单文件库都没能搞定,现成可用的库十几个.cpp 文件,难以下手。
wdc63
2022-10-15 19:31:05 +08:00
现在两条路线:1 PH-Tree ,据作者描述 phtree 的查询插入和删除操作都是 O(logn)的复杂度,但是看了下代码很多 https://github.com/tzaeschke/phtree
2 还是使用传统的 KDTree ,由于本项目在删除插入的工作中不会重新插入任何新点,只是把已经被选择的暂时移除,然后再移动回来而已,因此这里就直接用一个 flag 标记已经被删除的点,在 kdtree 查询最近点时,遇到这种已经被“删除”的点直接跳过。目前已经根据现有项目有一个初步实现,实测这种方法性能还不错。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/886988

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX