import java.util.StringTokenizer; import java.util.Arrays; import java.io.*; public class MST{ // Arrays to keep track of info. related to each city private String[] cityName; private String[] cityState; private int[] cityLat; private int[] cityLong; private int[] cityPop; // 2-D array to keep track of pairwise distances between cities private int[][] distances; // number of cities private static int numCities; public MST(int n) { numCities = n; //Allotting the space for each 1-D array cityName = new String[numCities]; cityState = new String[numCities]; cityLat = new int[numCities]; cityLong = new int[numCities]; cityPop = new int[numCities]; // Allocate space for each 2-D array. These arrays have 0 elements in row 0, // 1 element in row 1, 2 elements in row 2, etc. distances = new int[numCities][]; for(int i = 0; i < numCities; i++) distances[i] = new int[i]; try{ // Construct a buffered reader object and connect it to the files "miles.dat" BufferedReader in = new BufferedReader(new FileReader("miles.dat")); // A counter that keeps track of the index of the current city being read int cityNumber = 0; // While-loop for reading in data from "miles.dat." At the beginning of the while-loop // the expectation is that we'll be reading a line containing the city name. Instead, // if we encounter a line that starts with "*" then we skip to the next line while(cityNumber < numCities) { // Read in a line String line = in.readLine(); // Skip the rest of the loop if line starts with a "*" if(line.charAt(0) == '*') continue; // Otherwise tokenize the line StringTokenizer tokenizedLine= new StringTokenizer(line, ",[]"); //Putting actual data into correct position in the array cityName[cityNumber] = tokenizedLine.nextToken(); cityState[cityNumber]= (tokenizedLine.nextToken()).trim(); // trim() gets rid of leading/trailing blanks cityLat[cityNumber] = Integer.parseInt(tokenizedLine.nextToken()); cityLong[cityNumber] = Integer.parseInt(tokenizedLine.nextToken()); cityPop[cityNumber] = Integer.parseInt(tokenizedLine.nextToken()); //while loop to put distances in the array; this may need to read several lines int mileNumber = 0; while (mileNumber < cityNumber) { // Read a mileage line and tokenize it String mileage = in.readLine(); StringTokenizer tokenizedMileage = new StringTokenizer(mileage, " "); // Read all the mileage data in this line into row cityNumber; increment // mileNumber after each read while(tokenizedMileage.hasMoreTokens()) { distances[cityNumber][cityNumber-mileNumber-1] = Integer.parseInt(tokenizedMileage.nextToken()); mileNumber++; } } // end of while reading distances cityNumber++; } // end of while reading cities } // end of try catch (IOException e) {System.out.println("File not found.");} } // end of TSPTester() constructor // A simple getIndex method to help test the constructor int getIndex(String city, String state) { int location; for(location = 0; location < numCities; location++) if((cityName[location].equals(city)) && (cityState[location].equals(state))) return location; return -1; } // Print information about a city, given a city index void printCityInfo(int index) { System.out.println(cityName[index] + " " + cityState[index] + " " + cityLat[index] + " " + cityLong[index] + " " + cityPop[index]); } // Print distance information between a given pair of cities void printDistanceInfo(int i, int j) { if(i < j) System.out.println(distances[j][i]); else System.out.println(distances[i][j]); } int getDistance(int i, int j) { if(i < j) return distances[j][i]; else if(j < i) return distances[i][j]; else return 0; } int[] greedyTSP() { // Find a cheapest triangle // Load triangle 0-1-2 into the the first 3 slots of the greedy array int[] greedy = new int[numCities]; int currentDistance; greedy[0] = 0; greedy[1] = 1; greedy[2] = 2; int currentBestDistance = getDistance(0, 1) + getDistance(1, 2) + getDistance(2, 0); for(int i = 0; i < numCities; i++) for(int j = 0; j < i; j++) for(int k = 0; k < j; k++) if((currentDistance = getDistance(i, j) + getDistance(j, k) + getDistance(i, k)) < currentBestDistance) { greedy[0] = i; greedy[1] = j; greedy[2] = k; currentBestDistance = currentDistance; } // Try greedily to add a city that yields the smallest increase // in the cost of the tour int partialTourSize = 3; boolean[] visited = new boolean[numCities]; for(int i = 0; i < numCities; i++) visited[i] = false; visited[greedy[0]] = true; visited[greedy[1]] = true; visited[greedy[2]] = true; // Main loop: keep repeating until partial tour covers all cities while(partialTourSize < numCities) { int smallestIncrease = Integer.MAX_VALUE; int increase = 0; int bestInsertionPoint = 0; int bestCity = 0; // Scan through all cities, stopping at unvisited cities for(int i = 0; i < numCities; i++) { if(!visited[i]) { // Consider all possible positions of inserting city i into the tour // and record the smallest increase for(int j = 0; j < partialTourSize; j++) { increase = getDistance(greedy[j], i) + getDistance(i, greedy[(j+1)%numCities]) - getDistance(greedy[j], greedy[(j+1)%numCities]); if(increase < smallestIncrease) { smallestIncrease = increase; bestCity = i; bestInsertionPoint = j; } // end of if we have found a smaller increase } // end of for-j } // end of if not visited } // end of for-i // Now we are ready to insert the bestCity at the bestInsertionPoint for(int j = partialTourSize-1; j > bestInsertionPoint; j--) greedy[j+1] = greedy[j]; greedy[bestInsertionPoint+1] = bestCity; visited[bestCity] = true; partialTourSize++; } // end-while return greedy; } void copy(int[] source, int[] dest) { for(int i = 0; i < dest.length; i++) dest[i] = source[i]; } void TSP(int[] R, int partialTourSize, boolean[] visited, int[] T) { // Base case: we have discovered a tour better than T if((partialTourSize == numCities)&&(cost(R) < cost(T))) { System.out.println("Base case. Tour cost is " + cost(R)); copy(R, T); return; } // Another base case: our partial tour is not worth completing if (cost(R, partialTourSize) >= cost(T)) return; // Recursive case: R is not complete and is currently better than T // and is therefore worth completing for(int i = 0; i < numCities; i++) { if(!visited[i]) { //System.out.println("Appending " + i); visited[i] = true; R[partialTourSize++] = i; TSP(R, partialTourSize, visited, T); partialTourSize--; visited[i] = false; //System.out.println("Deleting " + i); } } // end of for-loop } // end of TSP double cost(int[] tour) { return cost(tour, tour.length); } double cost(int[] tour, int tourSize) { double c = 0; for(int i = 0; i < tourSize-1; i++) c = c + getDistance(tour[i], tour[i+1]); c = c + getDistance(tour[tourSize-1], tour[0]); return c; } //Main method public static void main(String[] args) { int n = 15; MST T = new MST(n); // Initialize the list of vertices in the tree // Initially, no one except vertex 0 is in the tree boolean[] visited = new boolean[n]; for(int i = 0; i < n; i++) visited[i] = false; visited[0] = true; // Initialize the int[] that maintains the tree to default values // No vertices have parents set, except vertex 0 whose parent is itself int[] tree = new int[n]; for(int i = 0; i < n; i++) tree[i] = -1; tree[0] = 0; for(int i = 1; i <= n-1; i++) { long minWeight = Long.MAX_VALUE; int bestVertex = -1; int bestParent = -1; for(int j = 0; j < n; j++) { for(int k = 0; k < n; k++) { if((visited[j]) && (!visited[k])) { if(T.getDistance(j, k) < minWeight) { minWeight = T.getDistance(j, k); bestVertex = k; bestParent = j; } // end if better distance is found } // end if an edge between a visited and an unvisited is found } // end for-k } // end for-j // Update visited and tree visited[bestVertex] = true; tree[bestVertex] = bestParent; } // end for-i // Printing the MST for(int i = 1; i < n; i++) System.out.println(T.cityName[i] + " " + T.cityState[i] + ", " + T.cityName[tree[i]] + " " + T.cityState[tree[i]]); // Compting the MST cost long cost = 0; for(int i = 0; i < n; i++) cost += T.getDistance(i, tree[i]); System.out.println("The cost of the minimum spanning tree is " + cost); } // end main method } // end class