// Prim's algorithm without a priority queue // // Author: Rahul Simha // Date: Oct, 2001. import edu.gwu.algtest.*; import edu.gwu.util.*; import edu.gwu.debug.*; import java.util.*; import java.io.*; /** * Class Prim implements Prim's algorithm but without * the customary priority-queue for the sake of illustration. * * @see SpanningTreeAlgorithm */ public class Prim 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). boolean useMatrix; // Adjacency matrix or list? double[][] adjMatrix; // The adjacency matrix (given as input). GraphVertex[] adjList; // The adjacency list (given as input). int[] predecessor; // Store predecessors to build MST. double[] predecessorEdgeWeight; // Store edge weights as well. double[][] treeMatrix; // The MST, if required in matrix form. GraphVertex[] treeList; // The MST, if required in list form. double treeWeight; // Total weight of tree. //---------------- Algorithm interface ------------------------------------ public String getName () { return "Prim"; } public void setPropertyExtractor (int algID, PropertyExtractor props) { this.algID = algID; this.props = props; } //---------------- SpanningTreeAlgorithm interface ------------------------- public void initialize (int numVertices) { this.numVertices = numVertices; predecessor = new int [numVertices]; predecessorEdgeWeight = new double [numVertices]; } public double[][] minimumSpanningTree (double[][] adjMatrix) { // Consistency check: if (numVertices != adjMatrix.length) { System.out.println ("ERROR: adjMatrix length not equal to numVertices"); return null; } // We are using an adjacency list. useMatrix = true; // Maintain two sets: one set contains vertices in the current MST. // The other set contains those outside. Prim's algorithm always // adds an edge (the best one) between the two sets. Here, // inSet[i]=true if vertex is in the MST. boolean[] inSet = new boolean [numVertices]; // vertexKey[i] = priority of vertex i. double[] vertexKeys = new double [numVertices]; for (int i=0; i 0) ) { // We have found a neighbor: explore the edge (v,i). double w = adjMatrix[v][i]; // If the current priority is higher, lower it via edge (v,i). if (vertexKeys[i] > w) { // decreaseKey operation. vertexKeys[i] = w; // Record predecessor and weight for building MST later. predecessor[i] = v; predecessorEdgeWeight[i] = w; } } } //endfor } // endwhile // Create space for tree. treeMatrix = new double [numVertices][numVertices]; treeWeight = 0; // Now build tree using pred edges. Note: we start from "1" // since "0" is its own predecessor (the root of the tree). // ... code not shown (see in-class exercise) return treeMatrix; } public GraphVertex[] minimumSpanningTree (GraphVertex[] adjList) { // ... (not shown) ... return null; } public double getTreeWeight () { return treeWeight; } }