How to implement N-Opt in Genetic Algorithm To Solve the Travelesman Problem?

Hi Guys,
How to implement N-Opt in Genetic Algorithm To Solve the Travelesman Problem?

Im trying to implement 2-opt in a GA algorithm, but im confused in how-to…
Should i implement it in the mutate() method or mate() method?

https://bitbucket.org/dermetfan/tsm-ga-solver/src/73f2a35bf2e036bdcca03bef4340eeb683dc620e/core/src/main/net/nexusteam/tsmGaSolver/ann/TSPGeneticAlgorithm.java?at=default

https://bitbucket.org/dermetfan/tsm-ga-solver/src/73f2a35bf2e036bdcca03bef4340eeb683dc620e/core/src/main/net/nexusteam/tsmGaSolver/ann/TSPChromosome.java?at=default

//

https://bitbucket.org/dermetfan/tsm-ga-solver/src/73f2a35bf2e036bdcca03bef4340eeb683dc620e/core/src/main/net/JeffHeatonCode/GeneticAlgorithm.java?at=default

https://bitbucket.org/dermetfan/tsm-ga-solver/src/73f2a35bf2e036bdcca03bef4340eeb683dc620e/core/src/main/net/JeffHeatonCode/Chromosome.java?at=default

I know in theory how 2-opt should WORK :

Example :
For 4 Cities A,B,C,D

A B
C D

A–> D -->C -->B

Their connections form concorrent lines…
The method should be capable to Transform that into either these :

A–>B–>D–>C
or
A–>C–>D–>B

The one with less cost obviously.

Im not getting how to do it.
I know how to identify if a line intersects other by using

f(x) = mx + b
Or is there any other way i should do it?

Guys, i got this Now.
But im confused with this part:

  2optSwap(route, i, k) {
       1. take route[0] to route[i-1] and add them in order to new_route
       2. take route[i] to route[k] and add them in reverse order to new_route
       3. take route[k+1] to end and add them in order to new_route
       return new_route;
   }

What exactly should we do???

package net.nexusteam.tsmGaSolver.ann;

import net.JeffHeatonCode.Chromosome;
import net.JeffHeatonCode.NeuralNetworkError;

/** @author Mix Of Jeff Heaton Code with Our Team Code */
public class TSPChromosome extends Chromosome<Integer, TSPGeneticAlgorithm> {

	protected Waypoint[] path;

	public TSPChromosome(final TSPGeneticAlgorithm owner, final Waypoint path[]) {
		setGeneticAlgorithm(owner);
		this.path = path;

		final Integer genes[] = new Integer[this.path.length];
		final boolean taken[] = new boolean[path.length];

		for(int i = 0; i < genes.length; i++) {
			taken[i] = false;
		}
		for(int i = 0; i < genes.length - 1; i++) {
			int icandidate;

			do {
				icandidate = (int) (Math.random() * genes.length);
			} while(taken[icandidate]);

			genes[i] = icandidate;
			taken[icandidate] = true;
			if(i == genes.length - 2) {
				icandidate = 0;

				while(taken[icandidate]) {
					icandidate++;
				}

				genes[i + 1] = icandidate;
			}
		}
		setGenes(genes);
		calculateCost();

	}

	@Override
	public void calculateCost() throws NeuralNetworkError {
		double cost = 0.0;
		for(int i = 0; i < path.length - 1; i++) {
			final double dist = path[getGene(i)].dst(path[getGene(i + 1)]);
			cost += dist;
		}
		setCost(cost);

	}

	@Override
	public void mutate() {
		final int length = getGenes().length;
		final int iswap1 = (int) (Math.random() * length);
		final int iswap2 = (int) (Math.random() * length);
		final Integer temp = getGene(iswap1);

		setGene(iswap1, getGene(iswap2));
		setGene(iswap2, temp);
		getGeneticAlgorithm().incrementMutationCounter();

		boolean use2OptSwap = false;
		if(use2OptSwap)
		{
			setGenes(optimize(getGenes()));

		}

		// System.out.println("Mutation Calls : " + getGeneticAlgorithm().gettimesMutated());

	}

	//2Opt Methods
	private Waypoint[] optSwap(Integer genes[], int i, int k)
	{

		//Step 1

		for(int index = i; index < i - 1; i++)
		{

		}

		//Step 2

		for(int index = i; index < k; i++)
		{

		}

		//Step 3

		for(int index = k + 1; index < genes.length; i++)
		{

		}

		//2optSwap(route, i, k) {
		//     1. take route[0] to route[i-1] and add them in order to new_route
		//   2. take route[i] to route[k] and add them in reverse order to new_route
		//  3. take route[k+1] to end and add them in order to new_route
		//  return new_route;
		// }

		//

		return path;
	}

	/**
	 * @param genes
	 * @return
	 */
	private Integer[] optimize(Integer genes[])
	{
		boolean improved = false;
		double best_distance = Double.MAX_VALUE;

		while(!improved)
		{
			calculateCost();
			best_distance = getCost();

			for(int i = 0; i < getGenes().length; i++)
			{
				for(int k = i + 1; k < getGenes().length; k++)
				{

					TSPChromosome newRoute = new TSPChromosome(this.getGeneticAlgorithm(), optSwap(genes, i, k));

					newRoute.calculateCost();

					double new_distance = newRoute.getCost();

					if(new_distance < best_distance)
					{
						improved = true;
						genes = newRoute.getGenes();
					}

				}
			}
		}

		return genes;

		// repeat until no improvement is made {
		//     start_again:
		//   best_distance = calculateTotalDistance(existing_route)
		// for (i = 0; i < number of nodes eligible to be swapped - 1; i++) {
		//   for (k = i + 1; k < number of nodes eligible to be swapped; k++) {
		//     new_route = 2optSwap(existing_route, i, k)
		//   new_distance = calculateTotalDistance(new_route)
		// if (new_distance < best_distance) {
		//   existing_route = new_route
		// goto start_again
		//}
		//}
		//}
		//}

		//
	}

	/** Used to compare two chromosomes. Used to sort by cost.
	 * 
	 * @param other The other chromosome to compare.
	 * @return The value 0 if the argument is a chromosome that has an equal cost to this chromosome; a value less than 0 if the
	 *         argument is a chromosome with a cost greater than this chromosome; and a value greater than 0 if the argument is a
	 *         chromosome what a cost less than this chromosome. */
	@Override
	public int compareTo(Chromosome<Integer, TSPGeneticAlgorithm> other) {
		if(getCost() > other.getCost()) {
			return 1;
		} else if(getCost() == other.getCost())
			return 0;
		else {
			return -1;
		}
	}

	/** @return the {@link #path} */
	public Waypoint[] getPath() {
		return path;
	}

}

Ok, i made a small example class…
Not working, having NPE issues…
Can anyone help me?

package br.Lopes.Logic;

/**
 *
 * @author Andre Lopes
 */
public class Logic {

    private Waypoint waypoints[];

    public static void main(String args[]) {
        Logic logic = new Logic();
        logic.optimizeRoute(logic.waypoints);

    }

    public Logic() {
        waypoints = new Waypoint[4];

        //Add A--> C and C-->D and D--> B
        waypoints[0] = new Waypoint(0, 0, "A"); //Left Bottom
        waypoints[1] = new Waypoint(5, 5, "C"); // Right Top
        waypoints[2] = new Waypoint(0, 5, "B"); //Left Top
        waypoints[3] = new Waypoint(5, 0, "D"); //Right Bottom

    }

    public Waypoint[] optSwap(Waypoint waypoints[], int i, int k) {

        Waypoint auxWaypoints[] = new Waypoint[waypoints.length];

        for (int index = 0; index < i - 1; index++) {
            System.out.println("Step 1 : Index :" + index);
            auxWaypoints[index] = waypoints[index];
        }
        System.out.println("Step 1 : ");
        //printVector(auxWaypoints);

        int reverse = k;
        for (int index = i; index < k; index++) {
            auxWaypoints[index] = waypoints[reverse];
            reverse--;
        }
        System.out.println("Step 2 : ");
        printVector(auxWaypoints);

        for (int index = k + 1; index < waypoints.length; index++) {
            auxWaypoints[index] = waypoints[index];
        }
        System.out.println("Step 3 : ");
        printVector(auxWaypoints);

        return auxWaypoints;

    }

//     2optSwap(route, i, k) {
//       1. take route[0] to route[i-1] and add them in order to new_route
//       2. take route[i] to route[k] and add them in reverse order to new_route
//       3. take route[k+1] to end and add them in order to new_route
//       return new_route;
//   }
//     
//      example route: A ==> B ==> C ==> D ==> E ==> F ==> G ==> H ==> A
//   example i = 4, example k = 7
//   new_route:
//       1. (A ==> B ==> C)
//       2. A ==> B ==> C ==> (G ==> F ==> E ==> D)
//       3. A ==> B ==> C ==> G ==> F ==> E ==> D (==> H ==> A)
//    
//          repeat until no improvement is made {
//       start_again:
//       best_distance = calculateTotalDistance(existing_route)
//       for (i = 0; i < number of nodes eligible to be swapped - 1; i++) {
//           for (k = i + 1; k < number of nodes eligible to be swapped; k++) {
//               new_route = 2optSwap(existing_route, i, k)
//               new_distance = calculateTotalDistance(new_route)
//               if (new_distance < best_distance) {
//                   existing_route = new_route
//                   goto start_again
//               }
//           }
//       }
//   }
    public void optimizeRoute(Waypoint waypoints[]) {
        int numberOfRowsToBeSwapped = waypoints.length;
        int numberOfColumnsToBeSwapped = waypoints.length;

        double bestDistance = calculateTotalDistance(waypoints);

        //Aux Variables
        Waypoint[] new_route;
        double new_distance;
        for (int i = 0; i < numberOfRowsToBeSwapped - 1; i++) {
            for (int k = i + 1; k < numberOfColumnsToBeSwapped; k++) {
                System.out.println("OptSwap : (i;k)" + i + ";" + k);
                new_route = optSwap(waypoints, i, k);
                System.out.println("New Route Calculated!");
                new_distance = calculateTotalDistance(new_route);

                if (new_distance < bestDistance) {
                    this.waypoints = new_route;
                    System.out.println("New Route Set!");
                }
            }
        }
    }

    public double calculateTotalDistance(Waypoint waypoints[]) {
        double distance = 0;
        for (int i = 0; i < waypoints.length; i++) {
            Waypoint auxpoint = waypoints[i];
            double dx = 0, dy = 0;
            if (i > 0) {
                dx = waypoints[i - 1].getX() - auxpoint.getX();
                dy = waypoints[i - 1].getY() - auxpoint.getY();
            }

            System.out.println("Name : " + auxpoint.getName());
            distance += Math.sqrt(dx * dx + dy * dy);
        }

        System.out.println("Calculated Distance :" + distance);
        return distance;

    }

    private void printVector(Waypoint waypointsAux[]) {
        for (int index = 0; index < waypointsAux.length; index++) {
            Waypoint auxpoint = waypointsAux[index];
            if (auxpoint == null) {
                System.out.println("WayPoint[" + index + "] = NULL!");
                break;
            }
            System.out.println("\nWayPoint");
            System.out.println("Name : " + auxpoint.getName());
            System.out.println("X;Y :" + auxpoint.getX() + ";" + auxpoint.getY());
        }
    }
}

You’re just attempting to find a path through waypoints? If so, forget genetic. Heck even forget shortest path.

His problem is to find the shortest path through all waypoints and back. I believe that is the minimum criteria.

It works fine without 2-opt method.

Now im trying to implement 2-opt into the mutate() method…

I understand the definition of the problem. :slight_smile: And I also understand that the solution to the problem contains no fun-factor. Moreover, generally, traveling salesman paths tend to look unnatural because they are. Likewise for shortest path (with obstacles). It’s not what animals or humans do. Keep it simple.

EDIT: Likewise for A* like path finding. Forget admissible heuristics.