
这个问题字面上的理解是:有一个推销员,要到n个城市推销商品,他要找出一个包含所有n个城市的具有最短路程的环路。
TSP的历史很久,最早的描述是1759年欧拉研究的骑士周游问题,即对于国际象棋棋盘中的64个方格,走访64个方格一次且仅一次,并且最终返回到起始点。
TSP由美国RAND公司于1948年引入,该公司的声誉以及线性规划这一新方法的出现使得TSP成为一个知名且流行的问题。
2、中国邮递员问题(Chinese Postman Problem CPP)
同样的问题,在中国还有另一个描述方法:一个邮递员从邮局出发,到所辖街道投递邮件,最后返回邮局,如果他必须走遍所辖的每条街道至少一次,那么他应如何选择投递路线,使所走的路程最短?这个描述之所以称为中国邮递员问题, 因为是我国学者管梅古谷教授于1962年提出的这个问题并且给出了一个解法。
3、“一笔画”问题(Drawing by one line)
还有一个用图论语言的描述方式:平面上有n个点,用最短的线将全部的点连起来。称为“一笔画”问题。
4、配送路线问题(Route of Distribution)
TSP问题在物流中的描述是对应一个物流配送公司,欲将n个客户的订货沿最短路线全部送到。如何确定最短路线。
TSP问题最简单的求解方法是枚举法。它的解是多维的、多局部极值的、趋于无穷大的复杂解的空间,搜索空间是n个点的所有排列的集合,大小为(n-1)!。可以形象地把解空间看成是一个无穷大的丘陵地带,各山峰或山谷的高度即是问题的极值。求解TSP,则是在此不能穷尽的丘陵地带中攀登以达到山顶或谷底的过程。
5、多回路运输问题(Vehicle Routing Problem, VRP)
多回路运输问题在物流中的解释是对一系列客户的需求点设计适当的路线,使车辆有序地通过它们,在满足一定的约束条件下,如货物需求量、发送量、交发货时间、车辆载重量限制、行驶里程限制、时间限制等等,达到一定的优化目标,如里程最短、费用最少、时间最短,车队规模最少、车辆利用率高。
VRP问题和TSP问题的区别在于:客户群体的数量大,只有一辆车或一条路径满足不了客户的需求,必须是多辆交通工具以及运输工具的行车顺序两个问题则野耐的求解。相对于TSP问题,VRP问题更复杂,求解更困难,但也更接近实际情况。
6、多个旅行商问题(Multiple TSP)
由于限制条件的增加,TSP问题可以衍生出多个旅行商问题(MTSP),就是一个出发点,m个旅行商的TSP,即所访问的客户没有需求,车辆没有装载的限制,优化目标就是要遍历所有的客户,达到总里程最短。
VRP问题是MTSP问题的普遍化,当客户的需求不仅仅是被访问,而是有一定容积和重量的商品的装载和卸载,涉及到不同种类和型号或不同载重量车辆的调度策略时,孙春MTSP问题转换为VRP问题。
7、最近邻点法(Nearest Neighbor)
这是一种用于解决TSP问题的启发式算法。方法简单,但得到的解并不十分理想,可以作为进一步优化的初始解。求解的过程一共四步:首先从零点开始,作为整个回路的起点,然后找到离刚刚加入到回路的上一节点最近的一个节点,并将其加入到回路中。重复上一步,直到所有的节点都加入到回路中,最后,将最后一个加入的节点和起点连接起来,构成了一个TSP问题的解。
8、最近插入法(Nearest Insertion)
最近插入法是另一个TSP问题的求解方法。它的求解过程也是4步:首先从一个节点出发,找到一个最近的节点,形成一个往返式子回路;在剩下的节点中,寻找一个离子回路中某一节点最近的节点,再在子回路中找到一个弧,使弧的两端节点到刚寻找到的最近节点的距离之和减去弧长的值最小,实际上就是把新找到的节点加入子回路以后使得增加的路程最短,就把这个节点增加到子回路中。重复以上过程,直到所有的节点都加入到子回路中。最近插入法比最近邻点法复杂,但可以得到相对比较满意的解脊槐。
9、节约里程法(Saving Algorithm)
节约算法是用来解决运输车辆数目不确定的VRP问题的最有名的启发式算法。它的核心思想是依次将运输问题中的两个回路合并为一个回路,每次使合并后的总运输距离减小得幅度最大,直到达到一辆车的装载限制时,再进行下一辆车的优化。优化过程分为并行方式和串行方式两种。
10、扫描算法(Sweep Algorithm)
它也是求解车辆数目不限制的VRP问题的启发式算法。求解过程同样是4步:以起始点为原点建立极坐标系,然后从最小角度的两个客户开始建立一个组,按逆时针方向将客户逐个加入到组中,直到客户的需求总量超出了车辆的载重定额。然后建立一个新的组,继续该过程,直到将全部客户都加入到组中
您好,有,来了:#include "stdio.h"
#include "math.h"
void main()
{
long x[21]={0},y[21]={0},d[191]={0},e[191]={0},g[41]={0},s[42]={0}
int i,j,h=1,k,l,o,m,n=0,p,q=3,r=0
int flag
double a[21]={0},b[21][21]={0},c[21][21]={0},f[191]={0}
char ch
printf(" C-W算法求解TSP问题 \n\n\n")
printf("请输入坐标(20个以内),坐标之间用空格隔开,按回车键结束输入:\n")
re:scanf("猛如%d,%d",&x[h],&y[h])
ch=getchar()
if(ch!='\n')
{ h++
goto re
}
for(i=1i<h+1i++)
a[i]=sqrt(x[i]*x[i]+y[i]*y[i])
for(i=1i<hi++)
{
for(j=i+1j<h+1j++)
{ n++
b[i][j]=sqrt((x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]))
c[i][j]=a[i]+a[j]-b[i][j]
d[n]=i
e[n]=j
f[n]=c[i][j]
}
}
for(i=1i<ni++)
{ flag=0
for(j=1j<n+1-ij++)
if(f[j]>f[j+1])
{ k=f[j]f[j]=f[j+1]f[j+1]=k
l=d[j]d[j]=d[j+1]d[j+1]=l
o=e[j]e[j]=e[j+1]e[j+1]=o
flag=1
}
if(flag==0)
break
}
printf("\n")
printf("节约值哗码排序:\n")
for(i=ni>0i--)
{ if(f[i]!=0)
printf("%lf(%ld,%ld)--(%ld,%ld)\n",f[i],x[d[i]],y[d[i]],x[e[i]],y[e[i]])
}
g[1]=d[n]
g[2]=e[n]
for(m=1m<枝芦启hm++)
{
for(j=n-1j>0j--)
{ p=0
for(i=1i<41i++)
{
if(d[j]==g[i])
p=p+1
if(e[j]==g[i])
p=p+1
}
if(p==1)
{ g[q]=d[j]
g[q+1]=e[j]
}
if(p==1)
break
}
q=q+2
}
printf("\n选出连接点:\n")
for(i=1i<41i=i+2)
{ if(g[i]!=0)
{
printf("(%ld,%ld)--(%ld,%ld)\n",x[g[i]],y[g[i]],x[g[i+1]],y[g[i+1]])
r=r+2
}
}
s[21]=g[1]
s[22]=g[2]
for(i=3i<ri=i+2)
for(j=1j<42j++)
{
if(g[i]==s[j])
{
if(s[j-1]==0)
s[j-1]=g[i+1]
else
s[j+1]=g[i+1]
break
}
if(g[i+1]==s[j])
{
if(s[j-1]==0)
s[j-1]=g[i]
else
s[j+1]=g[i]
break
}
}
printf("\n旅行商路线:\n")
printf("(0,0)--")
for(i=1i<42i++)
{
if(s[i]!=0)
printf("(%ld,%ld)--",x[s[i]],y[s[i]])
}
printf("(0,0)")
getch()
}
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)