当前位置:服务支持 >  软件文章 >  用Maple求解旅行推销员问题:算法与实现步骤

用Maple求解旅行推销员问题:算法与实现步骤

阅读数 3
点赞 0
article_banner

题记: 

       在中国,就数学软件使用者数目而言, Matlab 一直是占领着高地。这与 Matlab 优秀的数值计算和处理大数据的能力密不可分,还有一个关键原因就是中国用户多,交流环境良好。尺有所长,寸有所短,对于数学软件而言也是如此。比如就符号计算能力而言,Matlab显得相对不足,这时候恐怕要推荐一下 Maple或者 Mathematica。在使用软件的过程中,笔者发现很多人拿着一方的优势去有意贬低另外一个软件的不足,我认为大可不必,作为使用者不必拘泥,可以依据实际情况各取所需,为我所用。

    本文就抛转引玉,介绍下maple软件通用的一些使用方法,以及使用Maple 求解旅行推销员相关问。Maple 是1982年加拿大Waterloo大学开发的一个符号运算和数值计算软件平台。之后几乎每年都进行发布新版本,目前最新的版本是2019年三月发布的Maple 2019。它在处理数学相关问题相当出色和专业。结合Maple软件学习数学也会增加相应的乐趣。

首先这里针对Maple初学者可能遇到疑惑的点解释一下:为什么有的命令输入可以起作用,有的命令明明输入了怎么也不起作用。

比如想画一个各占1/3的饼状图。我们查到命令: PieChart([1, 2, 3])。输入之,很不幸你将会看到原样输出。这是为什么?

原因分析: Maple将一些专业性较强的关联紧密的函数命令集成到各种包里。如线性代数相关的 (典型的如求特征值,行列式) 就放到LinearAlgebra 包里,统计相关的就放在Statistics 包里。你使用内置命令之前需要查帮助文档(输入相关命令按F2)看看是不是在某个包里。上面说的函数PieChart 就在Statistics 包里。最直接的办法是添加with( Statistics): 效果图如下:

1.png

用Maple求解旅行推销员问题的图2

言归正传,图是一类重要的数据结构,图论是研究图的一门学科。可以利用Maple进行图论的研究。当然也有的人用其绘制精美的图论里的图。注意:Maple 里的图不支持含重边和环边。

图论相关的放在GraphTheory 和 SpecialGraphs 包里,分别有197和 79 个函数命令。 还有一个是networks 包,不过这个包已经停止更新和维护,属于将被弃用的状态。Maple之所以保留并可以使用,估计Maple开发者有恋旧的美好情怀。

旅行推销员问题 (英语:travelling salesman problem, TSP)是这样一个问题:给定一系列城市和每对城市之间的距离,求解访问每一座城市一次并回到起始城市的最短回路。它是组合优化中的一个NP困难问题,在运筹学理论计算机科学中非常重要。

一个判定问题(答案只有是或者否)属于NP 当且仅当这个问题是非确定型多项式时间可计算的。若NP问题类任何一个问题均可在多项式时间内转成问题A, 称 问题A 是NP 困难问题。说句人话就是这个问题本身比较复杂,随着问题规模越大,即使再强大的计算机也几乎无法求解。这时候规模大时候往往寻求近似解。

旅行推销员问题在图论中的一个等价形式是:给定一个加权完全图(顶点表示城市,边表示道路,权重就会是道路的成本或距离), 求一权值最小的哈密尔顿回路

下面举一个现在看起来疯狂的例子。

大学毕业生小张准备骑自行车进行毕业旅行,出发地武汉,到南京,成都,合肥,西安,四个城市旅游,最后回到武汉。模型假设我们将五个城市视为图的5个定点,他们的直接距离是图的权重。上面城市分别记为1,2,3,4,5.

首先我们可以利用Wolfram Mathematica 联网功能一次性求出它们之间的距离。

2.png

用Maple求解旅行推销员问题的图4

我们利用上面的距离数据在 Maple 里通过下列方式构建下面的图:

restart;

with(GraphTheory):               

 # 5个城市, 问题归结于在一个完全赋权图找一个最优Hamilton 圈.   

distanceofcities:= Matrix(5, {(1, 2) = 459.149, (1, 3) = 977.647, 

(1, 4) =319.501,(1,5)=649.843,(2,3)=1406.79,(2,4)=143.539,(2,5)=953.511, 

(3,4)= 1264.16,(3,5)=604.452,(4,5)=827.082 }, fill = 0, shape = symmetric):                                           # 定义赋权矩阵distanceofcities

travelcities:=Graph(distanceofcities):    # 通过赋权矩阵构成的完全赋权无向图travelcities

DrawGraph(travelcities,stylesheet= [vertexborder = false, vertexpadding = 15,edgecolor="blue", vertexcolor="Gold",

edgethickness=5], font=["Courier",10], size=[400,400]); 

3.png

然后利用内置命令求解:

t:=time[real]():

TravelingSalesman(travelcities);s

'time'=time[real]()-t; #记录运行时间

运行结果如下:

4.png

(*结果解读如下:选择路线为武汉->合肥->南京->西安->成都->武汉,总行程2998.65公里。运行时间是0.051秒。*)

如果此时我们将城市扩大到10个,并考虑有时候由于地理条件的诸多原因两地往返的路选择未必一样。也就是往返选择的路的距离未必一致,这时侯考虑的就是有向图了。Maple 照样可以处理。

n:=10:

A1:= Matrix(n, (i,j)->`if`(i=j,0,n*(n-i)^4+2*j+(n-i)^2+j^3));

# A1 赋权矩阵

G1:=Graph(A1):

t:=time[real]():

TravelingSalesman(G1);

'time'=time[real]()-t;

运行结果是

5.png

这时我们会发现内置命令为56.79300 秒,时间已经算多的了,有人会问我们有希望自己编写的代码比内置命令更节省时间吗?很多情况的确是可以幸运地做到的。下面的方面是把每个路线方法(共 10!/2= 1814400 种)进行比较。从方法上感觉很笨。

n:=10:

P:=Iterator:-Permute([seq(2..n)]): 

cmin:=infinity:  ord:= <"none">:                                      

for  v in P do     

  f:=add(A1[v[k],v[k+1]],k=1..n-2) + A1[1,v[1]]+A1[v[n-1],1];

  if f<cmin then cmin:=f; ord:=copy(v) fi;

od:

cmin;tour:=[1, entries(ord,'nolist',indexorder),1];

'time'=time[real]()-t; 

HighlightTrail(G1, tour, red);

DrawGraph(G1, style = circle);

运行结果如下:

用Maple求解旅行推销员问题的图8

 

6.jpg 

得到了相同的结果,但是令人惊讶的是时间却是1.775秒,远远小于内置方法。 其中原因估计有二:第一我们没有采用真正意义上的暴力计算,而是巧妙地采用所谓惰性计算方法-迭代,这里主要体现在:

P:=Iterator:-Permute([seq(2..n)]): 。

第二点,我们考察 Maple 里TravelingSalesman 函数帮助文档用的什么算法,可以看到如下文字: The algorithm is a branch-and-bound algorithm using the Reduce bound (see Kreher and Stinson, 1999).

于是我们知道主要采用分支定界算法,这个方法有时候搞不好枝搞地很多,将会花费很多时间去剪枝,有时候反而不如直接比较的方法来的快。所以说我们也不能过度依赖内置函数去处理问题,而是依据实际情况进行合理的处理。

至于较大规模的旅行销售员问题的近似计算,有兴趣地找找相关文献读读。

最后,如果大家有matlab/maple/mathematica相关算法问题,可以通过我们的微信公众号联系我们。

微信公众号:320科技工作室。


免责声明:本文系网络转载或改编,未找到原创作者,版权归原作者所有。如涉及版权,请联系删
相关文章
QR Code
微信扫一扫,欢迎咨询~

联系我们
武汉格发信息技术有限公司
湖北省武汉市经开区科技园西路6号103孵化器
电话:155-2731-8020 座机:027-59821821
邮件:tanzw@gofarlic.com
Copyright © 2023 Gofarsoft Co.,Ltd. 保留所有权利
遇到许可问题?该如何解决!?
评估许可证实际采购量? 
不清楚软件许可证使用数据? 
收到软件厂商律师函!?  
想要少购买点许可证,节省费用? 
收到软件厂商侵权通告!?  
有正版license,但许可证不够用,需要新购? 
联系方式 155-2731-8020
预留信息,一起解决您的问题
* 姓名:
* 手机:

* 公司名称:

姓名不为空

手机不正确

公司不为空