// Kruskal's algorithm using union-find.
//
// Author: Rahul Simha
// Date: Oct, 2001.
import edu.gwu.algtest.*;
import edu.gwu.util.*;
import edu.gwu.debug.*;
import java.util.*;
import java.io.*;
/**
* We're going to use Java's sorting utility to sort edges.
* In particular, we will use java.util.TreeSet to store edges
* in sorted order. To get a TreeSet to sort, we need to
* either make edges implement Comparable, or provide a comparator.
* We use the latter option, because we may want to leave edge-comparisons
* inside the GraphEdge class for other purposes.
* Note: TreeSet uses a balanced tree and so the
* operations should take at most O(log n) time.
* Describe class EdgeComparator
here.
*
* @see Comparator
*/
class EdgeComparator implements Comparator {
public int compare (Object obj1, Object obj2)
{
// A lower-weighted edge has precedence.
if ( ((GraphEdge)obj1).weight < ((GraphEdge)obj2).weight )
return -1;
else
return 1;
// NOTE: We cannot return 0 because the TreeSet will think it's a
// duplicate and get rid of it. Since equally-weighted edges
// can be processed in any order, return 1.
}
public boolean equals (Object obj)
{
// We don't need this for the sorted list.
return false;
}
}
/**
* Class Kruskal
implements Kruskal's minimum spanning tree
* algorithm. It implements the methods in the SpanningTreeAlgorithm
* interface to enable testing with the test-environment.
*
* @author "Rahul Simha"
* @see SpanningTreeAlgorithm
*/
public class Kruskal implements SpanningTreeAlgorithm {
// Debugging for internal use.
private static final boolean debug = true;
int algID; // Given by test-environment.
PropertyExtractor props; // Properties file.
int numVertices; // Number of vertices (when initialized).
double[][] adjMatrix; // The adjacency matrix (given as input).
GraphVertex[] adjList; // The adjacency list (given as input).
double[][] treeMatrix; // The MST, if required in matrix form.
GraphVertex[] treeList; // The MST, if required in list form.
double treeWeight; // Store the computed tree weight here.
//---------------- Algorithm interface ------------------------------------
public String getName ()
{
return "Kruskal";
}
public void setPropertyExtractor (int algID, PropertyExtractor props)
{
this.algID = algID;
this.props = props;
}
//---------------- SpanningTreeAlgorithm interface -------------------------
public void initialize (int numVertices)
{
this.numVertices = numVertices;
}
// Adjacency matrix version. Return value is tree in matrix form.
// Assumption: graph is undirected.
public double[][] minimumSpanningTree (double[][] adjMatrix)
{
// Check consistency.
if (numVertices != adjMatrix.length) {
System.out.println ("ERROR: adjMatrix length not equal to numVertices");
return null;
}
// Union-find sets: UnionFindInt is an implementation of union-find
// for integer values.
UnionFindInt unionFind = new UnionFindInt ();
unionFind.initialize (numVertices);
// Build the singleton sets.
for (int i=0; i 0) {
// GraphEdge stores the endpoints and weight of an edge.
GraphEdge edge = new GraphEdge (i, j, adjMatrix[i][j]);
// Put the edge in our TreeSet.
sortedEdgeSet.add (edge);
}
}
} // endfor
// Get a matrix ready to hold the MST.
treeMatrix = new double [numVertices][];
for (int i=0; i