旅行商问题的几种求解算法比较.docx
《旅行商问题的几种求解算法比较.docx》由会员分享,可在线阅读,更多相关《旅行商问题的几种求解算法比较.docx(12页珍藏版)》请在三一办公上搜索。
1、旅行商问题的几种求解算法比较旅行商问题的几种求解算法比较 作者: (xxx学校) 摘要:TSP问题是组合优化领域的经典问题之一,吸引了许多不同领域的研究工作者,包括数学,运筹学,物理,生物和人工智能等领域,他是目前优化领域里的热点.本文从动态规划法,分支界限法,回溯法分别来实现这个题目,并比较哪种更优越,来探索这个经典的NP(Nondeterministic Polynomial)难题. 关键词:旅行商问题 求解算法 比较 一.引言 旅行商问题(Travelling Salesman Problem),是计算机算法中的一个经典的难解问题,已归为NP一完备问题类.围绕着这个问题有各种不同的求解方
2、法,已有的算法如动态规划法,分支限界法,回溯法等,这些精确式方法都是指数级(2n)2,3的,根本无法解决目前的实际问题,贪心法是近似方法,而启发式算法不能保证得到的解是最优解,甚至是较好的解释.所以我认为很多问题有快速的算法(多项式算法),但是,也有很多问题是无法用算法解决的.事实上,已经证明很多问题不可能在多项式时间内解决出来.但是,有很多很重要的问题他们的解虽然很难求解出来,但是他们的值却是很容易求可以算出来的.这种事实导致了NP完全问题.NP表示非确定的多项式,意思是这个问题的解可以用非确定性的算法猜出来.如果我们有一个可以猜想的机器,我们就可以在合理的时间内找到一个比较好的解.NP-完
3、全问题学习的简单与否,取决于问题的难易程度.因为有很多问题,它们的输出极其复杂,比如说人们早就提出的一类被称作NP-难题的问题.这类问题不像NP-完全问题那样时间有限的.因为NP-问题由上述那些特征,所以很容易想到一些简单的算法把全部的可行解算一遍.但是这种算法太慢了(通常时间复杂度为O(2n)在很多情况下是不可行的.现在,没有知道有没有那种精确的算法存在.证明存在或者不存在那种精确的算法这个沉重的担子就留给了新的研究者了,或许你就是成功者. 本篇论文就是想用几种方法来就一个销售商从几个城市中的某一城市出发,不重复地走完其余N1个城市,并回到原出发点,在所有可能的路径中求出路径长度最短的一条,
4、比较是否是最优化,哪种结果好. 二.求解策略及优化算法 动态规划法解TSP问题 我们将具有明显的阶段划分和状态转移方程的规划称为动态规划,这种动态规划是在研究多阶段决策问题时推导出来的,具有严格的数学形式,适合用于理论上的分析.在实际应用中,许多问题的阶段划分并不明显,这时如果刻意地划分阶段法反而麻烦.一般来说,只要该问题可以划分成规模更小的子问题,并且原问题的最优解中包含了子问题的最优解(即满足最优子化原理),则可以考虑用动态规划解决.所以动态规划的实质是分治思想和解决冗余,因此,动态规划是一种将问题实例分解为更小的,相似的子问题,并存储子问题的解而避免计算重复的子问题,以解决最优化问题的算
5、法策略. 旅行商问题(TSP问题)其实就是一个最优化问题,这类问题会有多种可能的解,每个解都有一个值,而动态规划找出其中最优(最大或最小)值的解.若存在若干个取最优值的解的话,它只取其中的一个.在求解过程中,该方法也是通过求解局部子问题的解达到全局最优解,但与分治法和贪心法不同的是,动态规划允许这些子问题不独立,(亦即各子问题可包含公共的子子问题)也允许其通过自身子问题的解作出选择,该方法对每一个子问题只解一次,并将结果保存起来,避免每次碰到时都要重复计算. 关于旅行商的问题,状态变量是gk(i,S),表示从0出发经过k个城市到达i的最短距离,S为包含k个城市的可能集合,动态规划的递推关系为:
6、 gk(i,S)=mingk-1(j,Sj)+dji j属于S,dji表示j-i的距离. 或者我们可以用: f(S,v)表示从v出发,经过S中每个城市一次且一次,最短的路径. f(S,v)=min f(S-u,u)+dist(v,u) u in S f(V,1)即为所求 2.分支限界法解TSP问题 旅行商问题的解空间是一个排列树,与在子集树中进行最大收益和最小耗费分枝定界搜 索类似,使用一个优先队列,队列中的每个元素 中都包含到达根的路径. 假设我们要寻找的是最小耗费的旅行路径,那可以使用最小耗费分枝定界法.在实现 过程中,使用一个最小优先队列来记录活节点,队列中每个节点的类型为M i n H
7、 e a p N o d e.每个节点包括如下区域: x(从1到n的整数排列,其中x 0 = 1 ),s( 一个整数,使得从排列树的根节点到当前节点的路径定义了旅行路径的前缀x0:s, 而 剩余待访问的节点是x s + 1 : n - 1 ),c c(旅行路径前缀,即解空间树中从根 节点到当前节点的耗费),l c o s t(该节点子树中任意叶节点中的最小耗费), r c o s t(从顶点x s : n - 1 出发的所有边的最小耗费之和).当类型为M i n H e a p N o d e ( T )的数据被转换成为类型T时,其结果即为l c o s t的值.分枝定界 算法的代码见程序.
8、程序首先生成一个容量为1 0 0 0的最小堆,用来表示活节点的最小优先队列.活节点按其l c o s t值从最小堆中取出.接下来,计算有向图中从每个顶点出发的边中 耗费最小的边所具有的耗费M i n O u t.如果某些顶点没有出边,则有向图中没有旅行 路径,搜索终止.如果所有的顶点都有出边,则可以启动最小耗费分枝定界搜索.根的孩子(图1 6 - 5的节点B)作为第一个E-节点,在此节点上,所生成的旅行路径前缀只有一个顶点1,因此s=0, x0=1, x1:n-1是剩余的顶点(即顶点2 , 3 ,., n ).旅行路径前缀1 的开销为0 ,即c c = 0 ,并且,r c o st=n i=1
9、M i n O u t .在程序中,bestc 给出了当前能找到的最少的耗费值.初始时,由于没有找到任何旅行路径,因此b e s t c的值被设为N o E d g e. 程序旅行商问题的最小耗费分枝定界算法 template T AdjacencyWDigraph:BBTSP(int v) / 旅行商问题的最小耗费分枝定界算法 / 定义一个最多可容纳1 0 0 0个活节点的最小堆 MinHeap H(1000); T *MinOut = new T n+1; / 计算MinOut = 离开顶点i的最小耗费边的耗费 T MinSum = 0; / 离开顶点i的最小耗费边的数目 for (int
10、 i = 1; i = n; i+) T Min = NoEdge; for (int j = 1; j = n; j+) if (aj != NoEdge & (aj Min | Min = NoEdge) Min = aj; if (Min = NoEdge) return NoEdge; / 此路不通 MinOut = Min; MinSum += Min; / 把E-节点初始化为树根 MinHeapNode E; E.x = new int n; for (i = 0; i n; i+) E.x = i + 1; E.s = 0; / 局部旅行路径为x 1 : 0 E.cc = 0;
11、/ 其耗费为0 E.rcost = MinSum; T bestc = NoEdge; / 目前没有找到旅行路径 / 搜索排列树 while (E.s n - 1) / 不是叶子 if (E.s = n - 2) / 叶子的父节点 / 通过添加两条边来完成旅行 / 检查新的旅行路径是不是更好 if (aE.xn-2E.xn-1 != NoEdge & aE.xn-11 != NoEdge & (E.cc + aE.xn-2E.xn-1 + aE.xn-11 bestc | bestc = NoEdge) / 找到更优的旅行路径 bestc = E.cc + aE.xn-2E.xn-1 + aE
12、.xn-11; E.cc = bestc; E.lcost = bestc; E . s + + ; H . I n s e r t ( E ) ; else delete E.x; else / 产生孩子 for (int i = E.s + 1; i n; i+) if (aE.xE.sE.x != NoEdge) / 可行的孩子, 限定了路径的耗费 T cc = E.cc + aE.xE.sE.x; T rcost = E.rcost - MinOutE.xE.s; T b = cc + rcost; /下限 if (b bestc | bestc = NoEdge) / 子树可能有更好
13、的叶子 / 把根保存到最大堆中 MinHeapNode N; N.x = new int n; for (int j = 0; j n; j+) N.xj = E.xj; N.xE.s+1 = E.x; N.x = E.xE.s+1; N.cc = cc; N.s = E.s + 1; N.lcost = b; N.rcost = rcost; H . I n s e r t ( N ) ; / 结束可行的孩子 delete E.x; / 对本节点的处理结束 try H.DeleteMin(E); / 取下一个E-节点 catch (OutOfBounds) break; / 没有未处理的节点
14、 if (bestc = NoEdge) return NoEdge; / 没有旅行路径 / 将最优路径复制到v1:n 中 for (i = 0; i n; i+) vi+1 = E.x; while (true) /释放最小堆中的所有节点 delete E.x; try H.DeleteMin(E); catch (OutOfBounds) break; return bestc; while 循环不断地展开E-节点,直到找到一个叶节点.当s = n - 1时即可说明找到了 一个叶节点.旅行路径前缀是x 0 : n - 1 ,这个前缀中包含了有向图中所有的n个顶点.因此s = n - 1的活
15、节点即为一个叶节点.由于算法本身的性质,在叶节点上lco st 和cc 恰好等于叶节点对应的旅行路径的耗费.由于所有剩余的活节点的lcost 值都大于等于从最小堆中取出的第一个叶节点的lcost 值,所以它们并不能帮助我们找到更好的叶节点,因此,当某个叶节点成为E-节点后,搜索过程即终止. while 循环体被分别按两种情况处理,一种是处理s = n - 2的E-节点,这时,E-节点是某个单独叶节点的父节点.如果这个叶节点对应的是一个可行的旅行路径,并且此旅行路径的耗费小于当前所能找到的最小耗费,则此叶节点被插入最小堆中,否则叶节点被删除,并开始处理下一个E-节点. 其余的E-节点都放在whi
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 旅行 问题 求解 算法 比较
链接地址:https://www.31ppt.com/p-3571380.html