我想执行一些图聚类,并且由于我非常依赖Java,因此决定尝试使用Java包Jung。作为一个简单的图,我创建了每个相互连接的5个顶点的两个群集。我使用一个边缘连接两个群集。我希望在图聚类之后检索两个大小均为5的2个聚类,但是会得到不同的结果。这是代码:
import edu.uci.ics.jung.algorithms.cluster.VoltageClusterer;
import edu.uci.ics.jung.graph.Graph;
import edu.uci.ics.jung.graph.SparseGraph;
import java.io.IOException;
import java.util.Collection;
import java.util.Set;
public class CreateGraph {
public static void main(String[] args) throws IOException {
// Graph<V, E> where V is the type of the vertices
// and E is the type of the edges
Graph<Integer, String> g = new SparseGraph<Integer, String>();
for (int i = 0; i < 5; i++) {
g.addVertex((Integer) i);
}
for (int i = 0; i < 5; i++) {
for (int ii = 0; ii < 5; ii++) {
if (i != ii) {
g.addEdge("EdgeA-" + i + ii, i, ii);
}
}
}
// cluster 2
for (int i = 5; i < 10; i++) {
g.addVertex((Integer) i);
}
for (int i = 5; i < 10; i++) {
for (int ii = 5; ii < 10; ii++) {
if (i != ii) {
g.addEdge("EdgeB-" + i + ii, i, ii);
}
}
}
System.out.println(g.toString());
g.addEdge("Edge-connector", 1, 5);
System.out.println("Creating voltageclusterer");
VoltageClusterer<Integer, String> vc = new VoltageClusterer<Integer, String>(g, 2);
Collection<Set<Integer>> clusters = vc.cluster(2);
for (Set<Integer> s : clusters) {
System.out.println("set is " + s.size());
for (Integer ss : s) {
System.out.println("Element " + ss);
}
}
}
}
和输出: +
设置为1
设置为9
有人知道吗? (也欢迎提出其他有关方法的建议,只要它们在Java中即可。)
答案 0 :(得分:1)
VoltageClusterer具有一个随机元素:根据骰子滚动的方式(以及掷骰子的次数-见下文),有时您会得到非常奇怪的答案,如本例所示。您可以使用setRandomSeed()
指定随机种子。
您遇到此问题的原因是VoltageClusterer
构造函数的Javadoc错误:您要传递的数字参数不是簇数;这是正在生成的随机样本的数量。对于那个很抱歉;我们会修复它。
您几乎可以肯定要使用比2个更多的随机样本。
JUNG实现的其他聚类算法是确定性的。如果您告诉EdgeBetweennessClusterer
删除某条边,则Values(..)
会按照您的期望进行分区。