Fishnet 2.0.1
Framework for Graph-Based Analysis of GIS Vector Data
Loading...
Searching...
No Matches
DBScan.hpp
Go to the documentation of this file.
1#pragma once
2#include <assert.h>
3#include <fishnet/Graph.hpp>
6
7namespace fishnet {
8
9template<typename T>
10class DBSCAN {
11private:
12 double eps;
13 size_t minPts;
15
16 template<fishnet::graph::Graph GraphType>
17 void expandCluster(const GraphType & graph,
18 const typename GraphType::node_type & point,
20 int clusterID,
21 std::unordered_map<typename GraphType::node_type, int>& labels)
22 {
23 std::queue<typename GraphType::node_type> toProcess;
24 labels[point] = clusterID;
25 for (const auto& neighbor : neighbors) {
26 toProcess.push(neighbor);
27 }
28 while (!toProcess.empty()) {
29 auto current = toProcess.front();
30 toProcess.pop();
31 if(labels.contains(current) && labels[current] != -1) {
32 continue;
33 }
34 labels[current] = clusterID;
35 auto neighborNeighbors = regionQuery(graph, current);
36 if (fishnet::util::size(neighborNeighbors) >= minPts) {
37 for (const auto& newNeighbor : neighborNeighbors) {
38 toProcess.push(newNeighbor);
39 }
40 }
41
42 }
43 }
44
45 template<fishnet::graph::Graph GraphType>
46 auto regionQuery(const GraphType & graph, const typename GraphType::node_type & point) {
47 return graph.getNeighbours(point) | std::views::filter([&](const auto & neighbor) {
48 return distanceFunction(point, neighbor) <= eps;
49 });
50 }
51
52public:
53 DBSCAN(double eps, size_t minPts, fishnet::util::BiFunction<T,T,double> auto && distanceFunction)
54 : eps(eps), minPts(minPts), distanceFunction(std::forward<fishnet::util::BiFunction_t<T,T,double>>(distanceFunction)) {
55 assert(eps > 0 && "Epsilon must be positive");
56 assert(minPts > 0 && "Minimum Points per Cluster must be positive");
57 }
58
60 return cluster(graph);
61 }
62
63 using node_type = T;
64
65 auto cluster(fishnet::graph::Graph auto const & graph) {
66 using G = typename std::decay_t<decltype(graph)>::node_type;
67 int clusterID = 0;
68 std::unordered_map<G, int> labels;
69 for (const auto& node : graph.getNodes()) {
70 if(labels.contains(node)) {
71 continue;
72 }
73 auto neighbors = regionQuery(graph, node);
74 if (fishnet::util::size(neighbors) < minPts) {
75 labels[node] = -1;
76 continue;
77 }
78 expandCluster(graph, node, neighbors, clusterID, labels);
79 clusterID++;
80 }
81 auto vals = labels | std::views::values;
82 auto maxLabel = std::ranges::max_element(vals);
83 if(maxLabel == vals.end()){
84 return ClusterResult<G>{};
85 }
86 if(*maxLabel == -1){
87 ClusterResult<G> result;
88 for(auto && pair : labels) {
89 result.noise.push_back(std::move(pair.first));
90 }
91 return result;
92 }
93 ClusterResult<G> result;
94 result.clusters.resize(*maxLabel + 1);
95 for (auto && pair : labels) {
96 if(pair.second == -1){
97 result.noise.push_back(std::move(pair.first));
98 continue;
99 }
100 result.clusters[pair.second].push_back(std::move(pair.first));
101 }
102 return result;
103 }
104};
105
106static_assert(ClusterAlgorithm<DBSCAN<int>, fishnet::graph::UndirectedGraph<int>>);
107
108} // namespace fishnet
Definition DBScan.hpp:10
T node_type
Definition DBScan.hpp:63
ClusterResult< T > operator()(fishnet::graph::Graph auto const &graph)
Definition DBScan.hpp:59
DBSCAN(double eps, size_t minPts, fishnet::util::BiFunction< T, T, double > auto &&distanceFunction)
Definition DBScan.hpp:53
auto cluster(fishnet::graph::Graph auto const &graph)
Definition DBScan.hpp:65
Interface for graph types. Every graph type has to inherit from AbstractGraph.
Definition GraphModel.hpp:23
Definition FunctionalConcepts.hpp:15
Definition CollectionConcepts.hpp:21
graph::__impl::BaseGraph< UndirectedEdge< N, Hash, Equal >, AdjContainer > UndirectedGraph
Simple Undirected Graph type.
Definition Graph.hpp:20
std::function< R(const T &, const U &)> BiFunction_t
Definition FunctionalConcepts.hpp:18
constexpr size_t size(std::ranges::range auto &&range) noexcept
Definition CollectionConcepts.hpp:50
Definition BFSClustering.hpp:5
STL namespace.
Definition ClusterAlgorithm.hpp:9
std::vector< std::vector< R > > clusters
Definition ClusterAlgorithm.hpp:10
std::vector< R > noise
Definition ClusterAlgorithm.hpp:11