TSP问题算法分析

合集下载

TSP问题算法分析

TSP问题算法分析

算法第二次大作业TSP问题算法分析021251班王昱(02125029)-.问题描述“TSP问题”常被称为“旅行商问题”,是指一名推销员要拜访多个地点时,如何找到在拜访每个地点一次后再回到起点的最短路径。

TSP问题在本实验中的具体化:从A城市出发,到达每个城市并且一个城市只允许访问一次,最后又回到原来的城市,寻找一条最短距离的路径。

二.算法描述2.1分支界限法2.1.1算法思想分支限界法常以广度优先或以最小耗费(最大效益)优先的方式搜索问题的解空间树。

在分支限界法中,每一个活结点只有一次机会成为扩展结点。

活结点一旦成为扩展结点,就一次性产生其所有儿子结点。

在这些儿子结点中,导致不可行解或导致非最优解的儿子结点被舍弃,其余儿子结点被加入活结点表中。

此后,从活结点表中取下一结点成为当前扩展结点,并重复上述结点扩展过程。

这个过程一直持续到找到所需的解或活结点表为空时为止。

2.1.2算法设计说明设求解最大化问题,解向量为X=(x1,…,xn),xi的取值范围为Si,|Si|=ri 。

在使用分支限界搜索问题的解空间树时,先根据限界函数估算目标函数的界[down, up],然后从根结点出发,扩展根结点的r1个孩子结点,从而构成分量x1的r1种可能的取值方式。

对这r1个孩子结点分别估算可能的目标函数bound(x1),其含义:以该结点为根的子树所有可能的取值不大于bound(x1),即:bound(x1) >bound(x1,x2)》bound(x1,…,xn)若某孩子结点的目标函数值超出目标函数的下界,则将该孩子结点丢弃;否则,将该孩子结点保存在待处理结点表PT中。

再取PT表中目标函数极大值结点作为扩展的根结点,重复上述。

直到一个叶子结点时的可行解X=(x1,…,xn),及目标函数值bound(x1,…,xn)。

2.2 A*算法算法思想对于某一已到达的现行状态,如已到达图中的n节点,它是否可能成为最佳路径上的一点的估价,应由估价函数f(n)值来决定。

TSP问题的几种常用求解算法比较共3页

TSP问题的几种常用求解算法比较共3页

TSP问题的几种常用求解算法比较旅行商问题(Traveling Salesman Problem, TSP)是典型的组合优化问题,很多优化问题都可以直接或间接的转为为TSP问题,而且TSP问题已被证明具有NPC计算复杂性,有很大的求解难度,因此研究TSP问题的求解方法有着很大的实际意义。

本文旨在介绍求解TSP的几种常用解法,并结合实例比较这些算法的性能,为TSP的求解提供一些参考。

1 TSP问题描述TSP问题的数学表述为:一个有穷的城市集合C={C1,C2,…,Cm},对于每一对城市Ci,Cj∈C有距离d(Ci,Cj)∈R+。

问:经过C中所有城市的旅行路线,记为序列,是否存在最小的正数B,对所有可能的序列都有2 TSP问题几种常用求解方法TSP问题有着很多求解算法,主要有。

2.1 贪婪算法贪婪算法[2](Greedy algorithm)是求解大规模TSP问题的常用算法之一,是一种求解优化问题的简单、迅速的求解办法。

贪婪法有限考虑当前情况下最优的优化测度,自顶向下,逐步迭代,具有算法简单,耗时短的特点。

但贪婪算法的求解结果往往不是最优的,甚至可能与全局最优解间有不小的差距。

2.2 模拟退火算法模拟退火(Simulated Annealing,SA)算法是求解TSP问题的有效方法之一,容易编程实现,求解速度快。

模拟退火是一种全局优化算法,加入了随机状态模型,使算法以概率选择的方式逼近最优状态,其收敛性可以得到严格的理论证明。

模拟退火算法具有一整套完整的退火搜索计划,包括足够高的初始温度、缓慢的退火速度、大量的迭代次数及足够的概率扰动[3]。

2.3 遗传算法遗传算法(Genetic Algorithm,GA)是一种常用的智能算法,具有全局搜索能力,对TSP问题有良好的效果。

遗传算法是由Michigan大学的J.Holland教授于1975年提出,算法通常由编码、个体适应度评估和遗传运算三部分构成,其中遗传运算包括染色体复制、交叉、变异和倒位等[4]。

tsp问题算法

tsp问题算法

旅行商问题(traveling saleman problem,简称tsp):已知n 个城市之间的相互距离,现有一个推销员必须遍访这n 个城市,并且每个城市只能访问一次,最后又必须返回出发城市。

如何安排他对这些城市的访问次序,可使其旅行路线的总长度最短?用图论的术语来说,假设有一个图g=(v,e),其中v 是顶点集,e 是边集,设d=(dij)是由顶点i 和顶点j 之间的距离所组成的距离矩阵,旅行商问题就是求出一条通过所有顶点且每个顶点只通过一次的具有最短距离的回路。

这个问题可分为对称旅行商问题(dij=dji,,任意i,j=1,2,3,…,n)和非对称旅行商问题(dij ≠dji,,任意i,j=1,2,3,…,n)。

若对于城市v={v1,v2,v3,…,vn}的一个访问顺序为t=(t1,t2,t3,…,ti,…,tn),其中ti∈v(i=1,2,3,…,n),且记tn+1= t1,则旅行商问题的数学模型为:min l=σ d(t(i),t(i+1)) (i=1,…,n)旅行商问题是一个典型的组合优化问题,并且是一个np 难问题,其可能的路径数目与城市数目n 是成指数型增长的,所以一般很难精确地求出其最优解,本文采用遗传算法求其近似解。

遗传算法:初始化过程:用v1,v2,v3,…,vn 代表所选n 个城市。

定义整数pop-size 作为染色体的个数,并且随机产生pop-size 个初始染色体,每个染色体为1 到18 的整数组成的随机序列。

适应度f 的计算:对种群中的每个染色体vi,计算其适应度,f=σ d(t(i),t(i+1)). 评价函数eval(vi):用来对种群中的每个染色体vi 设定一个概率,以使该染色体被选中的可能性与其种群中其它染色体的适应性成比例,既通过轮盘赌,适应性强的染色体被选择产生后台的机会要大,设alpha ∈(0,1) ,本文定义基于序的评价函数为eval(vi)=alpha*(1-alpha).^(i-1) 。

TSP问题的近似算法

TSP问题的近似算法

TSP问题的近似算法近似算法是解决优化问题的一种有效方法,它可以在较短时间内得到一个接近最优解的解,而不是花费大量时间去寻找最优解。

TSP问题(Traveling Salesman Problem)是一个经典的优化问题,它的目标是找到一条经过所有城市的最短路径。

这个问题是一个经典的NP难题,意味着在合理的时间内找到准确的最优解是不可能的,最多只能得到近似解。

因此,近似算法在TSP问题中具有重要的应用价值。

常见的近似算法包括贪心算法、局部搜索算法、动态规划算法等。

下面我们将介绍其中几种经典的算法。

1. 贪心算法贪心算法是一种基于贪心策略的近似算法。

它的基本思想是每次选择当前最优解,直到得到一个接近最优解的解。

在TSP问题中,贪心算法的思路是从起点出发,每次选择距离当前城市最近的城市,直到遍历所有城市。

但是这种贪心策略往往不能得到最优解,因为它可能陷入局部最优解。

2. 局部搜索算法局部搜索算法是一种基于局部优化的近似算法。

它的基本思想是从一个随机的解出发,不断地进行局部搜索,直到得到一个接近最优解的解。

在TSP问题中,局部搜索算法的思路是从一个随机的解出发,通过交换城市的顺序来不断优化当前解,直到达到一定的迭代次数或无法继续优化为止。

这种算法的优点是效率高,缺点是易陷入局部最优解。

3. 动态规划算法动态规划算法是一种基于状态转移的近似算法。

它的基本思想是将一个复杂问题分解成若干个子问题,通过按顺序解决子问题来求解原问题。

在TSP问题中,动态规划算法通过定义状态、状态转移方程和初始状态来求解最短路径。

其时间复杂度为O(n^2*2^n),因此不适用于大规模的问题。

总结以上是常见的几种近似算法,在实际运用中可以根据问题的特点选择合适的算法。

虽然这些算法不能得到准确的最优解,但它们可以在短时间内得到一个接近最优解的解,具有重要的实际应用价值。

TSP的几种求解方法及其优缺点

TSP的几种求解方法及其优缺点

TSP的几种求解方法及其优缺点一、什么是TSP问题旅行商问题,简称TSP,即给定n个城市和两两城市之间的距离,要求确定一条经过各城市当且仅当一次的最短路线。

其图论描述为:给定图G=(V,A),其中V为顶点集,A 为各顶点相互连接组成的边集,设D=(dij)是由顶点i和顶点j之间的距离所组成的距离矩阵,要求确定一条长度最短的Hamilton回路,即遍历所有顶点当且仅当一次的最短距离。

旅行商问题可分为如下两类:1)对称旅行商问题(dij=dji,Πi,j=1,2,3,⋯,n);2)非对称旅行商问题(dij≠dji,ϖi,j=1,2,3,⋯,n)。

非对称旅行商问题较难求解,我们一般是探讨对称旅行商问题的求解。

若对于城市V={v1,v2,v3,⋯,v n}的一个访问顺序为T={t1,t2,t3,⋯,t i,⋯,t n},其中t i∈V(i=1,2,3,⋯,n),且记t n+1=t1,则旅行商问题的数学模型为:minL=。

TSP是一个典型的组合优化问题,并且是一个NP完全难题,是诸多领域内出现的多种复杂问题的集中概括和简化形式,并且已成为各种启发式的搜索、优化算法的间接比较标准。

因此,快速、有效地解决TSP有着重要的理论价值和极高的实际应用价值。

二、主要求解方法基于TSP的问题特性,构造型算法成为最先开发的求解算法,如最近邻点、最近合并、最近插入、最远插入、最近添加、贪婪插入等。

但是,由于构造型算法优化质量较差,迄今为止已开发了许多性能较好的改进型搜索算法,主要有:1)模拟退火算法2)禁忌搜索算法3)Hopfield神经网络优化算法4)蚁群算法5)遗传算法6)混合优化策略2.1模拟退火算法方法1)编码选择:采用描述TSP解的最常用的一种策略——路径编码。

2)SA状态产生函数的设计:对于基于路径编码的SA状态产生函数操作,可将其设计为:①互换操作(SW AP);②逆序操作(INV);③插入操作(INS)。

3)SA状态接受函数的设计:min{1,exp(-△/t)}>random[0,1]准则是作为接受新状态的条件最常用的方案,其中△为新旧状态的目标值差,t为”温度”。

TSP问题算法分析报告

TSP问题算法分析报告

算法第二次大作业TSP问题算法分析021251班王昱(02125029)一.问题描述“TSP问题”常被称为“旅行商问题”,是指一名推销员要拜访多个地点时,如何找到在拜访每个地点一次后再回到起点的最短路径。

TSP问题在本实验中的具体化:从A城市出发,到达每个城市并且一个城市只允许访问一次,最后又回到原来的城市,寻找一条最短距离的路径。

二.算法描述2.1分支界限法2.1.1 算法思想分支限界法常以广度优先或以最小耗费(最大效益)优先的方式搜索问题的解空间树。

在分支限界法中,每一个活结点只有一次机会成为扩展结点。

活结点一旦成为扩展结点,就一次性产生其所有儿子结点。

在这些儿子结点中,导致不可行解或导致非最优解的儿子结点被舍弃,其余儿子结点被加入活结点表中。

此后,从活结点表中取下一结点成为当前扩展结点,并重复上述结点扩展过程。

这个过程一直持续到找到所需的解或活结点表为空时为止。

2.1.2 算法设计说明设求解最大化问题,解向量为X=(x1,…,xn),xi的取值范围为Si,|Si|=ri。

在使用分支限界搜索问题的解空间树时,先根据限界函数估算目标函数的界[down, up],然后从根结点出发,扩展根结点的r1个孩子结点,从而构成分量x1的r1种可能的取值方式。

对这r1个孩子结点分别估算可能的目标函数bound(x1),其含义:以该结点为根的子树所有可能的取值不大于bound(x1),即:bound(x1)≥bound(x1,x2)≥…≥ bound(x1,…,xn)若某孩子结点的目标函数值超出目标函数的下界,则将该孩子结点丢弃;否则,将该孩子结点保存在待处理结点表PT中。

再取PT表中目标函数极大值结点作为扩展的根结点,重复上述。

直到一个叶子结点时的可行解X=(x1,…,xn),及目标函数值bound(x1,…,xn)。

2.2 A*算法算法思想对于某一已到达的现行状态, 如已到达图中的n节点, 它是否可能成为最佳路径上的一点的估价, 应由估价函数f(n)值来决定。

Tsp问题的几种算法的分析

Tsp问题的几种算法的分析

摘要本文分析比较了tsp问题的动态计划算法,分支界限法,近似等算法。

分析了旅行商问题的时刻度特点,针对启发式算法求解旅行商问题中存在的一些问题提出了改良算法。

此算法将群体分为假设干小子集,并用启发式交叉算子,以较好利用父代个体的有效信息,达到快速收敛的成效,实验说明此算法能提高寻优速度,解得质量也有所提高。

关键词:旅行商问题 TSPAbstractthis paper analyzed the time complexity of traveling salesman problem,then put forward some imprivement towards the genetic algorithm for solving this problen: divding the population into some small parent individual well.so it can quickly get into convergence, the experimental result indicates the impwoved algorithm can accelerate the apeed of finding solution and improve the precision. Keywords traveling salesman problem; genetic algorithm; subset; henristic crossover operator目录1、摘要--------------------------------------------------------------12、Abstract---------------------------------------------------------13、Tsp问题的提法------------------------------------------------24、回溯法求Tsp问题--------------------------------------------35、分支限界法求Tsp问题--------------------------------------76、近似算法求解Tsp问题-------------------------------------107、动态计划算法解Tsp问题----------------------------------12引言tsp问题刚提出时,很多人都以为很简单。

TSP的几种求解方法及其优缺点

TSP的几种求解方法及其优缺点

v1.0 可编辑可修改TSP的几种求解方法及其优缺点一、什么是TSP问题旅行商问题,简称TSP,即给定n个城市和两两城市之间的距离,要求确定一条经过各城市当且仅当一次的最短路线。

其图论描述为:给定图G=(V,A),其中V为顶点集,A为各顶点相互连接组成的边集,设D=(dij)是由顶点i和顶点j之间的距离所组成的距离矩阵,要求确定一条长度最短的Hamilton回路,即遍历所有顶点当且仅当一次的最短距离。

旅行商问题可分为如下两类:1)对称旅行商问题(dij=dji,Πi,j=1,2,3,⋯,n);2)非对称旅行商问题(dij≠dji,ϖi,j=1,2,3,⋯,n)。

非对称旅行商问题较难求解,我们一般是探讨对称旅行商问题的求解。

若对于城市V={v1,v2,v3,⋯,v n}的一个访问顺序为T={t1,t2,t3,⋯,t i,⋯,t n},其中t i∈V(i=1,2,3,⋯,n),且记t n+1=t1,则旅行商问题的数学模型为:minL=。

TSP是一个典型的组合优化问题,并且是一个NP完全难题,是诸多领域内出现的多种复杂问题的集中概括和简化形式,并且已成为各种启发式的搜索、优化算法的间接比较标准。

因此,快速、有效地解决TSP有着重要的理论价值和极高的实际应用价值。

二、主要求解方法基于TSP的问题特性,构造型算法成为最先开发的求解算法,如最近邻点、最近合并、最近插入、最远插入、最近添加、贪婪插入等。

但是,由于构造型算法优化质量较差,迄今为止已开发了许多性能较好的改进型搜索算法,主要有:1)模拟退火算法2)禁忌搜索算法3)Hopfield神经网络优化算法4)蚁群算法5)遗传算法6)混合优化策略模拟退火算法方法1)编码选择:采用描述TSP解的最常用的一种策略——路径编码。

2)SA状态产生函数的设计:对于基于路径编码的SA状态产生函数操作,可将其设计为:①互换操作(SWAP);②逆序操作(INV);③插入操作(INS)。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

T S P问题算法分析集团企业公司编码:(LL3698-KKI1269-TM2483-LUI12689-ITT289-算法第二次大作业TSP问题算法分析021251班王昱(02125029)一.问题描述“TSP问题”常被称为“旅行商问题”,是指一名推销员要拜访多个地点时,如何找到在拜访每个地点一次后再回到起点的最短路径。

TSP问题在本实验中的具体化:从A城市出发,到达每个城市并且一个城市只允许访问一次,最后又回到原来的城市,寻找一条最短距离的路径。

二.算法描述2.1分支界限法2.1.1算法思想分支限界法常以广度优先或以最小耗费(最大效益)优先的方式搜索问题的解空间树。

在分支限界法中,每一个活结点只有一次机会成为扩展结点。

活结点一旦成为扩展结点,就一次性产生其所有儿子结点。

在这些儿子结点中,导致不可行解或导致非最优解的儿子结点被舍弃,其余儿子结点被加入活结点表中。

此后,从活结点表中取下一结点成为当前扩展结点,并重复上述结点扩展过程。

这个过程一直持续到找到所需的解或活结点表为空时为止。

2.1.2算法设计说明设求解最大化问题,解向量为X=(x1,…,xn),xi的取值范围为Si,|Si|=ri。

在使用分支限界搜索问题的解空间树时,先根据限界函数估算目标函数的界[down,up],然后从根结点出发,扩展根结点的r1个孩子结点,从而构成分量x1的r1种可能的取值方式。

对这r1个孩子结点分别估算可能的目标函数bound(x1),其含义:以该结点为根的子树所有可能的取值不大于bound(x1),即:bound(x1)≥bound(x1,x2)≥…≥bound(x1,…,xn)若某孩子结点的目标函数值超出目标函数的下界,则将该孩子结点丢弃;否则,将该孩子结点保存在待处理结点表PT中。

再取PT表中目标函数极大值结点作为扩展的根结点,重复上述。

直到一个叶子结点时的可行解X=(x1,…,xn),及目标函数值bound(x1,…,xn)。

2.2A*算法算法思想对于某一已到达的现行状态,如已到达图中的n节点,它是否可能成为最佳路径上的一点的估价,应由估价函数f(n)值来决定。

假设g*(n)函数值表示从起始节点s到任意一个节点n的一条最佳路径上的实际耗散值。

h*(n)函数值表示从任意节点n到目标节点ti的最佳路径的实际耗散值。

其中ti是一个可能的目标节点。

f*(n)函数值表示从起始s,通过某一指定的n到达目标节点ti的一条最佳路径的实际耗散值,并有f*(n)=g*(n)+h*(n)。

假设f函数是对f*函数的一种估计,并有f(n)=g(n)+h(n),其中g函数是对g*的估计,h函数是对h*的一种估计。

f(n)包括两个部分,其中g(n)表示到达n节点时,已付出代价的估计;而h(n)表示从n节点到达目标节点ti将要付出代价的估计。

按f(n)=g*(n)+h*(n)的值来排序ff表的节点,f值小者优先。

通常称这种算法为A算法。

在A算法的基础上,进一步限制h(n)函数,使得搜索图中的每一个节点n,能满足h(n)<=h*(n)、称h函数取h*的下界。

这种算法叫A*算法。

对ff里的每一个节点做评估函数F分为两部分G和H:假设从A城市走到X城市,又走到Y城市,所以G可表示为:G=A到X的距离+X到Y的距离;未走的的城市数=(总城市数+1)-目前城市的层数。

为什得加1,因为最后得走回初始城市,所以总路径的城市数为总城市数+1。

H=未走的城市数×目前的最小距离;F=G+H;计算ff表里每个节点的F值,F值最小的节点作为活路径,把它加到bestpath中。

三.算法代码3.1分支界限法#include<stdio.h>#include<malloc.h>#defineNoEdge1000structMinHeapNode{intlcost;//子树费用的下界intcc;//当前费用intrcost;//x[s:n-1]中顶点最小出边费用和ints;//根节点到当前节点的路径为x[0:s]int*x;//需要进一步搜索的顶点是//x[s+1:n-1] structMinHeapNode*next;};intn;//图G的顶点数int**a;//图G的邻接矩阵//intNoEdge;//图G的无边标记intcc;//当前费用intbestc;//当前最小费用MinHeapNode*head=0;/*堆头*/MinHeapNode*lq=0;/*堆第一个元素*/ MinHeapNode*fq=0;/*堆最后一个元素*/ intDeleteMin(MinHeapNode*&E){MinHeapNode*tmp=NULL;tmp=fq;//w=fq->weight;E=fq;if(E==NULL)return0;head->next=fq->next;/*一定不能丢了链表头*/fq=fq->next;//free(tmp);return0;}intInsert(MinHeapNode*hn){if(head->next==NULL){head->next=hn;//将元素放入链表中fq=lq=head->next;//一定要使元素放到链中}else{MinHeapNode*tmp=NULL;tmp=fq;if(tmp->cc>hn->cc){hn->next=tmp;head->next=hn;fq=head->next;/*链表只有一个元素的情况*/}else{for(;tmp!=NULL;){if(tmp->next!=NULL&&tmp->cc>hn->cc){hn->next=tmp->next; tmp->next=hn;break;}tmp=tmp->next;}}if(tmp==NULL){lq->next=hn;lq=lq->next;}}return0;}intBBTSP(intv[]){//解旅行售货员问题的优先队列式分支限界法/*初始化最优队列的头结点*/head=(MinHeapNode*)malloc(sizeof(MinHeapNode));head->cc=0;head->x=0;head->lcost=0;head->next=NULL;head->rcost=0;head->s=0;int*MinOut=newint[n+1];/*定义定点i的最小出边费用*///计算MinOut[i]=顶点i的最小出边费用intMinSum=0;//最小出边费用总合for(inti=1;i<=n;i++){intMin=NoEdge;/*定义当前最小值*/for(intj=1;j<=n;j++)if(a[i][j]!=NoEdge&&/*当定点i,j之间存在回路时*/(a[i][j]<Min||Min==NoEdge))/*当顶点i,j之间的距离小于Min*/ Min=a[i][j];/*更新当前最小值*/if(Min==NoEdge)returnNoEdge;//无回路MinOut[i]=Min;//printf("%d\n",MinOut[i]);/*顶点i的最小出边费用*/ MinSum+=Min;//printf("%d\n",MinSum);/*最小出边费用的总和*/}MinHeapNode*E=0;E=(MinHeapNode*)malloc(sizeof(MinHeapNode));E->x=newint[n];//E.x=newint[n];for(inti=0;i<n;i++)E->x[i]=i+1;E->s=0;E->cc=0;E->rcost=MinSum;E->next=0;//初始化当前扩展节点intbestc=NoEdge;/*记录当前最小值*///搜索排列空间树while(E->s<n-1){//非叶结点if(E->s==n-2){//当前扩展结点是叶结点的父结点/*首先考虑s=n-2的情形,此时当前扩展结点是排列树中某个叶结点的父结点。

如果该叶结点相应一条可行回路且费用小于当前最小费用,则将该叶结点插入到优先队列中,否则舍去该叶结点*/if(a[E->x[n-2]][E->x[n-1]]!=NoEdge&&/*当前要扩展和叶节点有边存在*/a[E->x[n-1]][1]!=NoEdge&&/*当前页节点有回路*/(E->cc+a[E->x[n-2]][E->x[n-1]]+a[E->x[n-1]][1]<bestc/*该节点相应费用小于最小费用*/||bestc==NoEdge)){bestc=E->cc+a[E->x[n-2]][E->x[n-1]]+a[E->x[n-1]][1];/*更新当前最新费用*/E->cc=bestc;E->lcost=bestc;E->s++;E->next=NULL;Insert(E);/*将该页节点插入到优先队列中*/}elsefree(E->x);//该页节点不满足条件舍弃扩展结点}else{/*产生当前扩展结点的儿子结点当s<n-2时,算法依次产生当前扩展结点的所有儿子结点。

由于当前扩展结点所相应的路径是x[0:s],其可行儿子结点是从剩余顶点x[s+1:n-1]中选取的顶点x[i],且(x[s],x[i])是所给有向图G中的一条边。

对于当前扩展结点的每一个可行儿子结点,计算出其前缀(x[0:s],x[i])的费用cc和相应的下界lcost。

当lcost<bestc时,将这个可行儿子结点插入到活结点优先队列中。

*/for(inti=E->s+1;i<n;i++)if(a[E->x[E->s]][E->x[i]]!=NoEdge){/*当前扩展节点到其他节点有边存在*///可行儿子结点intcc=E->cc+a[E->x[E->s]][E->x[i]];/*加上节点i后当前节点路径*/ intrcost=E->rcost-MinOut[E->x[E->s]];/*剩余节点的和*/intb=cc+rcost;//下界if(b<bestc||bestc==NoEdge){//子树可能含最优解,结点插入最小堆MinHeapNode*N;N=(MinHeapNode*)malloc(sizeof(MinHeapNode));N->x=newint[n];for(intj=0;j<n;j++)N->x[j]=E->x[j];N->x[E->s+1]=E->x[i];N->x[i]=E->x[E->s+1];/*添加当前路径*/N->cc=cc;/*更新当前路径距离*/N->s=E->s+1;/*更新当前节点*/N->lcost=b;/*更新当前下界*/N->rcost=rcost;N->next=NULL;Insert(N);/*将这个可行儿子结点插入到活结点优先队列中*/ }}free(E->x);}//完成结点扩展DeleteMin(E);//取下一扩展结点if(E==NULL)break;//堆已空}if(bestc==NoEdge)returnNoEdge;//无回路for(inti=0;i<n;i++)v[i+1]=E->x[i];//将最优解复制到v[1:n]while(true){//释放最小堆中所有结点free(E->x);DeleteMin(E);if(E==NULL)break;}returnbestc;}intmain(){n=0;inti=0;//FILE*in,*out;//in=fopen("input.txt","r");//out=fopen("output.txt","w"); //if(in==NULL||out==NULL)//{//printf("没有输入输出文件\n"); //return1;//}//fscanf(in,"%d",&n);n=5;a=(int**)malloc(sizeof(int*)*(n+1)); for(i=1;i<=n;i++){a[i]=(int*)malloc(sizeof(int)*(n+1)); }//for(i=1;i<=n;i++)//for(intj=1;j<=n;j++)////fscanf(in,"%d",&a[i][j]);//a[i][j]=1;a[1][1]=0;a[1][2]=6;a[1][3]=1;a[1][4]=5;a[1][5]=7;a[2][1]=6;a[2][2]=0;a[2][3]=6;a[2][4]=4;a[2][5]=3;a[3][1]=1;a[3][2]=6;a[3][3]=0;a[3][4]=8;a[3][5]=2;a[4][1]=5;a[4][2]=4;a[4][3]=8;a[4][4]=0;a[4][5]=5;a[5][1]=7;a[5][2]=3;a[5][3]=2;a[5][4]=5;a[5][5]=0;//prev=(int*)malloc(sizeof(int)*(n+1));int*v=(int*)malloc(sizeof(int)*(n+1));//MaxLoading(w,c,n); for(i=1;i<=n;i++)v[i]=0;bestc=BBTSP(v);printf("\n");printf("最优路径为");for(i=1;i<=n;i++)fprintf(stdout,"%c\t",v[i]+64);fprintf(stdout,"\n");fprintf(stdout,"总路程为\n",bestc);return0;}3.2A*算法#include"stdio.h"constintmax=9999;constintax=50;intisbest(inti,intbestpath[],intp)//检测改节点是否已经加入bestpath[]中{for(intk=1;k<=p;k++){if(i==bestpath[k])break;}if(k!=p+1)//新测试节点在a[]中return1;elsereturn0;}voidmain(){intmin=max;intminf=max;intnum;//城市数量intmat[ax][ax];//城市间距离intbestpath[ax];//最佳路径intf=0,g=0,h=0;intff[ax];//依次求每个城市的f值intgg[ax];//城市的g值printf("城市个数为:");scanf("%d",&num);printf("城市间的距离为:\n");//输入各城市间距离的矩阵for(inti=0;i<num;i++)for(intj=0;j<num;j++)scanf("%d",&mat[i][j]);bestpath[0]=0;//起点为0,即城市Afor(intp=0;p<num-1;p++)//依次求每个最优节点,每次循环得到一个新的最优城市放到bestpath[]中{for(intkk=0;kk<num;kk++)ff[kk]=max;//便于后面求最小值for(i=1;i<num;i++)//起点A不算,从非起点开始找寻最优城市{if(isbest(i,bestpath,p))//该点已经在bestpath[]中的话,忽略continue;else//计算该点的g值gg[i]=g+mat[bestpath[p]][i];//i点的g值for(intm=0;m<num;m++)//开始计算h值{if(isbest(m,bestpath,p))//该点已经在bestpath[]中的话,忽略continue;for(intt=m+1;t<num;t++){if(isbest(t,bestpath,p))continue;if(m!=0||t!=i||p==num-2)//不是最后一个点的话,不算A点到这个点长度if(mat[m][t]<min)min=mat[m][t];}}h=min*(num-p-1);//h值ff[i]=gg[i]+h;//第i个节点的f值min=max;//重新赋值最大,以便下次循环}for(i=0;i<num;i++)//找寻最优点,即f值最小者{if(ff[i]<minf){minf=ff[i];bestpath[p+1]=i;}}minf=max;//重新赋值最大,以便下次循环g=g+mat[bestpath[p]][bestpath[p+1]];//更新g值}printf("最优路径为:");for(i=0;i<num;i++)printf("%c",bestpath[i]+65);printf("A\n");printf("总路程为:");intsum=0;for(i=0;i<num-1;i++)sum=sum+mat[bestpath[i]][bestpath[i+1]];sum=sum+mat[bestpath[num-1]][0];//总路程最后一个城市要回到A,所以加上其距离printf("%d\n",sum);}四.结果截图4.1分支界限法4.2A*算法。

相关文档
最新文档