图论最短路径选址问题.docx
《图论最短路径选址问题.docx》由会员分享,可在线阅读,更多相关《图论最短路径选址问题.docx(12页珍藏版)》请在冰点文库上搜索。
图论最短路径选址问题
姓名:
之宇文皓月创作
学号:
专业:
图论的实际应用——蔬菜批发市场选址问题
摘要:
在现实生活和生产实践中,有许多管理、组织与计划中的优化问题,都可借助图论知识得以解决,而最短路问题是利用图论解决的一个典型的实际问题。
图论中最典型的两种求最短路径的算法分别为Dijkstra算法和Floyd算法,其中Floyd算法广泛应用于求任意两点间的最短路径。
本文介绍了利于Floyd算法来解决城市蔬菜批发市场选址的问题。
关键词:
最短路;Floyd算法;选址问题
0.引言
对于许多地理问题,当它们被抽象为图论意义下的网络图时,问题的核心就酿成了网络图上的优化计算问题。
其中,最为罕见的是关于路径和顶点的优选计算问题[5]。
在路径的优选计算问题中,最罕见的是最短路径问题,最短路径可能是给定两点间的最短路径,也可能是任意各点间的最短路径。
而在顶点的优选计算问题中,最为罕见的是选址问题,所谓选址问题就是在某一地理区域构成的网络中选择一个顶点,建立服务设施,为该网络中的各个点提供服务,使得服务效率最高[3]。
选址问题,在规划建设中经常可以碰到,这里所谓的服务设施,可以是某些公共服务设施,如医院,消防站,物流中心等。
也可以是生产服务设施,如仓库,转运站等等。
可以认为,选址问题,就是把服务设施与服务对象,反映与统一的网络中,便于对问题进行研究[4]。
尽管对选址的目标、要求有分歧的评判尺度,但是要求服务对象与服务设施之间易于沟通、易于达到,这是一个最基本的要求。
1.最短路径问题
最短路径问题是图论研究的一个经典算法问题,其目的是求出给定两点之间的长最短的路径,这里所说的长具有广泛意义,即可指普通意义的距离,也可是时间或费用等[2]。
因此,最短路径问题通常可以归纳为三类:
(1)距离意义上的最短路径,即求两点间距离最短的路径;
(2)经济意义上的最短路径,即为两点间的费用最少的路径;(3)时间意义上的最短路径,即选择两点间最节省时间的路径。
以上三类问题,都可以抽象为同一类问题,即带权图上的最短路径问题。
分歧意义下的距离都可以被抽象为网络图中边的权值,权值既可以代表“纯距离”,又可以代表“经济距离”,还可以代表“时间距离”。
1.1Dijkstra算法
Dijkstra算法是一种求解最短路径方法。
它是一个按路径长度递增的顺序发生最短路径的算法,其基本思想是:
设图中所有顶点集合为V,另设置两个顶点集合S和T=V-S,集合S中存放已找到最短路径的顶点,集合T存放当前还未找到最短路径的顶点。
初始状态时,集合S中只包含源点V1,然后不竭从集合T中选取到顶点V1的路径长度最短顶点Vi加入到集合S中,集合S每加入一个新的顶点Vi,都要修改顶点V1到集合T中剩余顶点的最短路径长度值,此过程不竭重复,直到集合T中的顶点全部加入到S中为止。
这样,就可以求出一点到其它的任一顶点的最短路径。
Dijkstra算法简单易懂,在求给定两点间的最短距离时效率很高,但是其只能求图中一个特定结点到其他各个结点的最短路[1]。
当需要求出图中任意两顶点的最短路径时,就需要以图中的每个顶点为起点,依次求出到另外顶点的最短路径,在顶点数目比较多的情况下,其效率将非常低下。
1.2Floyd算法
Floyd算法为另外一种求最短路径的算法。
在某些问题中,需要求出图中任意两顶点之间的最短路径,这时,Floyd算法将比Dijkstra算法具有明显优势。
Floyd算法借助于权矩阵的运算直接可以求出任意两点之间的最短路径[2]。
Floyd算法的实现思路为:
首先定义赋权图的边权矩D=[dij)]nxn,即dij=w(i,j),若结点i到j无边相连时,则去dij=∞。
然后依次计算出矩阵D[2],D[3],…,D[n]。
其中D[2]=D*D=(d[2]ij)nxn,d[2]ij=min{di1+d1j,di2+d2j,…,din+dnj}暗示从vi出发两步可以到达vj的道路中距离最短者;D[k]=(d[k]ij)nxn,d[k]ij暗示从vi出发k步可以到达vj的道路距离中最短路径。
D[n]=D[n-1]*D=(d[n]ij)nxn
S=D
D[2]
D[3]
…
D[n]=(Sij)nxn
由定义可知d暗示从结点i到j经过k边的路(在有向图中即为有向路)中的长度最短者,而Sij为结点i到j的所有路中的长度最短者。
2.最短路径问题在蔬菜批发市场中的应用
河南某城市市政管理部分决定新建一个蔬菜批发市场,为周边的几个小区的菜市场集中供应新鲜蔬菜。
由于蔬菜水果容易蜕变,小区菜市场的商贩必须在每天早晨把蔬菜从批发市场运送回店铺,这就要求批发市场的地址不克不及距离小区太远。
该城市管理部分经过征求意见后,决定将批发市场建在其中的一个小区旁边,现在的问题是该将此批发市场建在那个小区才干使最远的小区距离该批发市场距离最短。
2.1分析问题并建立模型
已知该城市的小区位置及相互连通道路分布示意图如图1所示,其中结点v1,v2,v3,v4,v5,v6,v7暗示七个小区,结点间的数字暗示小区间的距离。
25
图1小区位置分布示意图
由上面的小区位置及道路分布图可知,若找一个合适的小区来建造批发市场,使该小区到其它小区的最远距离最短,即求无向简单图图1中的一点,使该点到其它点的最大值为最小。
为此,我们可以使用Floyd算法来求解问题。
首先根据图1画出对应的权矩阵D:
∞30∞∞∞∞∞
30∞20∞∞15∞
∞20∞206025∞
D=∞∞20∞3018∞
∞7∞3∞∞∞
∞152518∞∞15
∞∞∞∞∞15∞
2.2Floyd算法求各点间最短路径
通过7阶加权简单图的权矩阵D,分别算出矩阵D[2],D[3],D[4],D[5],D[6],D[7],然后求出最短路矩阵S,S如下:
则可得出矩阵S中v1,v2,v3,v4,v5,v6,v7结点到其它个结点的最长距离分别为93,63,50,63,93,48,63,即v6结点到其它结点有最短路径。
由以上结论知,将蔬菜批发市场应该建在小区v6处才最为合理,使得最远的小区菜市场距批发市场的距离最短。
3.编程实现
以下为使用C++语言实现的Floyd算法的核心代码:
#include
#defineMaxInt10000//最大数
constintMaxNumEdges=50;
constintMaxNumVertices=10;//最大顶点数
classGraph
{
private:
intvNum;//当前顶点数
inteNum;//当前边数
intVertex[MaxNumVertices];//顶点数组
intEdge[MaxNumVertices][MaxNumVertices];//边数组
boolGetVertexPos(constint&vertex,int&i);//给出顶点vertex在图中的位置
public:
Graph(constintsz=MaxNumEdges);//构造函数
boolFindVertex(constint&vertex);
boolInsertVertex(constint&vertex);//拔出一个顶点vertex
boolInsertEdge(constintv1,constintv2,constintweight);//拔出一条边(v1,v2),该边上的权值为weight
voidHospital();//选址函数
};
Graph:
:
Graph(constintsz):
vNum(0),eNum(0)
//构造函数
{
intn,e;
intname,tail,head;
intweight;
for(inti=0;ifor(intj=0;j{
if(i==j)
Edge[i][j]=0;//顶点到自身权值为0
else
Edge[i][j]=10000;//邻接矩阵初始化为最大值
}
printf("请输入顶点数,注意本程序最多为10个!
\n");
scanf("%d",&n);
printf("请依次输入顶点名称:
\n");
for(intr=0;r{
scanf("%d",&name);
InsertVertex(name);
vNum++;
}
printf("请输入边数:
\n");
scanf("%d",&e);
printf("以下输入边信息:
\n");
for(intk=0;k{
printf("请输入第%d边头顶点:
\n",k+1);
scanf("%d",&head);
printf("请输入该边尾顶点:
\n");
scanf("%d",&tail);
printf("请输入该边权值:
\n");
scanf("%d",&weight);
if(!
InsertEdge(head,tail,weight))
{
printf("不存在该边,请重输!
\n");
continue;
}
}
}
boolGraph:
:
FindVertex(constint&vertex)
//给出顶点vertex在图中的位置
{
for(inti=0;iif(vertex==Vertex[i])
returntrue;
returnfalse;
}
boolGraph:
:
GetVertexPos(constint&vertex,int&i)
//给出顶点vertex在图中的位置
{
for(i=0;iif(vertex==Vertex[i])
returntrue;
returnfalse;
}
boolGraph:
:
InsertVertex(constint&vertex)
//拔出一个顶点vertex
{
if(FindVertex(vertex))
returnfalse;
Vertex[vNum]=vertex;
returntrue;
}
boolGraph:
:
InsertEdge(constintv1,constintv2,constintweight)
//拔出一条边(v1,v2),该边上的权值为weight
{
intk=0,j=0;
if(GetVertexPos(v1,k)&&GetVertexPos(v2,j))
{
Edge[k][j]=weight;
eNum++;
Edge[j][k]=weight;
eNum++;
returntrue;
}
else
returnfalse;
}
voidGraph:
:
Hospital()
//在以邻接带权矩阵暗示的n个小区中,求批发市场建在何处,使离市场距离最远的小区到达市场的路径最短。
{
intk,i,j,s;
for(k=0;kfor(i=0;ifor(j=0;jif(Edge[i][k]+Edge[k][j]Edge[i][j]=Edge[i][k]+Edge[k][j];
intm=MaxInt;//设定m为机器内最大整数。
printf("********************************************\n");
//以下为求各小区离批发市场最近的选址
intmin=MaxInt;//设定机器最大数作小区间距离之和的初值。
k=0;//k设小区位置。
for(j=0;j{
m=0;
for(i=0;iif(min>m)
{
min=m;
k=j;
}//取顶点间的距离之和的最小值。
}//for
printf("各小区离批发市场最近的选址,要建批发市场的小区为:
%d\n",k+1);//输出要建批发市场的小区编号
for(j=0;jif(j!
=k)
printf("该小区离%d小区最短距离为:
%d\n",j+1,Edge[k][j]);
}//算法结束
intmain()
{
GraphTown(MaxNumVertices);
Town.Hospital();
return0;
}
运行程序,并将2.1中的加权矩阵D的数值输入程序,得到的程序运行的结果如图2所示:
25
图2程序运行结果图
对图2中结果分析知,将批发市场建在V6小区,使得到其它6个小区的最长距离为48。
结果和2.2中的矩阵S的计算结果相同。
4.总结
通过利用学习到的Floyd算法解决了一个城市蔬菜批发市场的选址问题,我认识到最短路径问题在现实生活中的巨大作用,它可以广泛应用于建筑物选址,厂区规划等实际问题,用此方法可得到最好的解决方案。
参考文献
[1]殷剑宏,吴开亚.基于图论及其算法[M].合肥:
中国科学技术大学出版社,2005:
63-75.
[2]张清华.图论及其应用[M].北京:
清华大学出版社,2012:
87-95.
[3]胡桔洲.Floyd最短路径算法在配送中心选择中的应用[J].湖南农业大学学报,2004(08):
51-75
[4]毕亚君,王晓威.网络图中任意两点间最短路径问题的计算机实现[J].科技资讯,2006(06):
32-34.
[5]叶玉萍.最短路径在中心选址中的应用研究[J].电脑与信息技术,2012(08):
8-12.