我在java中实现DBSCAN。我遵循here (Wikipedia)给出的算法。我认为我说得对,但由于某种原因,只形成一个集群。 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和布尔噪声并访问。 这里提供的数据为here data
答案 0 :(得分:1)
您的数据是统一分布的。
此数据集中没有群集。
恕我直言,将所有内容放在一个群集中是正确的(如果eps太高而且碎片太低)是正确的,或者将所有内容都置于噪音中(如果eps和minpts设置得恰当)。
所以也许它不是一个实现错误,但你的数据不合适。