From 002470574f2929561e8f8e7c7508848db5cd7ae7 Mon Sep 17 00:00:00 2001 From: hxf0223 Date: Wed, 28 Aug 2024 21:49:51 +0800 Subject: [PATCH] add template example BFS search function --- _posts/2024-08-26-density-algrithm-knn.md | 71 +++++++++++++++++++++-- 1 file changed, 65 insertions(+), 6 deletions(-) diff --git a/_posts/2024-08-26-density-algrithm-knn.md b/_posts/2024-08-26-density-algrithm-knn.md index 042fe81..d7e41d2 100644 --- a/_posts/2024-08-26-density-algrithm-knn.md +++ b/_posts/2024-08-26-density-algrithm-knn.md @@ -32,7 +32,9 @@ Kdtree 算法的构建时间复杂度为 O(nlogn),搜索时间复杂度最好 由于使用点云处理库`PCL`比较庞大,以及其依的`FLANN`基于`C++14`,使用`C++17/20`导致在自定义点云数据结构时,编译有些`STL`算法库被废弃,编译出错。故使用 [nanoflann](https://github.com/jlblancoc/nanoflann)。 -### 1.1 自定义点云数据结构 +## 2. 基于 nano-flann 的聚类算法实现 + +### 2.1 自定义点云数据结构 ```c++ #pragma once @@ -74,7 +76,7 @@ struct PointCloud { }; ``` -### 1.2 基于 K-D 树构建广度优先搜索算法 +### 2.2 基于 K-D 树构建广度优先搜索算法 ```c++ #pragma once @@ -180,7 +182,7 @@ class BFSDensitySampleSearch { } // namespace rias::alg ``` -### 1.3 测试代码 +### 2.3 测试代码 ```c++ { @@ -201,7 +203,7 @@ class BFSDensitySampleSearch { } ``` -### 1.4 测试 +### 2.4 测试 ```bash [2024-08-26 21:47:35.648] [warning] [dataxy_loader.cc:146] under flow 870 samples in dataset @@ -212,14 +214,71 @@ class BFSDensitySampleSearch { TODO: 测试小数据集下的性能对比。 -### 1.5 参考 +### 2.5 参考 - [nanoflann](https://github.com/jlblancoc/nanoflann) - [空间数据结构(四叉树/八叉树/BVH树/BSP树/k-d树)](https://www.cnblogs.com/KillerAery/p/10878367.html) - [数据结构-k-d树](https://yanglei253.github.io/2020/07/11/dataStructure/dataStructure-kdtree/) - [nanoflann库使用笔记](https://zxl19.github.io/nanoflann-note/) -## 聚类算法资料收集 +## 3. 基于templated的聚类算法实现(线性搜索 O2时间复杂度) + +```c++ +template +class BFSLinerMerge { + public: + BFSLinerMerge(const std::vector& blocks, LinerFuncType linerCondFunc, AdjFuncType adjCondFunc) + : blocks_(blocks), liner_cond_func_(linerCondFunc), adj_cond_func_(adjCondFunc) {}; + + BFSLinerMerge& search() { + if (!clusters_.empty()) clusters_.clear(); + std::vector visited(blocks_.size(), false); + clusters_.reserve(blocks_.size()); + + for (size_t i = 0; i < blocks_.size(); i++) { + if (visited[i]) continue; + + std::queue q; + q.push(i); + visited[i] = true; + + std::vector cluster; + while (!q.empty()) { + size_t idx = q.front(); + q.pop(); + + const auto this_blk = blocks_[idx]; + cluster.push_back(blocks_[idx]); + + for (size_t j = 0; j < blocks_.size(); j++) { + if (visited[j]) continue; + + const auto& blkj = blocks_[j]; + if (liner_cond_func_(this_blk, blkj) && adj_cond_func_(this_blk, blkj)) { + q.push(j); + visited[j] = true; + } + } + } + + clusters_.push_back(cluster); + }; + + return *this; + } + + std::vector>& clusters() { return clusters_; } + + private: + const std::vector& blocks_; + LinerFuncType liner_cond_func_; + AdjFuncType adj_cond_func_; + + std::vector> clusters_; +}; +``` + +## 4. 聚类算法资料收集 - [几种常用的基于密度的聚类算法](https://www.cnblogs.com/alterwl/p/density-based-clustering.html) - [DBSCAN密度聚类算法](https://www.cnblogs.com/pinard/p/6208966.html)