0

just having some issues with the distance calculation in a Traveling Salesman optimized nearest neighbor solution I have been working on in the past week or so in my free time. Basically, what is happening is when I get my result printed, the "total" it calculates (encompassing the total distance traveled over the trip) is returned incorrectly compared to the solution given in a functioning checker applet. However, it isn't returning incorrectly in any immediately obvious way. It is always within about +/- 300km of the answer. Sometimes is is a larger result than it should be, sometimes it is lower. I have tried hard coding the final step to loop back to the first town, which is in the current iteration of the code, and it made things closer, but with the same behaviour occurring.

Here is a rundown of the issue and what I have done: - I have an input file, which contains 160 lines, with each pair of lines being the latitude and longitude of a random town in Ireland, for 80 town - This input file is then used in the creation of an identity matrix of size [80][80] using a haversine function in the main method where each element is the distance from town i to j. You can assume that this part is correctly calculated. - The haversine class takes the radius of the earth to be 6378.1km and calculates distances correctly as tested in other problems. - This identity matrix is then passed into the TSP method for calculation.

Here is the source code that is causing issues, I am sure it is happening somewhere in here and not in my main method or haversine, I just cannot pin point it:

//Main calculation method that takes in the adjacency matrix
    public void tsp(double[][] adjacency_matrix)
    {
        int last = 0;
        int count = 0;

        //Array that will store if a town has been previously visited, first town will be visited from the start
        boolean[] visited = new boolean[numberOfNodes];

        //Creates an element variable which takes in the current town were at on the stack
        //also creates a shortest variable to store the shortest distance each time
        //lastly an i to run through the loop with
        int element; 
        int shortest = 0;
        int i = 0;

        //Sets the default minimum value to max size
        double min = 0.0;

        //Total distance variable to be used
        double total = 0.0;
        double tempDistance = 0.0;

        //Used to say we found a shortest route this time
        boolean minFlag = false;

        //Run Nearest Neighbour for each starting town
        for(int k=0; k<numberOfNodes; k++)
        {
            visited[k] = true;

            //Pushes the first town onto the stack
            stack.push(k);

            //Always starting at the first town, so it prints this out
            System.out.print(k+1 + ".");

            //While the stack isn't empty, we see what town were at, start from town 0
            //and calculate all distances from town element to town i MAX
            while (!stack.isEmpty())
            {
                element = stack.peek();
                i = 0;

                //This min is used as a default biggest distance
                min = Double.MAX_VALUE;

                //Go up to the number of nodes
                while (i < numberOfNodes)
                {
                    //If the distance from this town to another is big enough and isn't already visited
                    if (adjacency_matrix[element][i] > 0.1 && visited[i] == false)
                    {
                        //Then if this distance is smaller than the last
                        if (min > adjacency_matrix[element][i])
                        {
                            //The minimum distance is now from element to i, shortest town is i, and the minflag is set
                            min = adjacency_matrix[element][i];
                            shortest = i;
                            minFlag = true;

                            tempDistance = adjacency_matrix[element][i];
                        }

                    }

                    i++;
                }

                //If we found a shortest route
                if (minFlag)
                {
                    //we visited it
                    visited[shortest] = true;

                    //It's now the town on the top of stack
                    stack.push(shortest);

                    //Print this out to the screen
                    System.out.print(shortest +1 + ".");

                    //Adds this distance into the total distance travelled
                    total += tempDistance;
                    tempDistance = 0.0;

                    for(int l=0; l<numberOfNodes; l++)
                    {
                        if(visited[l] == true)
                        {
                            count++;
                        }

                        if(count == 80)
                        {
                            last = stack.peek();
                        }

                        count = 0;
                    }

                    //Reset
                    minFlag = false;

                    //go back up the loops
                    continue;
                }

                stack.pop();
            }

            total +=adjacency_matrix[last][k];
            System.out.println("\nTotal distance was " + (total) + " km approximately.\n");

            //reset all variables for next run
            last = 0;
            count = 0;

            for(int reset=0; reset< numberOfNodes; reset++)
            {
                visited[reset] = false;
            }

            element =0; 
            shortest = 0;
            min = 0.0;
            total = 0.0;
            tempDistance = 0.0;
            minFlag = false;            
        }

    }

Here's what the algorithm is doing: - It takes the identity matrix, and the number of nodes in the graph. - It uses a stack to see what town it's at currently. - It also uses a boolean array to see where it has visited so far - It runs 80 times in a control loop to have each town as a starting point in each iteration. - Then the main calculation section checks what the shortest distance is in the matrix from the current town to another town, then pushes it onto the stack, marks it visited and repeats from there. - For the last bit, I hard code in to add town 80 back to town 1 as the last bit of distance. - It then prints out the distance and the route and then goes back up and checks the route from town 2.

Any help would be appreciated, if anything isn't clear from the commenting let me know.

brainiac
  • 41
  • 4
  • Before we are trying to dive into a wall of code to look for needle in a haystack, please first describe the algorithm you are using (in a few lines). You should also debug your code with a debugger to isolate subset of your code that is faulty. – amit May 03 '14 at 22:30
  • Your problem is that annother implementation, maybe using another algo gives you another solution? – Dirk Lachowski May 03 '14 at 22:34
  • edited in algorithm description above @amit – brainiac May 03 '14 at 22:45
  • Here's [my TSP distance implementation](https://github.com/droolsjbpm/optaplanner/blob/master/optaplanner-examples/src/main/java/org/optaplanner/examples/tsp/domain/City.java#L62), in case it helps... – Geoffrey De Smet May 04 '14 at 14:02
  • Thanks for the response @GeoffreyDeSmet, problem isn't in the actually distance function. I have a properly working haversine function calculating the distances for the identity matrix. It's something going wrong in the main function that is causing a wide variance in incorrect final distance. – brainiac May 04 '14 at 23:17

0 Answers0