遗传算法解决tsp问题java
时间: 2023-07-28 12:07:47 浏览: 53
好的,遗传算法可以用于TSP问题的求解。下面是一个简单的Java实现,供您参考:
```java
import java.util.*;
public class TSPGeneticAlgorithm {
private int populationSize;
private double mutationRate;
private double crossoverRate;
private int elitismCount;
public TSPGeneticAlgorithm(int populationSize, double mutationRate, double crossoverRate, int elitismCount) {
this.populationSize = populationSize;
this.mutationRate = mutationRate;
this.crossoverRate = crossoverRate;
this.elitismCount = elitismCount;
}
public List<TSPChromosome> evolvePopulation(List<TSPChromosome> population) {
List<TSPChromosome> newPopulation = new ArrayList<>();
// Sort population by fitness
population.sort(Comparator.comparingDouble(TSPChromosome::getFitness));
// Apply elitism
for (int i = 0; i < elitismCount; i++) {
newPopulation.add(population.get(i));
}
// Crossover
for (int i = elitismCount; i < populationSize; i++) {
TSPChromosome parent1 = selectParent(population);
TSPChromosome parent2 = selectParent(population);
TSPChromosome child = crossover(parent1, parent2);
newPopulation.add(child);
}
// Mutation
for (int i = elitismCount; i < populationSize; i++) {
mutate(newPopulation.get(i));
}
return newPopulation;
}
private TSPChromosome selectParent(List<TSPChromosome> population) {
int index = (int) (Math.random() * population.size());
return population.get(index);
}
private TSPChromosome crossover(TSPChromosome parent1, TSPChromosome parent2) {
TSPChromosome child = new TSPChromosome(parent1.getCities().size());
int startPos = (int) (Math.random() * parent1.getCities().size());
int endPos = (int) (Math.random() * parent1.getCities().size());
for (int i = 0; i < child.getCities().size(); i++) {
if (startPos < endPos && i > startPos && i < endPos) {
child.setCity(i, parent1.getCity(i));
} else if (startPos > endPos) {
if (!(i < startPos && i > endPos)) {
child.setCity(i, parent1.getCity(i));
}
}
}
for (int i = 0; i < parent2.getCities().size(); i++) {
if (!child.containsCity(parent2.getCity(i))) {
for (int j = 0; j < child.getCities().size(); j++) {
if (child.getCity(j) == null) {
child.setCity(j, parent2.getCity(i));
break;
}
}
}
}
return child;
}
private void mutate(TSPChromosome chromosome) {
for (int i = 0; i < chromosome.getCities().size(); i++) {
if (Math.random() < mutationRate) {
int j = (int) (Math.random() * chromosome.getCities().size());
City city1 = chromosome.getCity(i);
City city2 = chromosome.getCity(j);
chromosome.setCity(i, city2);
chromosome.setCity(j, city1);
}
}
}
}
```
在上面的代码中,TSPChromosome类表示染色体,其中包含了一组城市的顺序,计算染色体的适应度(即路径长度),以及获取和设置城市的方法。City类表示一个城市,其中包含了城市的名称、经度和纬度。这两个类的代码如下:
```java
public class TSPChromosome {
private List<City> cities;
private double fitness;
public TSPChromosome(int size) {
cities = new ArrayList<>(size);
for (int i = 0; i < size; i++) {
cities.add(null);
}
}
public TSPChromosome(List<City> cities) {
this.cities = cities;
}
public List<City> getCities() {
return cities;
}
public void setCity(int index, City city) {
cities.set(index, city);
}
public City getCity(int index) {
return cities.get(index);
}
public double getFitness() {
if (fitness == 0) {
fitness = 1 / calculateDistance();
}
return fitness;
}
private double calculateDistance() {
double distance = 0;
for (int i = 0; i < cities.size(); i++) {
City fromCity = getCity(i);
City toCity;
if (i + 1 < cities.size()) {
toCity = getCity(i + 1);
} else {
toCity = getCity(0);
}
distance += fromCity.distanceTo(toCity);
}
return distance;
}
public boolean containsCity(City city) {
return cities.contains(city);
}
}
public class City {
private String name;
private double longitude;
private double latitude;
public City(String name, double longitude, double latitude) {
this.name = name;
this.longitude = longitude;
this.latitude = latitude;
}
public String getName() {
return name;
}
public double getLongitude() {
return longitude;
}
public double getLatitude() {
return latitude;
}
public double distanceTo(City other) {
double theta = longitude - other.getLongitude();
double dist = Math.sin(Math.toRadians(latitude)) * Math.sin(Math.toRadians(other.getLatitude())) + Math.cos(Math.toRadians(latitude)) * Math.cos(Math.toRadians(other.getLatitude())) * Math.cos(Math.toRadians(theta));
dist = Math.acos(dist);
dist = Math.toDegrees(dist);
dist = dist * 60 * 1.1515;
return dist;
}
}
```
在主函数中,可以使用以下代码来调用遗传算法:
```java
public static void main(String[] args) {
List<City> cities = new ArrayList<>();
cities.add(new City("New York", -74.0059413, 40.7127837));
cities.add(new City("Los Angeles", -118.2436849, 34.0522342));
cities.add(new City("Chicago", -87.6297982, 41.8781136));
cities.add(new City("Houston", -95.3698028, 29.7604267));
cities.add(new City("Philadelphia", -75.1652215, 39.9525839));
cities.add(new City("Phoenix", -112.0740373, 33.4483771));
cities.add(new City("San Antonio", -98.4936282, 29.4241219));
cities.add(new City("San Diego", -117.1610838, 32.715738));
cities.add(new City("Dallas", -96.7969879, 32.7766642));
cities.add(new City("San Jose", -121.8863286, 37.3382082));
List<TSPChromosome> population = new ArrayList<>(100);
for (int i = 0; i < 100; i++) {
TSPChromosome chromosome = new TSPChromosome(new ArrayList<>(cities));
Collections.shuffle(chromosome.getCities());
population.add(chromosome);
}
TSPGeneticAlgorithm ga = new TSPGeneticAlgorithm(100, 0.01, 0.95, 5);
for (int i = 0; i < 1000; i++) {
population = ga.evolvePopulation(population);
System.out.println(population.get(0).getFitness());
}
System.out.println(population.get(0).getCities());
}
```
在上面的代码中,首先定义了一组城市,然后生成了一个包含100个随机染色体的初始种群。接下来,使用TSPGeneticAlgorithm类的evolvePopulation方法对种群进行进化,并输出每一代的最优染色体的适应度。最后,输出最优染色体的顺序。