1、旅行商问题的求解方法摘要旅行商问题(TSP 问题)时是指旅行家要旅行 n 个城市然后回到出发城市,要求各个城市经历且仅经历一次,并要求所走的路程最短。该问题又称为货郎担问题、邮递员问题、售货员问题,是图问题中最广为人知的问题。本文主要介绍用蛮力法、动态规划法、贪心法和分支限界法求解 TSP 问题,其中重点讨论动态规划法和贪心法,并给出相应求解程序。关键字:旅行商问题;动态规划法;贪心法;分支限界法1 引言旅行商问题(TSP)是组合优化问题中典型的 NP-完全问题,是许多领域内复杂工程优化问题的抽象形式。研究 TSP 的求解方法对解决复杂工程优化问题具有重要的参考价值。关于 TSP 的完全有效的
2、算法目前尚未找到,这促使人们长期以来不断地探索并积累了大量的算法。归纳起来,目前主要算法可分成传统优化算法和现代优化算法。在传统优化算法中又可分为:最优解算法和近似方法。最优解算法虽然可以得到精确解,但计算时间无法忍受,因此就产生了各种近似方法,这些近似算法虽然可以较快地求得接近最优解的可行解,但其接近最优解的程度不能令人满意。但限于所学知识和时间限制,本文重点只讨论传统优化算法中的动态规划法、贪心法和分支限界法,并对蛮力法做简单介绍,用以比较。2 正文2.1 蛮力法2.1.1 蛮力法的设计思想蛮力法所依赖的基本技术是扫描技术,即采用一定的策略将待求解问题的所有元素一次处理一次,从而找出问题的
3、解。一次处理所有元素的是蛮力法的关键,为了避免陷入重复试探,应保证处理过的元素不再被处理。在基本的数据结构中,一次处理每个元素的方法是遍历。2.1.2 算法讨论用蛮力法解决 TSP 问题,可以找出所有可能的旅行路线,从中选取路径长度最短的简单回路。如对于图 1,我们求解过程如下:(1) 路径:1-2-3-4-1;路径长度:18;(2) 路径:1-2-4-3-1;路径长度:11;(3) 路径:1-3-2-4-1;路径长度:23;(4) 路径:1-3-4-2-1;路径长度:11;(5) 路径:1-4-2-3-1;路径长度:18;(6) 路径:1-4-3-2-1;路径长度:18;从中,我们可以知道,
4、路径(2)和(4)路径长度最短。我们还应注意到,图 1 中,有 3 对不同的路径,对每对路径来说,不同只是路径的方向,因此,可以将这个数量减半,则可能的解有(n-1)!/2 个。这是一个非常大的数,随着 n 的增长,TSP 问题的可能解也在迅速增长。如:一个 10 城市的 TSP 问题有大约有 180,000 个可能解。一个 20 城市的 TSP问题有大约有 60,000,000,000,000,000 个可能解。 一个 50 城市的 TSP 问题有大约 1062 个可能解,而一个行星上也只有 1021 升水。因此,我们可以知道用蛮力法求解 TSP 问题,只能解决问题规模很小的实例。2.2 动
5、态规划法2.2.1 动态规划法的设计思想动态规划法将待求解问题分解成若干个相互重叠的子问题,每个子问题对应决策过程的一个阶段,一般来说,子问题的重叠关系表现在对给定问题求解的递推关系(也就是动态规划函数)中,将子问题的解求解一次并填入表中,当需要再次求解此子问题时,可以通过查表获得该子问题的解而不用再次求解,从而避免了大量重复计算。2.2.2TSP 问题的动态规划函数假设从顶点 i 出发,令 表示从顶点 i 出发经过 中各个顶点一次且(,)diVV仅一次,最后回到出发点 i 的最短路径长度,开始时, ,于是,TSPi问题的动态规划函数为: (,)min(,)()ikidiVcdkk2.2.3
6、算法讨论(1)for (i=1; i (int)Math.pow(2,N-1) - 1)return;/如果全部顶点已初始化完成,则返回。if(m = 0)Vm + = “;/初始化出发顶点,即V0elseint i = m - 1;while(i = 0 i +;/把指针i指向满足条件的第一个集合while(i civ + dvstringEqual(str)min = civ + dvstringEqual(str);pathij = pathvstringEqual(str) + i;k +;/Vj.substring(beginIndex, endIndex)/System.out.p
7、rintln(pathij);return min;/返回最小值/处理函数public void dynamic()d = new intN(int)Math.pow(2,N-1);/分配空间path = new StringN(int)Math.pow(2,N-1);for(int i = 1 ; i = 0 ; i -)System.out.print(“-“ + str.charAt(i);System.out.println(“会有最短路径“ );System.out.println(“最短路径为:“ + d0(int)Math.pow(2,N-1) - 1);/主函数public s
8、tatic void main(String args) TSPDynamic TSP = new TSPDynamic();TSP.dynamic();/求最短路径/TSP.print();TSP.printShortestPath();/输出最短路径/测试数据/*99999 3 6 75 99999 2 36 4 99999 23 7 5 99999*/6.1.2 结果(1)(2)(3)(4)6.2 贪心法6.2.1 源代码package exp2;import java.util.Scanner;public class TSPGreedNode int V;/存放旅行所经过的城市顶点i
9、nt c;/存放每两座城市间的距离,注意:若路径不存在或同一城市间距离为无穷大int path;/存放旅行所经过的每两座城市间的距离int N;/城市个数int shortestPath;/表示最短路径int u0;/出发城市编号static int IFINITE = 99999;/无穷大距离 表示城市自己到达自己时,距离无穷大,不作为考虑因素public TSPGreedNode ()initialC();/得到最短路径public int getShortestPath()for(int i = 0 ; i “ + Vi + 1 + “,所经路程为:“ + pathi);shortestPath += pathi;System.out.println(“总路程为:“ + shortestPath);/* param args*/public static void main(String args) / TODO Auto-generated method stubTSPGreedNode gd = new TSPGreedNode();gd.tspGreedNode();gd.print();/*99999 3 3 2 63 99999 7 3 23 7 99999 2 52 3 2 99999 36 2 5 3 99999*/6.2.2 结果(1)(2)(3)(4)