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.