-
Notifications
You must be signed in to change notification settings - Fork 11
Expand file tree
/
Copy pathdemo_stepwise.m
More file actions
139 lines (117 loc) · 3.7 KB
/
Copy pathdemo_stepwise.m
File metadata and controls
139 lines (117 loc) · 3.7 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
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
function demo_stepwise()
%twospirals
data=twospirals(200,360,50,1.5,15);
% data=corners(500);
s=zeros(size(data,1),1);
for i=1:size(data,1)
hold on
s(i)=scatter(data(i,1),data(i,2),'filled','markerfacecolor',[0.8,0.8,0.8]);
end
drawnow
%%
%using euclidean distance
distmat=zeros(size(data,1),size(data,1));
for i=1:size(data,1)
for j=i:size(data,1)
distmat(i,j)=sqrt((data(i,1:2)-data(j,1:2))*(data(i,1:2)-data(j,1:2))');
end
end
for i=1:size(data,1)
for j=i:size(data,1)
distmat(j,i)=distmat(i,j);
end
end
% k_dist=zeros(size(data,1),1);
% figure
% for k=3:5
% for i=1:size(data,1)
% tmp=sort(distmat(:,i),'ascend');
% k_dist(i)=tmp(k);
% end
% hold on
% plot(1:size(data,1),k_dist);
% end
%%
Eps=0.5;
MinPts=4;
DBSCAN_STEPWISE(s,distmat,Eps,MinPts);
end
function Clust = DBSCAN_STEPWISE(s,DistMat,Eps,MinPts)
%A step-wise illustration of DBSCAN on 2D data
%A simple DBSCAN implementation of the original paper:
%"A Density-Based Algorithm for Discovering Clusters in Large Spatial
%Databases with Noise" -- Martin Ester et.al.
%Since no spatial access method is implemented, the run time complexity
%will be N^2 rather than N*logN
%**************************************************************************
%Input: DistMat, Eps, MinPts
%DistMat: A N*N distance matrix, the (i,j) element contains the distance
%from point-i to point-j.
%Eps: A scalar value for Epsilon-neighborhood threshold.
%MinPts: A scalar value for minimum points in Eps-neighborhood that holds
%the core-point condition.
%**************************************************************************
%Output: Clust
%Clust: A N*1 vector describes the cluster membership for each point. 0 is
%reserved for NOISE.
%**************************************************************************
%Written by Tianxiao Jiang, jtxinnocence@gmail.com
%Nov-4-2015
%**************************************************************************
%Initialize Cluster membership as -1, which means UNCLASSIFIED
Clust=zeros(size(DistMat,1),1)-1;
ClusterId=1;
ClusterColor=rand(1,3);
%randomly choose the visiting order
VisitSequence=randperm(length(Clust));
for i=1:length(Clust)
% For each point, check if it is not visited yet (unclassified)
pt=VisitSequence(i);
if Clust(pt)==-1
%Iteratively expand the cluster through density-reachability
[Clust,isnoise]=ExpandCluster(s,DistMat,pt,ClusterId,Eps,MinPts,Clust,ClusterColor);
if ~isnoise
ClusterId=ClusterId+1;
ClusterColor=rand(1,3);
end
end
end
end
function [Clust,isnoise]=ExpandCluster(s,DistMat,pt,ClusterId,Eps,MinPts,Clust,ClusterColor)
%region query
seeds=find(DistMat(:,pt)<=Eps);
if length(seeds)<MinPts
Clust(pt)=0; % 0 reserved for noise
set(s(pt),'Marker','*');
pause(0.01)
isnoise=true;
return
else
Clust(seeds)=ClusterId;
set(s(seeds),'MarkerFaceColor',ClusterColor);
pause(0.01)
%delete the core point
seeds=setxor(seeds,pt);
while ~isempty(seeds)
currentP=seeds(1);
%region query
result=find(DistMat(:,currentP)<=Eps);
if length(result)>=MinPts
for i=1:length(result)
resultP=result(i);
if Clust(resultP)==-1||Clust(resultP)==0 % unclassified or noise
set(s(resultP),'MarkerFaceColor',ClusterColor);
pause(0.01)
if Clust(resultP)==-1 %unclassified
seeds=[seeds(:);resultP];
end
Clust(resultP)=ClusterId;
end
end
end
seeds=setxor(seeds,currentP);
end
isnoise=false;
return
end
end