我正在尝试使用Kruskal的最小生成树算法进行K-Means聚类。我的原始设计是运行输入的全长Kruskal算法并生成一个MST,然后删除最后的k-1边(或等价k-1最昂贵的边)。
当然这与运行Kruskal算法相同,并在它添加最后的k-1边之前停止它。
我想使用第二种策略,即不是运行全长Kruskal算法,而是在到目前为止的簇数量等于K之后停止它。我正在使用Union-Find数据结构并在此Union中使用列表对象 - 查找数据结构。
此图表上的每个顶点由此列表中的当前聚类表示,例如[1,2,3...]
表示顶点1,2,3位于其不同的独立聚类中。如果连接了两个顶点,则更新列表数据结构上的相应索引以反映这一点。
例如,合并顶点2和3使列表数据对象保留为[1,2,2,4,5.....]
我的策略是每次合并两个节点,计算列表中DISTINCT元素的数量,如果它等于所需簇的数量,则停止。我担心这可能不是最有效的选择。有没有办法可以有效地计算列表中不同对象的数量?
答案 0 :(得分:2)
最简单且效率最高的是
len(set(l))
其中l
是列表。如果合适,您可以考虑首先将数据存储在集合而不是列表中。
请注意,为了实现这一点,l
的元素必须是可清除的,这对于数字是有保证的,但对于通用"对象"则不是。
答案 1 :(得分:1)
一种方法是对列表进行排序,然后通过将每个元素与前一个元素进行比较来遍历元素。如果它们与你的“独特计数器”不等于1。这个操作是O(n),对于排序你可以使用你喜欢的排序算法,比如快速排序或合并排序,但我想你使用的lib中有一个可用的排序算法。
另一个选择是创建一个哈希表并添加所有元素。插入的数量将是不同的元素,因为不会插入重复的元素。我认为在最好的情况下这是O(1)所以也许这是更好的解决方案。祝你好运!
希望这有帮助,
DídacPérez