1

I'm trying to design a 2-opt local search heuristic for the TSP in Java, but my algorithm seems to be flawed. Given a nearest neighbor circuit as in input, it somehow makes the circuit worse. Nearest neighbor: http://goo.gl/uI5X6; After ten seconds of 2-opt: http://goo.gl/5AGJ1. My code is below. What's wrong with my implementation? Location[] location is simply a list of the nodes of the "graph", each with latitude and longitude and distance calculation between it and another node.

    public HamiltonianCircuit execute(Location[] locations) {
    long startTime = System.currentTimeMillis();
    while (true) {
        for (int i = 0; i < locations.length; i++) {
            for (int k = 0; k < locations.length; k++) {
                if (System.currentTimeMillis() - startTime >= 10000) {
                    return new HamiltonianCircuit(locations);
                }
                Location a = locations[i];
                Location b = locations[(i + 1) % locations.length];
                Location c = locations[k];
                Location d = locations[(k + 1) % locations.length];
                double distanceab = a.distanceBetween(b);
                double distancecd = c.distanceBetween(d);
                double distanceac = a.distanceBetween(c);
                double distancebd = b.distanceBetween(d);
                double change = (distanceab + distancecd) - 
                    (distanceac + distancebd);
                if (change > 0) {
                    locations[k] = a;
                    locations[i] = c;
                }
            }
        }
    }
}
James
  • 45
  • 6

2 Answers2

1

2-opt is replacing the edges AB and CD with the edges AC and BD which means if we have the partial circuit 0 A B x y z C D 1 to start with, we want 0 A C z y x B D 1 when we're done.
Your code would generate 0 C B x y z A D 1.

You want to swap B and C, but also need to reverse everything in the middle.

-2

A possible solution in Java could be something like: (Note:Verbose)

public HamiltonianCircuit execute(){
ArrayList<Vehicle> locations= new ArrayList<Locations>;
//populate array

    for (int i = 1; i < locations.size()-3; i++) {
            Location a = locations.get(i);
            Location b = locations.get(i+1);
            Location c = locations.get(i+2);
            Location d = locations.get(i+3);

            double distanceab = EuclidianDistance.pair(a, b);
            double distancebd = EuclidianDistance.pair(b, d);
            double distanceac = EuclidianDistance.pair(a, c);
            double distancecd = EuclidianDistance.pair(c, d);
            double abcd = distanceab+distancecd;
            double acbd = distanceac+distancebd;

            if(acbd<abcd){
                Collections.swap(locations, i+1, i+2);
                System.out.println("swapped"+vehicles);
            }
    }
    Locations.setDistance(EuclidianDistance.Collection(locations));
    return locations;
}
sman0307
  • 198
  • 1
  • 9