Advertisement
Guest User

Untitled

a guest
May 6th, 2015
254
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 18.69 KB | None | 0 0
  1. import java.util.*;
  2.  
  3. public class TSP {
  4.     static int radius = 6371;
  5.     public static void main(String[] args) {
  6.         long start = System.nanoTime();
  7.         FileIO reader = new FileIO();
  8.         String[] inputs = reader.load("E:\\TSP/Towns.txt");
  9.  
  10.         int inputsRows = inputs.length;
  11.         int inputsColumns = inputs[0].trim().split(",").length;
  12.         int TownRows = inputs.length;
  13.         int TownColumns = inputsColumns - 2;
  14.         double[][] coords = new double[inputsRows][inputsColumns - 2];
  15.         String[][] Towns = new String[TownRows][TownColumns];
  16.         // populating Town string with town numbers and names.
  17.         for(int i = 0; i < inputsRows; i++) {
  18.             String[] tokens = inputs[i].trim().split(",");
  19.             for(int j = 0; j < tokens.length - 2; j++) {
  20.                 Towns[i][j] = (tokens[j]);
  21.             }
  22.         }
  23.  
  24.         // //populating Coords string with the necessary information
  25.         for(int i = 0; i < TownRows; i++) {
  26.             String[] tokens = inputs[i].trim().split(",");
  27.             for(int j = 2; j < tokens.length; j++) {
  28.                 coords[i][j - 2] = Double.parseDouble(tokens[j]);
  29.             }
  30.             // System.out.println();
  31.         }
  32.  
  33.         double[][] distances = new double[inputs.length][inputs.length];
  34.         // setting a default value to the array
  35.         // getting the distances from each town to all other towns
  36.         double bestshort=Double.MAX_VALUE;
  37.         String shortestpath="";
  38.  
  39.         //         for(int here=0;here<1000;here++){
  40.         //              if((999-here)%100==0){
  41.         //                 System.out.println((999-here)+" runs left!");
  42.         //              }
  43.         for(int i = 0; i < inputs.length; i++) {
  44.             for(int j = 0; j < inputs.length; j++) {
  45.                 if(distances[i][j] == 0) {
  46.                     distances[i][j] = haversin(coords[i][0], coords[j][0], coords[i][1], coords[j][1]);
  47.                     distances[j][i] = (distances[i][j]);
  48.                 }
  49.             }
  50.         }
  51.  
  52.         int timessimulated = inputs.length;
  53.         String PathShort = "";
  54.         // setting a big variable that there will definitely be shorter le   ngths then
  55.         double travelledshort = Double.MAX_VALUE;
  56.         double[][] dcopy = new double[distances.length][distances[0].length];
  57.         int startingpoint = 0;        
  58.         // keep check of the town we are on
  59.         int TownOn = startingpoint;
  60.         for(int u = 0; u < timessimulated; u++) {
  61.             // starts at 0 by default on the first run through of the code, on the second it starts at the town in slot 1
  62.             // on the 3 its the town at slot 2 etc...
  63.             // records the shortest distance found to the next location, ie from town 1 to town 40 is shortest,
  64.             // so go to town 40
  65.             String Path = (u+1)+".";
  66.             startingpoint = u;
  67.             double shortest = 0;
  68.             // refilling the array as after each iteration of the code it is an array full of 0's
  69.             // as i use 0's to mark where i have been and where not to return to.
  70.             for(int a = 0; a < inputs.length; a++) {
  71.                 for(int s = 0; s < inputs.length; s++) {
  72.                     dcopy[a][s] = distances[a][s];
  73.                 }
  74.             }
  75.  
  76.             // the travelled variable does the same as travelledshort, however it is constantly updated
  77.             // every iteration with the total distance, whereas travelledshort is only updated when a shorter distance is found
  78.             double travelled = 0;
  79.             // looping through the amount of co-ordiantes given to find the shortest route.
  80.             for(int j = 0; j < inputs.length-1; j++) {
  81.                 // finds where to go to next(nearest neighbour)
  82.                 shortest=Double.MAX_VALUE;
  83.                 // looks for a shorter value then the one obtained, but omits 0 distances.
  84.                 for(int i = 0; i < dcopy.length; i++) {
  85.                     if((dcopy[startingpoint][i] < shortest) && (dcopy[startingpoint][i] > 0)) {
  86.                         shortest = dcopy[startingpoint][i];
  87.                         // updates what town we are going to.
  88.                         TownOn = i;
  89.                     }
  90.                 }
  91.  
  92.                 // setting all value leading to the current spot as 0, to prevent us coming back.
  93.                 for(int k = 0; k < dcopy.length; k++) {
  94.                     dcopy[startingpoint][k] = 0;
  95.                     dcopy[k][startingpoint] = 0;
  96.                     // dcopy[TownOn][startingpoint]=shortest;
  97.                 }
  98.  
  99.                 // adding the shortest town to the string
  100.                 Path += (TownOn + 1) + ".";
  101.  
  102.                 // sets new starting point
  103.                 startingpoint = TownOn;
  104.                 // adding the distance to our new location to the current distance travelled.
  105.                 travelled += shortest;
  106.  
  107.             }
  108.             //System.out.println(Path);
  109.             // omitting unecessary values that somehow creeped in to the path.
  110.             if(travelled < travelledshort) {
  111.                 // if the travelled path in this iteration is the shortest path then it is updated to path short.
  112.                 PathShort = Path;
  113.                 travelledshort=travelled;
  114.             }
  115.             //System.out.println(u);
  116.         }
  117.         //NEAREST NEIGHBOUR SOLUTION
  118.         //System.out.println(PathShort);
  119.         // time to implement 2-opt!
  120.         System.out.println("Done with the nearest neighbour solution.");
  121.         System.out.println("Excessively 2opting this solution, this will take a while.");
  122.         System.out.println(PathShort);
  123.         String [] split=PathShort.split("\\.");
  124.         String[] array4 = split;
  125.         // what will be the final output
  126.         String[] output =split;
  127.  
  128.         // filling array with the towns
  129.  
  130.         boolean isshorter=true;
  131.         int fill=0;
  132.         int iterations=0;
  133.         // moved all previous code to the Swapper method so i can call it on any part of the string
  134.         while(isshorter){
  135.  
  136.             double tempcheck=0;
  137.             double distanceofswapped=0;
  138.             String temp=new String(Swapper(output,2,distances));
  139.             String [] temp2=new String[output.length];
  140.  
  141.             //System.out.println(temp);
  142.  
  143.             temp2=temp.split("\\.");
  144.             fill=0;
  145.             while(fill<output.length-1){
  146.                 //sums the path length from the start position to a certain size
  147.                 distanceofswapped+=distances[(Integer.parseInt(output[fill]))-1][(Integer.parseInt(output[fill+1]))-1];
  148.                 tempcheck+=distances[(Integer.parseInt(temp2[fill]))-1][(Integer.parseInt(temp2[fill+1]))-1];
  149.                 fill++;
  150.             }
  151.             if((tempcheck<distanceofswapped)&&(tempcheck>0)){
  152.                 for(int y=0;y<array4.length;y++){
  153.                     output[y]=temp2[y];
  154.                 }
  155.                 distanceofswapped=tempcheck;              
  156.             }
  157.             else{
  158.                 isshorter=false;
  159.             }
  160.             if( iterations%10==0){
  161.                 System.out.println("shortest so far");
  162.                 for(int a=0;a<output.length;a++){
  163.                     System.out.print(output[a]+".");
  164.                 }
  165.  
  166.             }
  167.             else if(iterations==100){isshorter=false;}
  168.             iterations++;
  169.         }
  170.         System.out.println("Done with excessively 2 opting the nearest neighbour solution.");
  171.         System.out.println("It took: "+(System.nanoTime() - start) / 1000000 + "ms");
  172.         System.out.println("Excessively 2opting the inverse this solution, this will also take a while. \n");
  173.         String [] outputinverted=new String[output.length];
  174.         String  outputinverted1="";
  175.         for(int y=0;y<array4.length;y++){
  176.             outputinverted[y]=output[array4.length-1-y];
  177.         }
  178.         iterations=0;
  179.         while(isshorter){
  180.             double tempcheck=0;
  181.             double distanceofswapped=0;
  182.             String temp=new String(Swapper(outputinverted,2,distances));
  183.             String [] temp2=new String[output.length];
  184.  
  185.             //System.out.println(temp);
  186.  
  187.             for(int y=0;y<temp2.length;y++){
  188.                 temp2[y]=(temp.split("\\.")[y]);
  189.  
  190.                 //                 System.out.println();
  191.             }
  192.             fill=0;
  193.             while(fill<output.length-1){
  194.                 //sums the path length from the start position to a certain size
  195.                 distanceofswapped+=distances[(Integer.parseInt(outputinverted[fill]))-1][(Integer.parseInt(outputinverted[fill+1]))-1];
  196.                 tempcheck+=distances[(Integer.parseInt(temp2[fill]))-1][(Integer.parseInt(temp2[fill+1]))-1];
  197.                 fill++;
  198.             }
  199.             if((tempcheck<distanceofswapped)&&(tempcheck>0)){
  200.                 for(int y=0;y<array4.length;y++){
  201.                     outputinverted[y]=temp2[y];
  202.                 }
  203.                 distanceofswapped=tempcheck;              
  204.             }
  205.             else{
  206.                 isshorter=false;
  207.             }
  208.             if( iterations%10==0){
  209.                 System.out.println("shortest so far");
  210.                 for(int a=0;a<output.length;a++){
  211.                     System.out.print(outputinverted[a]+".");
  212.                 }
  213.             }
  214.             else if(iterations==100){isshorter=false;}
  215.             iterations++;
  216.         }
  217.  
  218.         System.out.println("Done with excessively 2 opting inverted 2opted solution.");
  219.         System.out.print("It took: "+(System.nanoTime() - start) / 1000000 + "ms \n");
  220.         for(int a=0;a<array4.length;a++){
  221.             System.out.print(output[a]+".");
  222.  
  223.         }
  224.         System.out.println();
  225.  
  226.         //             outputinverted1=(Swapper(outputinverted,2,distances));
  227.         //             for(int y=0;y<array4.length;y++){
  228.         //                 outputinverted[y]=(outputinverted1.split("\\.")[y]);
  229.         //             }
  230.         //last step, checking if the inverse of the route is better!
  231.         int normaldist=0;
  232.         int invertdist=0;
  233.         fill=0;
  234.         while(fill<output.length-1){
  235.             //sums the path length from the start position to a certain size
  236.             normaldist+=distances[(Integer.parseInt(output[fill]))-1][(Integer.parseInt(output[fill+1]))-1];
  237.             fill++;
  238.         }
  239.         fill=0;
  240.         while(fill<output.length-1){
  241.             //sums the path length from the start position to a certain size
  242.             invertdist+=distances[(Integer.parseInt(outputinverted[fill]))-1][(Integer.parseInt(outputinverted[fill+1]))-1];
  243.             fill++;
  244.         }
  245.         //System.out.println(normaldist+"     "+invertdist);
  246.         if(normaldist<invertdist){
  247.             if(normaldist<bestshort){
  248.                 bestshort=normaldist;
  249.                 shortestpath="";
  250.                 for(int a=0;a<array4.length;a++){
  251.                     shortestpath+=(output[a]+".");
  252.  
  253.                 }
  254.  
  255.             }
  256.             //                 for(int a=0;a<array4.length;a++){
  257.             //                     System.out.print(output[a]+".");
  258.             //
  259.             //                 }
  260.             // System.out.println("\n"+"Normal");
  261.         }
  262.         else{
  263.             if(invertdist<bestshort){
  264.                 bestshort=invertdist;
  265.                 shortestpath="";
  266.                 for(int a=0;a<array4.length;a++){
  267.                     shortestpath+=(outputinverted[a]+".");
  268.  
  269.                 }
  270.  
  271.             }
  272.             //                 for(int a=0;a<array4.length;a++){
  273.             //                     System.out.print(outputinverted[a]+".");
  274.             //
  275.             //                 }
  276.         }
  277.         //         System.out.println("\n" + "Normal");
  278.         //         System.out.println();
  279.         //         } //THIS ONE FOR THE FOR LOOP
  280.         System.out.println("Shortest solution.");
  281.         System.out.println(shortestpath);
  282.         System.out.println("\n"+(System.nanoTime() - start) / 1000000 + "ms");
  283.     }
  284.  
  285.     public static double haversin(double latitude1, double latitude2, double longitude1, double longitude2) {
  286.         double la1 = Math.toRadians(latitude1);
  287.         double la2 = Math.toRadians(latitude2);
  288.         double lo1 = Math.toRadians(longitude1);
  289.         double lo2 = Math.toRadians(longitude2);
  290.         return (2 * radius)
  291.         * Math.asin(Math.sqrt((Math.sin((la1 - la2) / 2) * Math.sin((la1 - la2) / 2) + (Math.cos(la1) * Math.cos(la2))
  292.                     * (Math.sin((lo1 - lo2) / 2) * Math.sin((lo1 - lo2) / 2)))));
  293.     }
  294.  
  295.     public static String Swapper(String[] array, int chunksof, double[][] distances) {
  296.         String output="";  
  297.         String [] bestarray=new String[array.length];
  298.         String [] arrayswapped=new String [array.length];
  299.         String [] arraycopy=new String[array.length];
  300.         String []output1=new String[array.length];
  301.         Arrays.fill(output1,"-1");
  302.  
  303.         for(int a = 0; a < array.length; a++) {
  304.             arrayswapped[a]=array[a];
  305.             bestarray[a]=array[a];
  306.             arraycopy[a]=array[a];
  307.             output+=arrayswapped[a]+".";
  308.         }
  309.         while(chunksof<array.length){
  310.             for(int a = 0; a < array.length; a++) {
  311.                 arrayswapped[a]=array[a];
  312.                 arraycopy[a]=array[a];
  313.             }
  314.             int lastswap=0;
  315.             int swap=0;
  316.             int start=0;
  317.             int end=0;
  318.             while(start<array.length-chunksof){
  319.  
  320.                 swap=0;
  321.                 end=start+chunksof;
  322.                 double path1=0;
  323.                 double path2=0;
  324.                 int position;
  325.                 if(start==0){position=0;}
  326.                 else{position=start-1;}
  327.                 for(int a=0;a<arrayswapped.length;a++){
  328.                     arrayswapped[a]=array[a];
  329.                     //                     System.out.print(arrayswapped[a]+".");
  330.                 }
  331.                 while(swap<chunksof/2){
  332.                     String [] temp=new String[1];
  333.                     temp[0]=arrayswapped[start+1+swap];
  334.                     arrayswapped[start+1+swap]=arrayswapped[end-swap];
  335.                     arrayswapped[end-swap]=temp[0];
  336.                     swap++;
  337.                 }
  338.  
  339.                
  340.                 while(position<array.length-1){
  341.                     path1+=distances[Integer.parseInt(bestarray[position])-1][Integer.parseInt(bestarray[position+1])-1];
  342.                     path2+=distances[Integer.parseInt(arrayswapped[position])-1][Integer.parseInt(arrayswapped[position+1])-1];
  343.                     position++;
  344.                 }
  345.                 //                 System.out.println((start+1)+"   "+(end));
  346.                 //                      System.out.println(path1+"   "+path2);
  347.                 //                 System.out.println(Arrays.toString(arrayswapped));
  348.                 //                 System.out.println(Arrays.toString(bestarray));
  349.  
  350.                 if(path2<path1){
  351.  
  352.                     // System.out.println(path1+"=path1     ,path2="+path2);
  353.                     //                      System.out.println("before");
  354.                     //                      System.out.println();
  355.                     output="";
  356.                     //System.out.println("Swappedarray=");
  357.                     for(int copy=0;copy<array.length;copy++){
  358.                         //System.out.print(arrayswapped[copy]+".");
  359.                         bestarray[copy]=arrayswapped[copy];
  360.                         output+= bestarray[copy]+".";
  361.                     }
  362.                     for(int copy=start+1;copy<array.length;copy++){
  363.                         //System.out.print(arrayswapped[copy]+".");
  364.                         output1[copy]=arrayswapped[copy];
  365.                     }
  366.                     //                      System.out.println("after");
  367.                 }
  368.  
  369.                 start++;
  370.             }
  371.             if(start-array.length+chunksof>1){
  372.                 int newend=array.length-1;
  373.                 lastswap=(array.length)-start;
  374.                 int lastchunks=(lastswap-1)/2;
  375.                 swap=0;
  376.                 for(int a=0;a<arrayswapped.length;a++){
  377.                     arrayswapped[a]=array[a];
  378.                     //                     System.out.print(arrayswapped[a]+".");
  379.                 }
  380.                 while(swap<lastchunks){
  381.                     String [] temp=new String[1];
  382.                     temp[0]=arrayswapped[start+1+swap];
  383.                     arrayswapped[start+1+swap]=arrayswapped[newend-swap];
  384.                     arrayswapped[newend-swap]=temp[0];
  385.                     swap++;
  386.                 }
  387.  
  388.                 double path1=0;
  389.                 double path2=0;
  390.                 int position;
  391.                 if(start==0){position=0;}
  392.                 else{position=start-1;}
  393.  
  394.                 while(position<array.length-1){
  395.                     path1+=distances[Integer.parseInt(array[position])-1][Integer.parseInt(array[position+1])-1];
  396.                     path2+=distances[Integer.parseInt(arrayswapped[position])-1][Integer.parseInt(arrayswapped[position+1])-1];
  397.                     position++;
  398.                 }
  399.                 //                 System.out.println((start+1)+"   "+(newend));
  400.                 //                    System.out.println(path1+"   "+path2);
  401.                 //                 System.out.println(Arrays.toString(bestarray));
  402.                 if(path2<path1){
  403.                     //                     System.out.println("yup");
  404.                     output="";
  405.                     //System.out.println("Swappedarray=");
  406.                     for(int copy=0;copy<array.length;copy++){
  407.                         //System.out.print(arrayswapped[copy]+".");
  408.                         bestarray[copy]=arrayswapped[copy];
  409.                         output+= bestarray[copy]+".";
  410.                     }
  411.                     for(int copy=start+1;copy<array.length;copy++){
  412.                         //System.out.print(arrayswapped[copy]+".");
  413.                         output1[copy]=arrayswapped[copy];
  414.                     }
  415.  
  416.                 }
  417.             }
  418.  
  419.             chunksof+=2;
  420.         }
  421.         int check=0;
  422.         int check1=0;
  423.         for(int copy=0;copy<array.length;copy++){
  424.             if(output1[copy]=="-1"){
  425.                 output1[copy]=array[copy];
  426.             }
  427.         }
  428.         for(int copy=0;copy<array.length-1;copy++){
  429.             check+=distances[Integer.parseInt(output1[copy])-1][Integer.parseInt(output1[copy+1])-1];
  430.             check1+=distances[Integer.parseInt(bestarray[copy])-1][Integer.parseInt(bestarray[copy+1])-1];
  431.         }
  432.         if(check<check1){
  433.             for(int copy=0;copy<array.length;copy++){
  434.                 output+=output1[copy];
  435.             }
  436.         }
  437.  
  438.         return output;
  439.     }
  440. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement