在代码中,我们首先定义了一个 TSP 类,该类接受城市之间的距离矩阵和出发城市作为参数。然后我们使用回溯法来求解旅行商问题。在 solve 方法中,我们从第二个城市开始搜索,调用 backtrack 方法来进行回溯。在backtrack方法中,我们首先判断当前是否已经访问完所有城市。如果是,我们计算回到出发城市的距离,并更新最小距离和最优路径。如果不是,我们遍历所有没有被访问过的城市,并计算到这个城市的距离。如果新的距离已经大于最小距离,就没有必要搜索了(这就是剪枝操作)。否则,我们继续搜索下一个城市。
最后,在 main 方法中,我们定义了一个城市之间的距离矩阵,然后创建一个 TSP 对象,并调用 solve 方法来求解旅行商问题。
最小路径长度:21
最小路径:0 1 3 2 0
这表示从出发城市 0 开始,按照顺序访问城市 1、3、2,最后回到城市 0,可以得到最短的路径长度为 21。
import java.util.Arrays;
public class TSP {
private int[][] graph; // 存储城市之间的距离
private int[] path; // 存储当前的路径
private boolean[] visited; // 存储城市是否被访问过
private int n; // 城市数量
private int minDistance; // 最小路径长度
private int startCity; // 出发城市
public TSP(int[][] graph, int startCity) {
this.graph = graph;
this.n = graph.length;
this.path = new int[n + 1];
this.visited = new boolean[n];
Arrays.fill(visited, false);
this.minDistance = Integer.MAX_VALUE;
this.startCity = startCity;
path[0] = startCity; // 第一个城市是出发城市
visited[startCity] = true;
}
public void solve() {
backtrack(1, 0); // 从第二个城市开始搜索
System.out.println("最小路径长度:" + minDistance);
System.out.print("最小路径:");
for (int i = 0; i <= n; i++) {
System.out.print(path[i] + " ");
}
System.out.println();
}
private void backtrack(int cityIndex, int distance) {
if (cityIndex == n) { // 所有城市都已经访问完
int lastCity = path[n - 1];
int distanceToStart = graph[lastCity][startCity]; // 回到出发城市的距离
int totalDistance = distance + distanceToStart;
if (totalDistance < minDistance) {
minDistance = totalDistance;
path[n] = startCity; // 最后一个城市是出发城市
}
return;
}
for (int i = 0; i < n; i++) {
if (!visited[i]) {
int lastCity = path[cityIndex - 1];
int newDistance = distance + graph[lastCity][i]; // 计算新的距离
if (newDistance >= minDistance) { // 剪枝:如果当前距离已经大于最小距离,就没有必要搜索了
continue;
}
visited[i] = true;
path[cityIndex] = i;
backtrack(cityIndex + 1, newDistance);
visited[i] = false;
}
}
}
public static void main(String[] args) {
int[][] graph = {
{0, 2, 9, 10},
{1, 0, 6, 4},
{15, 7, 0, 8},
{6, 3, 12, 0}
};
int startCity = 0;
TSP tsp = new TSP(graph, startCity);
tsp.solve();
}
}