1

I am trying to find a solution of Travelling salesman problem in java. I have applied simulated annealing to solve this in the following way. Here is a code segment where I have implemented simulated annealing :

public class SimulatedAnnealing {

// Calculate the acceptance probability
public static double acceptanceProbability(int energy, int newEnergy, double temperature) {
    // If the new solution is better, accept it
    if (newEnergy < energy) {
        return 1.0;
    }
    // If the new solution is worse, calculate an acceptance probability
    return Math.exp((energy - newEnergy) / temperature);
}

public static void main(String[] args) {
    // Create and add our cities
    City city = new City(60, 200);
    TourManager.addCity(city);
    City city2 = new City(180, 200);
    TourManager.addCity(city2);
    City city3 = new City(80, 180);
    TourManager.addCity(city3);
    City city4 = new City(140, 180);
    TourManager.addCity(city4);
    City city5 = new City(20, 160);


    // Set initial temp
    double temp = 10000;

    // Cooling rate
    double coolingRate = 0.003;

    // Initialize intial solution
    Tour currentSolution = new Tour();
    currentSolution.generateIndividual();

    System.out.println("Initial solution distance: " + currentSolution.getDistance());

    // Set as current best
    Tour best = new Tour(currentSolution.getTour());

    // Loop until system has cooled
    while (temp > 1) {
        // Create new neighbour tour
        Tour newSolution = new Tour(currentSolution.getTour());

        // Get a random positions in the tour
        int tourPos1 = (int) (newSolution.tourSize() * Math.random());
        int tourPos2 = (int) (newSolution.tourSize() * Math.random());

        // Get the cities at selected positions in the tour
        City citySwap1 = newSolution.getCity(tourPos1);
        City citySwap2 = newSolution.getCity(tourPos2);

        // Swap them
        newSolution.setCity(tourPos2, citySwap1);
        newSolution.setCity(tourPos1, citySwap2);

        // Get energy of solutions
        int currentEnergy = currentSolution.getDistance();
        int neighbourEnergy = newSolution.getDistance();

        // Decide if we should accept the neighbour
        if (acceptanceProbability(currentEnergy, neighbourEnergy, temp) > Math.random()) {
            currentSolution = new Tour(newSolution.getTour());
        }

        // Keep track of the best solution found
        if (currentSolution.getDistance() < best.getDistance()) {
            best = new Tour(currentSolution.getTour());
        }

        // Cool system
        temp *= 1-coolingRate;
    }

    System.out.println("Final solution distance: " + best.getDistance());
    System.out.println("Tour: " + best);
  }
}

when I finish the TSP problem using the above way, I find there are many cross in the picture, I heard the 2-Opt Arithmetic can solve this problem. Basically, I want to create Tours of two vertices, or basically a Set of the unique Edges. Now for each unique pair of edges (x,y) and (u,v), if the cost(x,y) + cost (u,v) < cost(x,u) + cost(y,v), then I will use edges (x,y) and (u,v) over (x,u) and (y,v). I will repeat this process for each unique pair of edges until the cost doesn't decrease.

But how I will find the unique pair of edges to apply the 2-opt technique? I mean if i generate a solution previously (like in the above code), how I will find the cross edges (the edged I need to examine for applying 2 opt) in the solution?

  • Typically you check each pair of edges and see whether the swap you described above improves the solution. If it does, make the swap. If not, move on. – LarrySnyder610 Apr 20 '16 at 22:50
  • Normally I get a set of vertices (for example: (60,200),(80,180),(140,180),(20,160),(180,200)) as output from the current solution. But from this output : How will i choose each pair of edges? can you please give me a demo code to do this part? @grendelsdad –  Apr 21 '16 at 04:19

1 Answers1

0

2-Opt can be implemented as a sub-tour reversal.

int[] tour= new int[]{1,2,3,6,5,4,7,8,9};
List<int[]> neighboors = new ArrayList<int[]>();
for (int i = 0; i<tour.length; ++i) {
  for (int j = i+1; j<tour.length; ++j) {
    neighboors.add(opt2(tour,i,j));
  }
}
function int[] opt2(tour, i,j) {
  int n = tour.length;
  int d = Math.abs(j-i);
  if (j<i) return null;//or fix it
  d = (d+1)/2;//d+1==element count... /2 === number of pairs to swap
  for (int k = 0; k <d; k++) {
    //swap tour[i+k] and tour[j-k]
  }
}

opt2(tour,3,5)={1,2,3,4,5,6,7,8,9} this swaps edges (3,6) and (4,7) with (3,4) and (6,7). opt2(tour,2,6)={1,2,7,4,5,6,3,8,9} swaps the edges (2,3) and (7,8) with (2,7) and (3,8)

Note that you don't need to consider reversing around the begining or end of the array. {"reverse begining", "keep the same", "reverse ending"} as it is the same as reverseTheWholeArray({"keep the same", "reverse the middle", "keep the same"}). That is a tour of {1,2,3,4} is the same as {4,3,2,1}.

Now the fun part is in realizing that 3-Opt could be implemented with tour "rotations" and reversals >:) or just up to 3 reversals.