DBSCAN(D, eps, MinPts)
   C = 0
   for each unvisited point P in dataset D
      mark P as visited
      NeighborPts = regionQuery(P, eps)
      if sizeof(NeighborPts) < MinPts
         mark P as NOISE
      else
         C = next cluster
         expandCluster(P, NeighborPts, C, eps, MinPts)

expandCluster(P, NeighborPts, C, eps, MinPts)
   add P to cluster C
   for each point P' in NeighborPts
      if P' is not visited
         mark P' as visited
         NeighborPts' = regionQuery(P', eps)
         if sizeof(NeighborPts') >= MinPts
            NeighborPts = NeighborPts joined with NeighborPts'
      if P' is not yet member of any cluster
         add P' to cluster C

regionQuery(P, eps)
   return all points within P's eps-neighborhood

上面是。如你所见,根据维基百科的dbscan算法。
我想问一下这个确切的部分。
      NeighborPts = NeighborPts joined with NeighborPts'

我的理解是,如果访问了核心点邻居的核心点,它将加入到当前检查的集群中,对吗但是递归是怎么发生的呢?因为我们定义了循环:
   for each point P' in NeighborPts

在加入之前,expandCluster函数不会检查neighborrpts中的任何额外点,如果新的neighborrpts实际上有一个点是同一个集群的另一个核心点,那么该算法如何进行?
我有一个用Java实现“expandcluster”方法的代码:
public void expand(Vector<Integer> region, Group c, double dist, int minPts){
    for(int i = 0; i < region.size(); i++){
        int idx = region.get(i);
        if(labels[idx] == 0){                         // check if point is visited
            labels[idx] = 1;                          // mark as visited
            Vector<Integer> v = region(idx, dist);    // check for neighboring point
            if (v.size() >= minPts){                  // check if core point
                region.addAll(v);                     // join the NeighborPts
            }
        }
        if(clustered[idx] == 0){
            c.elements.add(patterns.get(idx));
            clustered[idx] = clusters.size()+1;
        }
    }
}

通过此代码修改数据收集后,是否将重新访问数据收集?

最佳答案

我的理解是如果一个核心点来自核心的邻居
点被访问,它将加入当前检查的群集,
正确的?
是的,你是对的,你可以安全地移除线路
如果不去拜访P'
然而,这并不有效。
如果一个点P'已经被访问过,则无需计算它的邻域并将其与P'的邻域连接。
它被访问的意思是:它是一个噪声点,它已经在一个集群中,或者它是一个边界点。
如果它已经在集群中并且是核心点,这意味着它的邻居已经被处理过了。
如果它是一个边界点,那么它的邻居就不能加入。
但是递归是怎么发生的呢?
排队
对于邻居中的每一点p'
必须将NeighborPts视为点的动态容器第一次输入for循环NeighborPts时包含X点。如果连接将Y点添加到NeighborPts上,则for循环将访问XY集然后对集合XY重复此操作,这就是递归的发生方式。
数据收集区域将在
通过此代码修改数据收集
地区.地址(v);?
是的,每次调用region.addAll(v)region.size()都会增加,这证实了递归行为会让您感到困惑。

08-06 04:45