// 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