/*
* This file is part of JGAP.
*
* JGAP offers a dual license model containing the LGPL as well as the MPL.
*
* For licensing information please see the file license.txt included with JGAP
* or have a look at the top of class org.jgap.Chromosome which representatively
* includes the JGAP license policy applicable for any file delivered with JGAP.
*/
package examples.salesman;
import org.jgap.*;
import org.jgap.impl.*;
import org.jgap.impl.salesman.*;
/**
* Explains how to use JGAP extensions, needed to solve the task group,
* known as the <i>Problem of the travelling salesman</i>. The extensions are
* defined in {@link org.jgap.impl.salesman org.jgap.impl.salesman}
*
* <font size=-1><p>
* The traveling salesman problem is the following: given a finite number of
* 'cities' along with the cost of travel between each pair of them, find the
* cheapest way of visiting all the cities and returning to your starting point.
* </p></font>
*
* Also see
* <ul>
* <li>J. Grefenstette, R. Gopal, R. Rosmaita, and D. Gucht.
* <i>Genetic algorithms for the traveling salesman problem</i>.
* In Proceedings of the Second International Conference on Genetice
* Algorithms. Lawrence Eribaum Associates, Mahwah, NJ, 1985.
* </li>
* <li>
* <a href="http://ecsl.cs.unr.edu/docs/techreports/gong/node3.html">
* Sushil J. Louis & Gong Li</a> (very clear explanatory material)
* </li>
* <li>
* <a href="http://www.tsp.gatech.edu www.tsp.gatech.edu">
* <i>Travelling salesman</i> web site</a>
* </li>
* </ul>
*
* This simple test and example shows how to use the Salesman class.
* The distance between the cities is assumed to be equal
* to the difference of the assigned numbers. So, the
* optimal solution is obviously 1 2 3 4 ... n or reverse,
* but the system does not know this. To get the useful application, you
* need to override at least the distance function. Also, it is recommended
* to define a new type of gene, corresponding the data about your "city".
* For example, it can contain the city X and Y co-ordinates, used by
* the distance function.
*
* @author Audrius Meskauskas
* @since 2.0
*/
public class TravellingSalesman
extends Salesman {
/** String containing the CVS revision. Read out via reflection!*/
private static final String CVS_REVISION = "$Revision: 1.14 $";
/** The number of cities to visit*/
public static final int CITIES = 7;
public static final int[][] CITYARRAY = new int[][] { {2, 4}, {7, 5}, {7, 11},
{8, 1}, {1, 6}, {5, 9}, {0, 11}
};
/**
* Create an array of the given number of integer genes. The first gene is
* always 0, this is the city where the salesman starts the journey.
*
* @param a_initial_data ignored
* @return Chromosome
*
* @author Audrius Meskauskas
* @since 2.0
*/
public IChromosome createSampleChromosome(Object a_initial_data) {
try {
Gene[] genes = new Gene[CITIES];
for (int i = 0; i < genes.length; i++) {
genes[i] = new IntegerGene(getConfiguration(), 0, CITIES - 1);
genes[i].setAllele(new Integer(i));
}
IChromosome sample = new Chromosome(getConfiguration(), genes);
return sample;
}
catch (InvalidConfigurationException iex) {
throw new IllegalStateException(iex.getMessage());
}
}
/**
* Distance is equal to the difference between city numbers, except the
* distance between the last and first cities that is equal to 1. In this
* way, we ensure that the optimal solution is 0 1 2 3 .. n - easy to check.
*
* @param a_from first gene, representing a city
* @param a_to second gene, representing a city
* @return the distance between two cities represented as genes
* @author Audrius Meskauskas
* @since 2.0
*/
public double distance(Gene a_from, Gene a_to) {
IntegerGene geneA = (IntegerGene) a_from;
IntegerGene geneB = (IntegerGene) a_to;
int a = geneA.intValue();
int b = geneB.intValue();
int x1 = CITYARRAY[a][0];
int y1 = CITYARRAY[a][1];
int x2 = CITYARRAY[b][0];
int y2 = CITYARRAY[b][1];
// if (A == 0 && B == CITIES - 1) {
// return 1;
// }
// if (B == 0 && A == CITIES - 1) {
// return 1;
// }
return Math.sqrt( (x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
}
/**
* Solve a sample task with the number of cities, defined in a CITIES
* constant. Print the known optimal way, sample chromosome and found
* solution.
*
* @param args not relevant here
*
* @author Audrius Meskauskas
* @since 2.0
*/
public static void main(String[] args) {
try {
TravellingSalesman t = new TravellingSalesman();
IChromosome optimal = t.findOptimalPath(null);
System.out.println("Solution: ");
System.out.println(optimal);
System.out.println("Score " +
(Integer.MAX_VALUE / 2 - optimal.getFitnessValue()));
}
catch (Exception ex) {
ex.printStackTrace();
}
}
}