-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathdbscan.c
More file actions
85 lines (67 loc) · 2.26 KB
/
dbscan.c
File metadata and controls
85 lines (67 loc) · 2.26 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "bitvec.h"
// Data is expected to be in the form of identifiers which
// monotonically increase from 0 to whatever
// Maintain a bit array of what's a neighbour and what's not
int DBSCAN(void *data, unsigned int *d, unsigned int dlen,
float eps, unsigned int minpoints,
unsigned int (*neighbours_search)(bitvec_t *out,
void *, unsigned int, float, unsigned int *)
) {
unsigned int cluster = 1;
unsigned int count, i, j, k;
bitvec_t *visited, *clustered, *neighbours, *neighbours2;
bitvec_alloc(&visited, dlen);
bitvec_alloc(&clustered, dlen);
bitvec_alloc(&neighbours, dlen);
bitvec_alloc(&neighbours2, dlen);
// d is a list of identifiers
for (i = 0; i < dlen; i++) {
count = 0;
// Already visited this point
if (bitvec_check(visited, i)) continue;
fprintf(stderr, "Cluster: %.2f\n", 100.0*i/dlen);
// Mark this point as visited
bitvec_set(visited, i);
bitvec_clear_all(neighbours);
// Get the first set of neighbours
if(neighbours_search(neighbours, data, i, eps, &count)) {
return 1;
}
if (count < minpoints) {
*(d + i) = 0; // Noise
continue;
}
*(d + i) = cluster;
bitvec_set(clustered, i);
// Expand the cluster
for (j = 0; j < dlen; j++) {
if(!bitvec_check(neighbours, j)) continue;
if(!bitvec_check(visited, j)) {
bitvec_set(visited, j);
count = 0;
bitvec_clear_all(neighbours2);
if (neighbours_search(neighbours2, data, j, eps, &count)) {
return 1;
}
if (count >= minpoints) {
// Merge two bitarrays
bitvec_union(neighbours, neighbours2);
j = 0;
}
}
if (!bitvec_check(clustered, j)) {
*(d + j) = cluster;
bitvec_set(clustered, j);
}
}
cluster++;
}
bitvec_free(visited);
bitvec_free(clustered);
bitvec_free(neighbours);
bitvec_free(neighbours2);
return 0;
}