Source From Here
Question
I have a problem that can essentially be viewed as a graph. I'm considering using JGraphT to implement it instead of rolling my own. What would be the best way to get a minimum spanning tree out of a graph using JGraphT?
How-To
The list of algorithms included with jgrapht is here, and you can also find graph traversals implemented as iterators (if that is any help) here.
Below are some algorithm sample code related to MST. First of all, we create a SimpleWeightedGraph object as target graph for follow up sample code:
The graph which looks like:
- Prim Algorithm (PrimMinimumSpanningTree)
Output:
- Kruskal Algorithm (KruskalMinimumSpanningTree)
Output:
Or you can implement your own MST by extends MinimumSpanningTree class. For example:
Testing Code:
Output:
Supplement
* [ Alg info ] Borůvka's algorithm (MST)
Question
I have a problem that can essentially be viewed as a graph. I'm considering using JGraphT to implement it instead of rolling my own. What would be the best way to get a minimum spanning tree out of a graph using JGraphT?
How-To
The list of algorithms included with jgrapht is here, and you can also find graph traversals implemented as iterators (if that is any help) here.
Below are some algorithm sample code related to MST. First of all, we create a SimpleWeightedGraph object as target graph for follow up sample code:
- package graph.alg
- import org.jgrapht.alg.PrimMinimumSpanningTree
- import org.jgrapht.graph.DefaultWeightedEdge
- import org.jgrapht.graph.SimpleWeightedGraph
- // 0) Initialize Graph
- SimpleWeightedGraph
g = - new SimpleWeightedGraph
(DefaultWeightedEdge. class) - // 1) Build Graph
- g.addVertex("A")
- g.addVertex("B")
- g.addVertex("C")
- g.addVertex("D")
- g.addVertex("E")
- g.addVertex("F")
- def edges = [:]
- edges["A"]=["B": 6, "F":12, "E":10]
- edges["B"]=["A": 6, "C": 3, "D": 5, "F": 8]
- edges["C"]=["B": 3, "D": 7]
- edges["D"]=["B": 5, "C": 7, "E": 9, "F":11]
- edges["E"]=["A":10, "D": 9, "F":16]
- edges["F"]=["A":12, "B": 8, "D":11, "E":16]
- edges.each{ k, v->
- v.each{ n, w->
- DefaultWeightedEdge e = g.addEdge(k, n)
- if(e!=null)
- {
- g.setEdgeWeight(e, w)
- }
- }
- }
- Prim Algorithm (PrimMinimumSpanningTree)
- printf("\t[Info] Prim's MST:\n")
- PrimMinimumSpanningTree pMST = new PrimMinimumSpanningTree(g)
- for(DefaultWeightedEdge e:pMST.getMinimumSpanningTreeEdgeSet())
- {
- printf("\t%s (%.01f)\n", e, e.getWeight())
- }
- Kruskal Algorithm (KruskalMinimumSpanningTree)
- KruskalMinimumSpanningTree kMST = new KruskalMinimumSpanningTree(g)
- printf("\t[Info] Kruskal's MST (%.01f):\n", kMST.getMinimumSpanningTreeTotalWeight())
- for(DefaultWeightedEdge e:kMST.getMinimumSpanningTreeEdgeSet())
- {
- printf("\t%s (%.01f)\n", e, e.getWeight())
- }
Or you can implement your own MST by extends MinimumSpanningTree class. For example:
- package graph.alg.cust
- import org.jgrapht.Graph
- import org.jgrapht.alg.interfaces.MinimumSpanningTree
- class JPrimMinimumSpanningTree
{ - /**
- * Minimum Spanning-Tree/Forest edge set
- */
- private final List
minimumSpanningTreeEdgeList; - /**
- * Minimum Spanning-Tree/Forest edge set overall weight
- */
- private final double minimumSpanningTreeTotalWeight;
- public JPrimMinimumSpanningTree(final Graph
g, V sv = null) - {
- minimumSpanningTreeEdgeList = new LinkedList
() - Set
unspanned = new HashSet (g.vertexSet()) - Set
spanned = new HashSet () - while (!unspanned.isEmpty())
- {
- PriorityQueue
dangling = - new PriorityQueue
( - g.edgeSet().size(),
- new Comparator
() { - @Override public int compare(E lop, E rop)
- {
- return Double.valueOf(g.getEdgeWeight(lop))
- .compareTo(g.getEdgeWeight(rop));
- }
- });
- if(sv==null)
- {
- sv = unspanned.iterator().next()
- unspanned.remove(sv)
- }
- spanned.add(sv)
- dangling.addAll(g.edgesOf(sv))
- sv = null
- while(dangling.size()>0)
- {
- E edge = dangling.poll()
- V s = edge.getSource(); V t = edge.getTarget()
- boolean hit=false
- if(unspanned.remove(s)) hit=true
- if(unspanned.remove(t)) hit=true
- if(hit)
- {
- minimumSpanningTreeEdgeList.add(edge)
- minimumSpanningTreeTotalWeight+=edge.getWeight()
- printf("\t[Test] MST Edge=%s\n", edge)
- if(spanned.add(s))
- {
- for(E se:g.edgesOf(s))
- {
- if(!spanned.contains(se.getSource())||!spanned.contains(se.getTarget()))
- {
- dangling.add(se)
- printf("\t\tAdd Edge=%s\n", se)
- }
- }
- }
- if(spanned.add(t))
- {
- for(E se:g.edgesOf(t))
- {
- if(!spanned.contains(se.getSource())||!spanned.contains(se.getTarget()))
- {
- dangling.add(se)
- printf("\t\tAdd Edge=%s\n", se)
- }
- }
- }
- }
- }
- }
- }
- public List
getMinimumSpanningTreeEdgeList(){ return Collections.unmodifiableList(minimumSpanningTreeEdgeList)} - @Override public Set
getMinimumSpanningTreeEdgeSet() - {
- Set
set = new HashSet (); set.addAll(minimumSpanningTreeEdgeList) - return Collections.unmodifiableSet(set);
- }
- @Override public double getMinimumSpanningTreeTotalWeight()
- {
- return minimumSpanningTreeTotalWeight;
- }
- }
- printf("\t[Info] JPrim's MST:\n")
- JPrimMinimumSpanningTree pMST = new JPrimMinimumSpanningTree(g, "A")
- for(DefaultWeightedEdge e:pMST.getMinimumSpanningTreeEdgeList())
- {
- printf("\t%s (%.01f)\n", e, e.getWeight())
- }
Supplement
* [ Alg info ] Borůvka's algorithm (MST)
* [ Alg info ] Kruskal’s algorithm (MST)
* Coursera - Algorithm2 - Prim's Algorithm
* [ 資料結構 小學堂 ] 圖形結構 : 擴張樹 - 求最小成本擴張樹 (Kruskal 演算法)
* Coursera - Algorithm2 - Prim's Algorithm
* [ 資料結構 小學堂 ] 圖形結構 : 擴張樹 - 求最小成本擴張樹 (Kruskal 演算法)
This message was edited 15 times. Last update was at 07/11/2015 22:11:59
沒有留言:
張貼留言