2009-04-15 102 views
3

我用Java编写的凝聚聚类算法和与删除操作后,故障没有删除。当簇的数量达到初始数量的一半时,似乎总是失败。从一个HashSet迭代它

在下面的示例代码,clustersCollection<Collection<Integer>>

 while(clusters.size() > K){ 
      // determine smallest distance between clusters 
      Collection<Integer> minclust1 = null; 
      Collection<Integer> minclust2 = null; 
      double mindist = Double.POSITIVE_INFINITY; 

      for(Collection<Integer> cluster1 : clusters){ 
       for(Collection<Integer> cluster2 : clusters){ 
        if(cluster1 != cluster2 && getDistance(cluster1, cluster2) < mindist){ 
          minclust1 = cluster1; 
          minclust2 = cluster2; 
          mindist = getDistance(cluster1, cluster2); 
        } 
       } 
      } 

      // merge the two clusters 
      minclust1.addAll(minclust2); 
      clusters.remove(minclust2); 
     } 

通过循环几运行后,最终clusters.remove(minclust2)返回false,但我不明白为什么。

我通过首先从1到10的距离创建群10,各自与一个整数测试此代码是随机数0和1之间下面是增加了一些println语句后的输出。在群集数量之后,我打印出实际的群集,合并操作以及clusters.remove(minclust2)的结果。

Clustering: 10 clusters 
[[3], [1], [10], [5], [9], [7], [2], [4], [6], [8]] 
[5] <- [6] 
true 
Clustering: 9 clusters 
[[3], [1], [10], [5, 6], [9], [7], [2], [4], [8]] 
[7] <- [8] 
true 
Clustering: 8 clusters 
[[3], [1], [10], [5, 6], [9], [7, 8], [2], [4]] 
[10] <- [9] 
true 
Clustering: 7 clusters 
[[3], [1], [10, 9], [5, 6], [7, 8], [2], [4]] 
[5, 6] <- [4] 
true 
Clustering: 6 clusters 
[[3], [1], [10, 9], [5, 6, 4], [7, 8], [2]] 
[3] <- [2] 
true 
Clustering: 5 clusters 
[[3, 2], [1], [10, 9], [5, 6, 4], [7, 8]] 
[10, 9] <- [5, 6, 4] 
false 
Clustering: 5 clusters 
[[3, 2], [1], [10, 9, 5, 6, 4], [5, 6, 4], [7, 8]] 
[10, 9, 5, 6, 4] <- [5, 6, 4] 
false 
Clustering: 5 clusters 
[[3, 2], [1], [10, 9, 5, 6, 4, 5, 6, 4], [5, 6, 4], [7, 8]] 
[10, 9, 5, 6, 4, 5, 6, 4] <- [5, 6, 4] 
false 

的所述[10,9,5,6,4,5,6,4,...]仅有无限从那里生长。

编辑:为了澄清,我使用集群中每一个群(一HashSet<HashSet<Integer>>)

+0

[10,9,5,6,4,5,6,4,...]显然不是一组。这是一个列表吗? – 2009-04-16 00:27:44

+0

是的,好点。 HashSet不应该能够包含重复的对象。这里的东西很奇怪。 – 2009-04-16 00:43:02

回答

5

啊。当您更改已在Set(或Map键)中的值时,它不一定处于正确位置,并且散列码将被缓存。你需要删除它,修改它,然后重新插入它。

0

明显的问题还有就是clusters.remove可能是使用equals找到去除不幸的是equals元素。对收藏一般比较是否元素是相同的,而不是如果它是相同的集合(我相信C#在这方面做出了更好的选择)

AN简单修复是创建clustersCollections.newSetFromMap(new IdentityHashMap<Collection<Integer>, Boolean>())(I认为)。

+0

关于平等的好处,但即使它使用平等,为什么移除会失败? – weiyin 2009-04-16 00:32:17

1

在所示的测试中,remove失败你第一次尝试删除包含多个整数的集合。情况总是如此吗?

什么具体类型集合的使用呢?

+0

是的,你走在正确的轨道上。第一次尝试删除具有多个整数的集合时,它总是失败。对群集中的每个群集使用HashSet (HashSet >)。 – weiyin 2009-04-16 00:34:57