我在java中实现DBSCAN。我遵循了这里给出的算法(维基百科)。我认为我说得对,但由于某种原因,只形成了 1 个集群。Java代码看起来像
ArrayList<ArrayList<Node>> dbcluster = new ArrayList<>();
ArrayList<Node> points; // this contains my data assume
int min =10, esp =50;
int clustcount =0;
for(int i=0;i<points.size();i++){
Node tempdb = points.get(i);
if(tempdb.visited==false){
tempdb.visited=true;
ArrayList<Node> myNeighbors = getNeigbhors(tempdb,points, esp);
if(myNeighbors.size() < min){
tempdb.noise = true;
}else{
//ArrayList<Node> tempclust = new ArrayList<>();
dbcluster.add(new ArrayList<Node>());
expandCluster(tempdb,points,myNeighbors,dbcluster,esp,min,clustcount);
clustcount++;
}
}
public static ArrayList<Node> getNeigbhors(Node p ,ArrayList<Node> data,int esp){
ArrayList<Node> tempReturn = new ArrayList<>();
for(int i=0;i<data.size();i++){
Node temptemp = data.get(i);
if(p.x != temptemp.x && p.y !=temptemp.y){
double distance =Math.sqrt(((p.x - temptemp.x)*(p.x - temptemp.x))+((p.y - temptemp.y)*(p.y - temptemp.y)));
if(distance <=esp){
tempReturn.add(temptemp);
}
}
}
return tempReturn;
}
public static void expandCluster(Node p, ArrayList<Node> data, ArrayList<Node> N, ArrayList<ArrayList<Node>> allCluster,int esp, int min,int clustcount){
//ArrayList<Node> tempSmallClust = new ArrayList<>();
//tempSmallClust.add(p);
allCluster.get(clustcount).add(p);
for(int i=0;i<N.size();i++){
Node tempP = N.get(i);
if(tempP.visited == false){
tempP.visited=true;
ArrayList<Node> tempNewNeighbors = new ArrayList<>();
tempNewNeighbors = getNeigbhors(tempP, data, esp);
if(tempNewNeighbors.size() >= min){
ArrayList<Node> tempN=new ArrayList<>();
tempN=mergeNeighbors(N, tempNewNeighbors);
N = new ArrayList<>();
N=tempN;
}
}
if(!checkInCluster(tempP,allCluster)) {
allCluster.get(clustcount).add(tempP);
}
}
//return tempSmallClust;
}
public static boolean checkInCluster(Node p, ArrayList<ArrayList<Node>> allCluster){
for(int i=0;i<allCluster.size();i++){
ArrayList<Node> tempList = allCluster.get(i);
if(tempList.contains(p)){
return true;
}
}
return false;
}
public static ArrayList<Node> mergeNeighbors(ArrayList<Node> N,ArrayList<Node> NewN){
ArrayList<Node> tmpR = N;
for(int i=0;i<NewN.size();i++){
if(!N.contains(NewN.get(i))){
tmpR.add(NewN.get(i));
}
}
return tmpR;
}
节点类很简单,具有 int x int y 和布尔噪声并已访问。数据在这里提供数据