org.jgrapht.alg.PrimMinimumSpanningTree Maven / Gradle / Ivy
/* ==========================================
* JGraphT : a free Java graph-theory library
* ==========================================
*
* Project Info: http://org.org.jgrapht.sourceforge.net/
* Project Creator: Barak Naveh (http://sourceforge.net/users/barak_naveh)
*
* (C) Copyright 2003-2013, by Barak Naveh and Contributors.
*
* This program and the accompanying materials are dual-licensed under
* either
*
* (a) the terms of the GNU Lesser General Public License version 2.1
* as published by the Free Software Foundation, or (at your option) any
* later version.
*
* or (per the licensee's choosing)
*
* (b) the terms of the Eclipse Public License v1.0 as published by
* the Eclipse Foundation.
*/
/* -------------------------
* PrimMinimumSpanningTree.java
* -------------------------
*
* Original Author: Alexey Kudinkin
* Contributor(s):
*
*/
package org.jgrapht.alg;
import java.util.*;
import org.jgrapht.*;
import org.jgrapht.alg.interfaces.*;
/**
* An implementation of
* Prim's algorithm that finds a minimum spanning tree/forest subject to
* connectivity of the supplied weighted undirected graph. The algorithm was
* developed by Czech mathematician V. Jarník and later independently by
* computer scientist Robert C. Prim and rediscovered by E. Dijkstra.
*
* @author Alexey Kudinkin
* @since Mar 5, 2013
*/
public class PrimMinimumSpanningTree
implements MinimumSpanningTree
{
/**
* Minimum Spanning-Tree/Forest edge set
*/
private final Set minimumSpanningTreeEdgeSet;
/**
* Minimum Spanning-Tree/Forest edge set overall weight
*/
private final double minimumSpanningTreeTotalWeight;
public PrimMinimumSpanningTree(final Graph g)
{
this.minimumSpanningTreeEdgeSet = new HashSet(g.vertexSet().size());
Set unspanned = new HashSet(g.vertexSet());
while (!unspanned.isEmpty()) {
Iterator ri = unspanned.iterator();
V root = ri.next();
ri.remove();
// Edges crossing the cut C = (S, V \ S), where S is set of
// already spanned vertices
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));
}
});
dangling.addAll(g.edgesOf(root));
for (E next; (next = dangling.poll()) != null;) {
V s,
t =
unspanned.contains(s = g.getEdgeSource(next)) ? s
: g.getEdgeTarget(next);
// Decayed edges aren't removed from priority-queue so that
// having them just ignored being encountered through min-max
// traversal
if (!unspanned.contains(t)) {
continue;
}
this.minimumSpanningTreeEdgeSet.add(next);
unspanned.remove(t);
for (E e : g.edgesOf(t)) {
if (unspanned.contains(
g.getEdgeSource(e).equals(t) ? g.getEdgeTarget(
e)
: g.getEdgeSource(e)))
{
dangling.add(e);
}
}
}
}
double spanningTreeWeight = 0;
for (E e : minimumSpanningTreeEdgeSet) {
spanningTreeWeight += g.getEdgeWeight(e);
}
this.minimumSpanningTreeTotalWeight = spanningTreeWeight;
}
@Override public Set getMinimumSpanningTreeEdgeSet()
{
return Collections.unmodifiableSet(minimumSpanningTreeEdgeSet);
}
@Override public double getMinimumSpanningTreeTotalWeight()
{
return minimumSpanningTreeTotalWeight;
}
}
// End PrimMinimumSpanningTree.java