Java Program to Solve TSP using Minimum Spanning Trees

This is a java program to solve TSP using MST.

Here is the source code of the Java Program to Solve TSP Using Minimum Spanning Trees. The Java program is successfully compiled and run on a Windows system. The program output is also shown below.

  1.  
  2. package com.sanfoundry.hardgraph;
  3.  
  4. import java.io.BufferedReader;
  5. import java.io.FileReader;
  6. import java.io.IOException;
  7. import java.util.StringTokenizer;
  8.  
  9. public class TSPUsingMST
  10. {
  11.     // Arrays to keep track of info. related to each city
  12.     private String[]   cityName;
  13.     private String[]   cityState;
  14.     private int[]      cityLat;
  15.     private int[]      cityLong;
  16.     private int[]      cityPop;
  17.     // 2-D array to keep track of pairwise distances between cities
  18.     private int[][]    distances;
  19.     // number of cities
  20.     private static int numCities;
  21.  
  22.     public TSPUsingMST(int n)
  23.     {
  24.         numCities = n;
  25.         // Allotting the space for each 1-D array
  26.         cityName = new String[numCities];
  27.         cityState = new String[numCities];
  28.         cityLat = new int[numCities];
  29.         cityLong = new int[numCities];
  30.         cityPop = new int[numCities];
  31.         // Allocate space for each 2-D array. These arrays have 0 elements in
  32.         // row 0,
  33.         // 1 element in row 1, 2 elements in row 2, etc.
  34.         distances = new int[numCities][];
  35.         for (int i = 0; i < numCities; i++)
  36.             distances[i] = new int[i];
  37.         try
  38.         {
  39.             // Construct a buffered reader object and connect it to the files
  40.             // "miles.dat"
  41.             BufferedReader in = new BufferedReader(new FileReader("miles.dat"));
  42.             // A counter that keeps track of the index of the current city being
  43.             // read
  44.             int cityNumber = 0;
  45.             // While-loop for reading in data from "miles.dat." At the beginning
  46.             // of the while-loop
  47.             // the expectation is that we'll be reading a line containing the
  48.             // city name. Instead,
  49.             // if we encounter a line that starts with "*" then we skip to the
  50.             // next line
  51.             while (cityNumber < numCities)
  52.             {
  53.                 // Read in a line
  54.                 String line = in.readLine();
  55.                 // Skip the rest of the loop if line starts with a "*"
  56.                 if (line.charAt(0) == '*')
  57.                     continue;
  58.                 // Otherwise tokenize the line
  59.                 StringTokenizer tokenizedLine = new StringTokenizer(line, ",[]");
  60.                 // Putting actual data into correct position in the array
  61.                 cityName[cityNumber] = tokenizedLine.nextToken();
  62.                 cityState[cityNumber] = (tokenizedLine.nextToken()).trim(); // trim()
  63.                                                                             // gets
  64.                                                                             // rid
  65.                                                                             // of
  66.                                                                             // leading/trailing
  67.                                                                             // blanks
  68.                 cityLat[cityNumber] = Integer.parseInt(tokenizedLine
  69.                         .nextToken());
  70.                 cityLong[cityNumber] = Integer.parseInt(tokenizedLine
  71.                         .nextToken());
  72.                 cityPop[cityNumber] = Integer.parseInt(tokenizedLine
  73.                         .nextToken());
  74.                 // while loop to put distances in the array; this may need to
  75.                 // read several lines
  76.                 int mileNumber = 0;
  77.                 while (mileNumber < cityNumber)
  78.                 {
  79.                     // Read a mileage line and tokenize it
  80.                     String mileage = in.readLine();
  81.                     StringTokenizer tokenizedMileage = new StringTokenizer(
  82.                             mileage, " ");
  83.                     // Read all the mileage data in this line into row
  84.                     // cityNumber; increment
  85.                     // mileNumber after each read
  86.                     while (tokenizedMileage.hasMoreTokens())
  87.                     {
  88.                         distances[cityNumber][cityNumber - mileNumber - 1] = Integer
  89.                                 .parseInt(tokenizedMileage.nextToken());
  90.                         mileNumber++;
  91.                     }
  92.                 } // end of while reading distances
  93.                 cityNumber++;
  94.             } // end of while reading cities
  95.             in.close();
  96.         } // end of try
  97.         catch (IOException e)
  98.         {
  99.             System.out.println("File not found.");
  100.         }
  101.     } // end of TSPTester() constructor
  102.  
  103.     // A simple getIndex method to help test the constructor
  104.     int getIndex(String city, String state)
  105.     {
  106.         int location;
  107.         for (location = 0; location < numCities; location++)
  108.             if ((cityName[location].equals(city))
  109.                     && (cityState[location].equals(state)))
  110.                 return location;
  111.         return -1;
  112.     }
  113.  
  114.     // Print information about a city, given a city index
  115.     void printCityInfo(int index)
  116.     {
  117.         System.out
  118.                 .println(cityName[index] + " " + cityState[index] + " "
  119.                         + cityLat[index] + " " + cityLong[index] + " "
  120.                         + cityPop[index]);
  121.     }
  122.  
  123.     // Print distance information between a given pair of cities
  124.     void printDistanceInfo(int i, int j)
  125.     {
  126.         if (i < j)
  127.             System.out.println(distances[j][i]);
  128.         else
  129.             System.out.println(distances[i][j]);
  130.     }
  131.  
  132.     int getDistance(int i, int j)
  133.     {
  134.         if (i < j)
  135.             return distances[j][i];
  136.         else if (j < i)
  137.             return distances[i][j];
  138.         else
  139.             return 0;
  140.     }
  141.  
  142.     int[] greedyTSP()
  143.     {
  144.         // Find a cheapest triangle
  145.         // Load triangle 0-1-2 into the the first 3 slots of the greedy array
  146.         int[] greedy = new int[numCities];
  147.         int currentDistance;
  148.         greedy[0] = 0;
  149.         greedy[1] = 1;
  150.         greedy[2] = 2;
  151.         int currentBestDistance = getDistance(0, 1) + getDistance(1, 2)
  152.                 + getDistance(2, 0);
  153.         for (int i = 0; i < numCities; i++)
  154.             for (int j = 0; j < i; j++)
  155.                 for (int k = 0; k < j; k++)
  156.                     if ((currentDistance = getDistance(i, j)
  157.                             + getDistance(j, k) + getDistance(i, k)) < currentBestDistance)
  158.                     {
  159.                         greedy[0] = i;
  160.                         greedy[1] = j;
  161.                         greedy[2] = k;
  162.                         currentBestDistance = currentDistance;
  163.                     }
  164.         // Try greedily to add a city that yields the smallest increase
  165.         // in the cost of the tour
  166.         int partialTourSize = 3;
  167.         boolean[] visited = new boolean[numCities];
  168.         for (int i = 0; i < numCities; i++)
  169.             visited[i] = false;
  170.         visited[greedy[0]] = true;
  171.         visited[greedy[1]] = true;
  172.         visited[greedy[2]] = true;
  173.         // Main loop: keep repeating until partial tour covers all cities
  174.         while (partialTourSize < numCities)
  175.         {
  176.             int smallestIncrease = Integer.MAX_VALUE;
  177.             int increase = 0;
  178.             int bestInsertionPoint = 0;
  179.             int bestCity = 0;
  180.             // Scan through all cities, stopping at unvisited cities
  181.             for (int i = 0; i < numCities; i++)
  182.             {
  183.                 if (!visited[i])
  184.                 {
  185.                     // Consider all possible positions of inserting city i into
  186.                     // the tour
  187.                     // and record the smallest increase
  188.                     for (int j = 0; j < partialTourSize; j++)
  189.                     {
  190.                         increase = getDistance(greedy[j], i)
  191.                                 + getDistance(i, greedy[(j + 1) % numCities])
  192.                                 - getDistance(greedy[j], greedy[(j + 1)
  193.                                         % numCities]);
  194.                         if (increase < smallestIncrease)
  195.                         {
  196.                             smallestIncrease = increase;
  197.                             bestCity = i;
  198.                             bestInsertionPoint = j;
  199.                         } // end of if we have found a smaller increase
  200.                     } // end of for-j
  201.                 } // end of if not visited
  202.             } // end of for-i
  203.               // Now we are ready to insert the bestCity at the bestInsertionPoint
  204.             for (int j = partialTourSize - 1; j > bestInsertionPoint; j--)
  205.                 greedy[j + 1] = greedy[j];
  206.             greedy[bestInsertionPoint + 1] = bestCity;
  207.             visited[bestCity] = true;
  208.             partialTourSize++;
  209.         } // end-while
  210.         return greedy;
  211.     }
  212.  
  213.     void copy(int[] source, int[] dest)
  214.     {
  215.         for (int i = 0; i < dest.length; i++)
  216.             dest[i] = source[i];
  217.     }
  218.  
  219.     void TSP(int[] R, int partialTourSize, boolean[] visited, int[] T)
  220.     {
  221.         // Base case: we have discovered a tour better than T
  222.         if ((partialTourSize == numCities) && (cost(R) < cost(T)))
  223.         {
  224.             System.out.println("Base case. Tour cost is " + cost(R));
  225.             copy(R, T);
  226.             return;
  227.         }
  228.         // Another base case: our partial tour is not worth completing
  229.         if (cost(R, partialTourSize) >= cost(T))
  230.             return;
  231.         // Recursive case: R is not complete and is currently better than T
  232.         // and is therefore worth completing
  233.         for (int i = 0; i < numCities; i++)
  234.         {
  235.             if (!visited[i])
  236.             {
  237.                 // System.out.println("Appending " + i);
  238.                 visited[i] = true;
  239.                 R[partialTourSize++] = i;
  240.                 TSP(R, partialTourSize, visited, T);
  241.                 partialTourSize--;
  242.                 visited[i] = false;
  243.                 // System.out.println("Deleting " + i);
  244.             }
  245.         } // end of for-loop
  246.     } // end of TSP
  247.  
  248.     double cost(int[] tour)
  249.     {
  250.         return cost(tour, tour.length);
  251.     }
  252.  
  253.     double cost(int[] tour, int tourSize)
  254.     {
  255.         double c = 0;
  256.         for (int i = 0; i < tourSize - 1; i++)
  257.             c = c + getDistance(tour[i], tour[i + 1]);
  258.         c = c + getDistance(tour[tourSize - 1], tour[0]);
  259.         return c;
  260.     }
  261.  
  262.     // Main method
  263.     public static void main(String[] args)
  264.     {
  265.         int n = 15;
  266.         TSPUsingMST T = new TSPUsingMST(n);
  267.         // Initialize the list of vertices in the tree
  268.         // Initially, no one except vertex 0 is in the tree
  269.         boolean[] visited = new boolean[n];
  270.         for (int i = 0; i < n; i++)
  271.             visited[i] = false;
  272.         visited[0] = true;
  273.         // Initialize the int[] that maintains the tree to default values
  274.         // No vertices have parents set, except vertex 0 whose parent is itself
  275.         int[] tree = new int[n];
  276.         for (int i = 0; i < n; i++)
  277.             tree[i] = -1;
  278.         tree[0] = 0;
  279.         for (int i = 1; i <= n - 1; i++)
  280.         {
  281.             long minWeight = Long.MAX_VALUE;
  282.             int bestVertex = -1;
  283.             int bestParent = -1;
  284.             for (int j = 0; j < n; j++)
  285.             {
  286.                 for (int k = 0; k < n; k++)
  287.                 {
  288.                     if ((visited[j]) && (!visited[k]))
  289.                     {
  290.                         if (T.getDistance(j, k) < minWeight)
  291.                         {
  292.                             minWeight = T.getDistance(j, k);
  293.                             bestVertex = k;
  294.                             bestParent = j;
  295.                         } // end if better distance is found
  296.                     } // end if an edge between a visited and an unvisited is
  297.                       // found
  298.                 } // end for-k
  299.             } // end for-j
  300.               // Update visited and tree
  301.             visited[bestVertex] = true;
  302.             tree[bestVertex] = bestParent;
  303.         } // end for-i
  304.           // Printing the MST
  305.         for (int i = 1; i < n; i++)
  306.             System.out.println(T.cityName[i] + " " + T.cityState[i] + ", "
  307.                     + T.cityName[tree[i]] + " " + T.cityState[tree[i]]);
  308.         // Compting the MST cost
  309.         long cost = 0;
  310.         for (int i = 0; i < n; i++)
  311.             cost += T.getDistance(i, tree[i]);
  312.         System.out.println("The cost of the minimum spanning tree is " + cost);
  313.     } // end main method
  314. } // end class

Output:

$ javac TSPUsingMST.java
$ java TSPUsingMST
 
Yankton SD, Wisconsin Dells WI
Yakima WA, Williston ND
Worcester MA, Wilmington DE
Wisconsin Dells WI, Youngstown OH
Winston-Salem NC, Winchester VA
Winnipeg MB, Yankton SD
Winchester VA, Wilmington DE
Wilmington NC, Winston-Salem NC
Wilmington DE, Williamsport PA
Williston ND, Winnipeg MB
Williamsport PA, Youngstown OH
Williamson WV, Winston-Salem NC
Wichita Falls TX, Wichita KS
Wichita KS, Yankton SD
The cost of the minimum spanning tree is 5461

Sanfoundry Global Education & Learning Series – 1000 Java Programs.

advertisement
advertisement

Here’s the list of Best Books in Java Programming, Data Structures and Algorithms.

If you find any mistake above, kindly email to [email protected]

advertisement
advertisement
Subscribe to our Newsletters (Subject-wise). Participate in the Sanfoundry Certification contest to get free Certificate of Merit. Join our social networks below and stay updated with latest contests, videos, internships and jobs!

Youtube | Telegram | LinkedIn | Instagram | Facebook | Twitter | Pinterest
Manish Bhojasia - Founder & CTO at Sanfoundry
Manish Bhojasia, a technology veteran with 20+ years @ Cisco & Wipro, is Founder and CTO at Sanfoundry. He lives in Bangalore, and focuses on development of Linux Kernel, SAN Technologies, Advanced C, Data Structures & Alogrithms. Stay connected with him at LinkedIn.

Subscribe to his free Masterclasses at Youtube & discussions at Telegram SanfoundryClasses.