算法题解:旅行商(TSP)问题JAVA算法求解

旅行商TSP问题描述

旅行推销员问题(Travelling salesman problem, TSP)是这样一个问题:给定一组城市和每对城市之间的距离,问题是找到最短的可能路线,访问每个城市一次,然后返回起点。它是组合优化中的一个NP困难问题,在运筹学和理论计算机科学中非常重要。

 

注意哈密顿回路和TSP之间的区别。哈密顿回路问题是要找出是否存在一个旅游线路,每个城市访问一次。这里我们知道哈密顿回路存在(因为图是完整的),事实上存在许多这样的回路,问题是找到一个最小权重的哈密顿回路。

算法题解:旅行商(TSP)问题JAVA算法求解_第1张图片

例如,考虑上面图中所示的内容。图中的TSP路线为:是-0>1->3->2->0。旅游费用为10+25+30+15,共80元。

哈密顿回路
哈密顿图(哈密尔顿图)(Hamiltonian graph,或Traceable graph)是一个无向图,由天文学家哈密顿提出,由指定的起点前往指定的终点,途中经过所有其他节点且只经过一次。在图论中是指含有哈密顿回路的图,闭合的哈密顿路径称作哈密顿回路(Hamiltonian cycle),含有图中所有顶点的路径称作哈密顿路径(Hamiltonian path)。


算法分析

这里给出一种简单的算法实现。


将城市0(假设为第0个节点)作为起点和终点。由于路线是循环的,所以我们可以把任何一点作为起点。

以DFS方式开始从源到相邻节点的遍历。

计算每次遍历的成本,跟踪最小成本,并不断更新最小成本存储值。

以最低成本返回结果。


算法设计

package com.bean.algorithm.basic;

public class TravellingSalesmanProblem {

	static int tsp(int[][] graph, boolean[] v, int currPos, int n, int count, int cost, int ans) {

		if (count == n && graph[currPos][0] > 0) {
			ans = Math.min(ans, cost + graph[currPos][0]);
			return ans;
		}

		/*
		 * 回溯步骤(BACKTRACKING STEP) 
		 * 循环遍历currPos结点的邻接表,将计数增加1,并按graph[currPos][i]值增加成本
		 * cost + graph[currPos][i]
		 */

		for (int i = 0; i < n; i++) {
			if (v[i] == false && graph[currPos][i] > 0) {

				// 标记结点被访问过
				v[i] = true;
				ans = tsp(graph, v, i, n, count + 1, cost + graph[currPos][i], ans);

				// 标记结点没有被访问过
				v[i] = false;
			}
		}
		return ans;
	}

	public static void main(String[] args) {
		// 顶点(结点)的数量
		int n = 4;

		int[][] graph = { 
				{ 0, 10, 15, 20 }, 
				{ 10, 0, 35, 25 }, 
				{ 15, 35, 0, 30 }, 
				{ 20, 25, 30, 0 } 
				};

		// boolean类型的数组 v 用来标记一个城市结点是否被访问过
		boolean[] v = new boolean[n];

		// 标记第 0 个 结点已经被访问过,所以v[0]=true
		v[0] = true;
		int ans = Integer.MAX_VALUE;

		// 查找最小权重的汉密尔顿回路 Hamiltonian Cycle
		ans = tsp(graph, v, 0, n, 1, 0, ans);

		// 输出结果ans就是最小权重的汉密尔顿回路( Hamiltonian Cycle)
		System.out.println(ans);

	}
}

程序运行结果:

80

 

你可能感兴趣的:(算法分析与设计)