用java代码实现一个旅行商问题
时间: 2024-02-03 08:16:00 浏览: 64
旅行商问题的代码实现
旅行商问题(Traveling Salesman Problem,TSP)是一个经典的组合优化问题,其目标是在给定的一组城市和每对城市之间的距离,找到一条经过每个城市一次且回到起点的最短路径。该问题属于 NP 难问题,没有多项式时间算法可以解决。
下面是一个用Java代码实现TSP的例子,采用了遗传算法来求解:
```java
import java.util.Arrays;
import java.util.Random;
public class TSP {
// 城市数量
private static final int CITY_NUM = 20;
// 迭代次数
private static final int MAX_ITERATION = 1000;
// 种群大小
private static final int POPULATION_SIZE = 100;
// 交叉概率
private static final double CROSSOVER_RATE = 0.9;
// 变异概率
private static final double MUTATION_RATE = 0.1;
// 交叉方式
private static final int CROSSOVER_TYPE = 1;
// 种群
private int[][] population = new int[POPULATION_SIZE][CITY_NUM];
// 适应度
private double[] fitness = new double[POPULATION_SIZE];
// 距离矩阵
private double[][] distanceMatrix = new double[CITY_NUM][CITY_NUM];
// 初始化距离矩阵
private void initDistanceMatrix() {
// 随机生成城市之间的距离
Random random = new Random();
for (int i = 0; i < CITY_NUM; i++) {
for (int j = i; j < CITY_NUM; j++) {
double distance = random.nextDouble() * 100;
distanceMatrix[i][j] = distance;
distanceMatrix[j][i] = distance;
}
}
}
// 计算一条路径的总距离
private double calculateDistance(int[] path) {
double distance = 0;
for (int i = 0; i < CITY_NUM - 1; i++) {
int city1 = path[i];
int city2 = path[i + 1];
distance += distanceMatrix[city1][city2];
}
distance += distanceMatrix[path[CITY_NUM - 1]][path[0]];
return distance;
}
// 计算适应度
private void calculateFitness() {
double totalDistance = 0;
for (int i = 0; i < POPULATION_SIZE; i++) {
int[] path = population[i];
double distance = calculateDistance(path);
fitness[i] = 1.0 / distance;
totalDistance += distance;
}
for (int i = 0; i < POPULATION_SIZE; i++) {
fitness[i] /= totalDistance;
}
}
// 选择
private int select() {
double r = Math.random();
double sum = 0;
for (int i = 0; i < POPULATION_SIZE; i++) {
sum += fitness[i];
if (r < sum) {
return i;
}
}
return 0;
}
// 交叉
private int[] crossover(int[] parent1, int[] parent2) {
int[] child = new int[CITY_NUM];
if (CROSSOVER_TYPE == 1) {
// 随机选择一个位置,将父代1的前半部分和父代2的后半部分拼接起来
Random random = new Random();
int pos = random.nextInt(CITY_NUM);
for (int i = 0; i < pos; i++) {
child[i] = parent1[i];
}
for (int i = pos; i < CITY_NUM; i++) {
int city = parent2[i];
while (contains(child, city)) {
city = parent2[++i % CITY_NUM];
}
child[i] = city;
}
} else if (CROSSOVER_TYPE == 2) {
// 随机选择两个位置,将父代1这两个位置之间的城市和父代2这两个位置之间的城市交换
Random random = new Random();
int pos1 = random.nextInt(CITY_NUM);
int pos2 = random.nextInt(CITY_NUM);
if (pos2 < pos1) {
int temp = pos1;
pos1 = pos2;
pos2 = temp;
}
for (int i = 0; i < CITY_NUM; i++) {
if (i >= pos1 && i <= pos2) {
child[i] = parent2[i];
} else {
int city = parent1[i];
while (contains(child, city)) {
city = parent1[++i % CITY_NUM];
}
child[i] = city;
}
}
}
return child;
}
// 变异
private void mutate(int[] path) {
Random random = new Random();
if (random.nextDouble() < MUTATION_RATE) {
int pos1 = random.nextInt(CITY_NUM);
int pos2 = random.nextInt(CITY_NUM);
int temp = path[pos1];
path[pos1] = path[pos2];
path[pos2] = temp;
}
}
// 判断一个城市是否已经在路径中
private boolean contains(int[] path, int city) {
for (int i = 0; i < CITY_NUM; i++) {
if (path[i] == city) {
return true;
}
}
return false;
}
// 初始化种群
private void initPopulation() {
for (int i = 0; i < POPULATION_SIZE; i++) {
int[] path = new int[CITY_NUM];
for (int j = 0; j < CITY_NUM; j++) {
path[j] = j;
}
shuffle(path);
population[i] = path;
}
}
// 打乱数组顺序
private void shuffle(int[] array) {
Random random = new Random();
for (int i = array.length - 1; i >= 1; i--) {
int j = random.nextInt(i + 1);
int temp = array[i];
array[i] = array[j];
array[j] = temp;
}
}
// 遗传算法求解TSP
public void solve() {
// 初始化距离矩阵和种群
initDistanceMatrix();
initPopulation();
// 迭代
for (int iter = 0; iter < MAX_ITERATION; iter++) {
// 计算适应度
calculateFitness();
// 生成下一代种群
int[][] nextPopulation = new int[POPULATION_SIZE][CITY_NUM];
for (int i = 0; i < POPULATION_SIZE; i++) {
int parent1 = select();
int parent2 = select();
int[] child = crossover(population[parent1], population[parent2]);
mutate(child);
nextPopulation[i] = child;
}
population = nextPopulation;
}
// 找到最优解
double minDistance = Double.MAX_VALUE;
int[] bestPath = null;
for (int i = 0; i < POPULATION_SIZE; i++) {
double distance = calculateDistance(population[i]);
if (distance < minDistance) {
minDistance = distance;
bestPath = population[i];
}
}
// 输出结果
System.out.println("最短路径长度为:" + minDistance);
System.out.print("最短路径为:");
for (int i = 0; i < CITY_NUM; i++) {
System.out.print(bestPath[i] + " ");
}
}
public static void main(String[] args) {
TSP tsp = new TSP();
tsp.solve();
}
}
```
阅读全文