欢迎访问 生活随笔!

生活随笔

当前位置: 首页 > 编程资源 > 编程问答 >内容正文

编程问答

回溯法解旅行商问题java,回溯法-旅行商问题

发布时间:2024/1/1 编程问答 42 豆豆
生活随笔 收集整理的这篇文章主要介绍了 回溯法解旅行商问题java,回溯法-旅行商问题 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

一、问题描述

旅行推销员问题(英语:Travelling salesman problem, TSP)是这样一个问题:给定一系列城市和每对城市之间的距离,求解访问每一座城市一次并回到起始城市的最短回路。它是组合优化中的一个NP难问题,在运筹学和理论计算机科学中非常重要。

二、解决思路

这个问题有点像地图着色问题但是是不一样的,地点之间是带权路径,地图着色相当于是节点的选择,顺序无关性,这个是顺序有关性,求解选择哪个节点,哪一个则是节点的路径选择问题。首先定义解空间。

三、代码

public class TravelPlan {

public static void main(String[] args) {

int[][] adjacencyMartix = new int[][]{

{-1, 3, -1, 8, 9},

{3, -1, 3, 10, 5},

{-1, 3, -1, 4, 3},

{8, 10, 4, -1, 20},

{9, 5, 3, 20, -1}};

Scanner scanner = new Scanner(System.in);

int originNode = scanner.nextInt();

int[] currentValueStatus = new int[]{-1, -1, -1, -1, -1};

// 设置源点已经被访问过

currentValueStatus[originNode - 1] = 1;

int[] bestValueStatus = new int[adjacencyMartix.length];

System.out.println(calc(adjacencyMartix, originNode - 1, currentValueStatus, bestValueStatus, Integer.MAX_VALUE, 0, 1, originNode - 1));

System.out.println(Arrays.toString(bestValueStatus));

}

/**

* 进行计算

*

* @param adjacencyMatrix 记录城市间关系

* @param lastCityIndex 记录上个城市的索引 也是起始城市节点

* @param currentValue 此路径城市到访状态维护

* @param bestValueStatus 最好结果城市最好路径记录

* @param bestValue 最好的结果

* @param currentValue 当前结果值

* @param loopIndex 第几次路径选择

* @param originNode 起始节点因为最后要回到起始节点所以需要记录下

*/

public static Integer calc(int[][] adjacencyMatrix, int lastCityIndex, int[] currentValueStatus, int[] bestValueStatus, int bestValue, int currentValue, int loopIndex, int originNode) {

/**

* 收集 到达链路的终点

*/

if (loopIndex > currentValueStatus.length - 1) {

//最后一个城市和起始点有边

if (currentValue + adjacencyMatrix[lastCityIndex][originNode] < bestValue && adjacencyMatrix[lastCityIndex][originNode] != -1) {

// 记录最优的解 再加上回到原点的值

bestValue = currentValue + adjacencyMatrix[lastCityIndex][originNode];

for (int j = 0; j < currentValueStatus.length; j++) {

bestValueStatus[j] = currentValueStatus[j];

}

}

return bestValue;

} else {

//搜索 这里如果用交换的算法可以较少遍历 也就是将状态维护为到访区间和未到访区间 KISS原则怎么容易看怎么来

// 这里由于起源节点已经被设置为访问过,所以不会再访问

for (int j = 0; j < adjacencyMatrix.length; j++) {

// 起始节点最后到达叶子处理

if (j == originNode) {

continue;

}

// 上一节点和当前节点是通路并且 到达当前节点后的值还是小于最优值才可以继续 当前节点没有被访问过

if ((adjacencyMatrix[lastCityIndex][j] != -1 && adjacencyMatrix[lastCityIndex][j] + currentValue < bestValue && currentValueStatus[j] == -1)) {

// 标记为已经到访 -.- loop代表访问的第几个节点

loopIndex += 1;

currentValueStatus[j] = loopIndex;

// 值累加 前一个节点到当前节点的距离

currentValue += adjacencyMatrix[lastCityIndex][j];

// 递归向下走 j节点变成前一个几点

bestValue = calc(adjacencyMatrix, j, currentValueStatus, bestValueStatus, bestValue, currentValue, loopIndex, originNode);

//回溯当前节点累加的值

currentValueStatus[j] = -1;

loopIndex -= 1;

currentValue -= adjacencyMatrix[lastCityIndex][j];

}

}

return bestValue;

}

}

}

四、优化空间

总结

以上是生活随笔为你收集整理的回溯法解旅行商问题java,回溯法-旅行商问题的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。