【发布时间】:2019-04-26 18:12:10
【问题描述】:
我有一个问题,基本上可以看作是一个图表。我正在考虑使用 JGraphT 来实现它,而不是自己动手。使用 JGraphT 从图中获得最小生成树的最佳方法是什么?
【问题讨论】:
标签: java graph minimum-spanning-tree jgrapht
我有一个问题,基本上可以看作是一个图表。我正在考虑使用 JGraphT 来实现它,而不是自己动手。使用 JGraphT 从图中获得最小生成树的最佳方法是什么?
【问题讨论】:
标签: java graph minimum-spanning-tree 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 的算法。
如果您在算法本身方面需要帮助,有许多带有 Wikipedia 条目的算法,带有详细的描述和伪代码。 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);
}
}
}
【讨论】: