我有一个基本上可以被视为图表的问题。我正在考虑使用JGraphT来实现它,而不是自己动手。使用JGraphT从图形中获取最小生成树的最佳方法是什么?
不幸的是,我不知道足够的图论给你一个完整的,直接的答案,但我在一些项目中使用了jgrapht,所以这可能会有所帮助。
jgrapht中包含的算法列表在这里:http://www.jgrapht.org/javadoc/org/jgrapht/alg/package-summary.html,你也可以在这里找到作为迭代器实现的图遍历(如果有任何帮助):http://www.jgrapht.org/javadoc/org/jgrapht/traverse/package-summary.html
我很确定这些算法都不会让你想要开箱即用,所以你必须自己编写代码,但我可以从经验告诉你,在jgrapht之上编码而不是从头开始是很容易。还有一个FibonacciHeap类可能有助于实现Prim的算法。
如果您需要有关算法本身的帮助,可以使用维基百科条目的许多算法,详细描述和伪代码。 Minimum spanning tree article链接到他们。
Jung有一个实现。
ClosestFirstIterator可以帮助你。它在迭代顶点时使用FibonacciHeap构建生成树。
ClosestFirstIterator提供方法getShortestPathLength()和getSpanningTreeEdge()以获取最小生成树的一部分。
// instantiate the iterator
ClosestFirstIterator<V,E> it = new ClosestFirstIterator<V,E>(graph, start_vertex);
// iterate to build the tree
while(it.hasNext())
it.next();
// query
double distance = getShortestPathLength(vertex);
E next_edge = getSpanningTreeEdge(vertex);
最新版本的JGraphT库有多种MST算法选择,无需从头开始实现。
以下代码适用于Java 8和JGraphT 1.3.0版。它使用(a)Prim,(b)Kruskal和(c)Borůvka的算法计算小图的最小生成树。有关不同算法的详细信息可以在维基百科关于mst problem的文章中找到。
package org.myorg.mstdemo;
import org.jgrapht.Graph;
import org.jgrapht.alg.spanning.BoruvkaMinimumSpanningTree;
import org.jgrapht.alg.spanning.KruskalMinimumSpanningTree;
import org.jgrapht.alg.spanning.PrimMinimumSpanningTree;
import org.jgrapht.graph.DefaultWeightedEdge;
import org.jgrapht.graph.builder.GraphTypeBuilder;
import org.jgrapht.util.SupplierUtil;
/**
* MST demo
*/
public class App {
public static void main(String[] args) {
Graph<String, DefaultWeightedEdge> graph = GraphTypeBuilder
.undirected()
.weighted(true)
.allowingMultipleEdges(false)
.allowingSelfLoops(false)
.vertexSupplier(SupplierUtil.createStringSupplier())
.edgeSupplier(SupplierUtil.createDefaultWeightedEdgeSupplier())
.buildGraph();
String v0 = graph.addVertex();
String v1 = graph.addVertex();
String v2 = graph.addVertex();
DefaultWeightedEdge e1 = graph.addEdge(v0, v1);
DefaultWeightedEdge e2 = graph.addEdge(v1, v2);
DefaultWeightedEdge e3 = graph.addEdge(v0, v2);
graph.setEdgeWeight(e1, 100d);
graph.setEdgeWeight(e2, 5d);
graph.setEdgeWeight(e3, 1d);
System.out.println("Prim:");
for(DefaultWeightedEdge e: new PrimMinimumSpanningTree<>(graph).getSpanningTree()) {
System.out.println(e);
}
System.out.println("Kruskal:");
for(DefaultWeightedEdge e: new KruskalMinimumSpanningTree<>(graph).getSpanningTree()) {
System.out.println(e);
}
System.out.println("Borůvka:");
for(DefaultWeightedEdge e: new BoruvkaMinimumSpanningTree<>(graph).getSpanningTree()) {
System.out.println(e);
}
}
}