回溯法解旅行商问题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;

}

}

}

四、优化空间

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
旅行商问题是一个经典的组合优化问题,它的目标是在给定的一些城市和它们之间的距离(或旅行时间)的情况下,找到一条经过每个城市一次且最短的路径。回溯法旅行商问题的一种常用方法。 以下是用回溯法旅行商问题的步骤: 1. 定义一个函数`backtrack(path, cost)`,其中`path`表示当前已经走过的路径,`cost`表示当前已经走过的路径的总旅费。 2. 如果`path`中包含了所有的城市,说明已经找到了一条完整的路径,此时更新最优和最优值。 3. 如果`cost`已经大于当前最优值,说明当前路径不是最优,直接返回。 4. 遍历所有的城市,如果该城市没有在`path`中出现过,将该城市加入`path`中,并将当前旅费加上该城市到上一个城市的旅费,然后递归调用`backtrack`函数。 5. 回溯到上一层时,将该城市从`path`中删除,并将当前旅费减去该城市到上一个城市的旅费。 下面是用Python实现的回溯法旅行商问题的代码: ```python def tsp_backtrack(graph, n): # 初始化最优和最优值 best_path = None best_cost = float('inf') # 定义回溯函数 def backtrack(path, cost): nonlocal best_path, best_cost # 如果已经遍历完所有城市,更新最优和最优值 if len(path) == n: cost += graph[path[-1]][path[0]] if cost < best_cost: best_path = path[:] best_cost = cost else: # 遍历所有城市 for i in range(n): if i not in path: # 将该城市加入路径中 path.append(i) cost += graph[path[-2]][i] # 递归调用回溯函数 backtrack(path, cost) # 回溯到上一层 cost -= graph[path[-2]][i] path.pop() # 从第一个城市开始遍历 path = [0] # 从第一个城市到自己的旅费为0 cost = 0 # 调用回溯函数 backtrack(path, cost) # 返回最优和最优值 return best_path, best_cost ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值