最短路

来源:互联网 发布:linux怎么运行脚本 编辑:程序博客网 时间:2024/05/01 01:51


最近学习离散数学里头的图论最短路,颇感兴趣,于是自己看了一下几种相关的算法,并且打算整理总结一下。

首先是单源最短路的dijkstra算法,是采取拓展点的方式来遍历更新指标函数,每个点都只拓展一次,而且根据算法的结构看,是双重循环,假设点的个数为n,复杂度为O(n2)

了解算法之前,我们先看一下数学定义,首先设顶点全集V,我们来求从v0到z的最短路。我们先将V分成两个集合,T和P,T={ v∈V| v0到v的最短路已经求出 },P=V-T还有对于任意的顶点t∈P,设l(t)表示从v0到t的最短路径和(在只经过T中顶点的前提下),若不存在这样的路径,l(t)=∞,我们称l(t)为t关于T的指标函数。

 

还是先把算法列出来吧:

开始时遍历P中每一个顶点t,初始化令l(t)=W(vo,t)      W(x,y)表示从顶点x到顶点y的距离,如果x不能直接到y,则该值为∞

⑵找到最小点x,将x加入到T中,即T=T+{x}, P=P-{x}

⑶在拓展与x相邻的点的指标函数,因为此时满足从x走过来为最小值,如果l(t)>l(x)+W(x,t)那么修改一下l(t)=l(x)+W(x,t);

然后再继续从⑵循环知道T=V才停止

额,这里我还显示了一下路径,就是用一个string trace[i]来表示从v0 走到i的最短路径 

具体c++描述如下

int Dijkstra(int startp,int endp){int l[100];bool P[100];string trace[100];for(int i=1;i<=vertex;++i){l[i]=INF,P[i]=true;}l[startp]=0;trace[startp].append(to_string(startp));for(int i=1;i<=vertex;++i){int x,min=INF;for(int j=1;j<=vertex;++j){if(P[j] && min>l[j]){min=l[j];x=j;}}P[x]=false;for(int j=1;j<=vertex;++j){if(matrix[x][j] && P[j] && l[j]>l[x]+matrix[x][j]){l[j]=l[x]+matrix[x][j];trace[j].clear();trace[j].append(trace[x]);trace[j].append(to_string(j));}}}cout<<"dijkstra: trace=";for(int i=0;i<trace[endp].size();++i){if(!i)cout<<trace[endp][i];else cout<<"->"<<trace[endp].at(i);}cout<<endl;return l[endp];}



原创粉丝点击