最短路径的Dijkstra算法及Matlab程序

合集下载

C语言迪杰斯特拉实现最短路径算法

C语言迪杰斯特拉实现最短路径算法

C语言迪杰斯特拉实现最短路径算法迪杰斯特拉(Dijkstra)算法是一种用于在加权图中寻找从起点到终点的最短路径的算法。

它使用贪心算法的原理,每次选择权重最小的边进行扩展,直到找到终点或者无法扩展为止。

下面是C语言中迪杰斯特拉算法的实现。

```c#include <stdio.h>#include <stdbool.h>//定义图的最大节点数#define MAX_NODES 100//定义无穷大的距离#define INFINITY 9999//自定义图的结构体typedef structint distance[MAX_NODES][MAX_NODES]; // 节点间的距离int numNodes; // 节点数} Graph;//初始化图void initGraph(Graph* graph)int i, j;//设置所有节点之间的初始距离为无穷大for (i = 0; i < MAX_NODES; i++)for (j = 0; j < MAX_NODES; j++)graph->distance[i][j] = INFINITY;}}graph->numNodes = 0;//添加边到图void addEdge(Graph* graph, int source, int destination, int weight)graph->distance[source][destination] = weight;//打印最短路径void printShortestPath(int* parent, int node)if (parent[node] == -1)printf("%d ", node);return;}printShortestPath(parent, parent[node]);printf("%d ", node);//执行迪杰斯特拉算法void dijkstra(Graph* graph, int source, int destination) int i, j;//存储起点到各个节点的最短距离int dist[MAX_NODES];//存储当前节点的父节点int parent[MAX_NODES];//存储已访问的节点bool visited[MAX_NODES];//初始化所有节点的距离和父节点for (i = 0; i < graph->numNodes; i++)dist[i] = INFINITY;parent[i] = -1;visited[i] = false;}//设置起点的距离为0dist[source] = 0;//寻找最短路径for (i = 0; i < graph->numNodes - 1; i++)int minDist = INFINITY;int minNode = -1;//选择距离最小的节点作为当前节点for (j = 0; j < graph->numNodes; j++)if (!visited[j] && dist[j] < minDist)minDist = dist[j];minNode = j;}}//标记当前节点为已访问visited[minNode] = true;//更新最短距离和父节点for (j = 0; j < graph->numNodes; j++)if (!visited[j] && (dist[minNode] + graph->distance[minNode][j]) < dist[j])dist[j] = dist[minNode] + graph->distance[minNode][j];parent[j] = minNode;}}}//打印最短路径及距离printf("Shortest Path: ");printShortestPath(parent, destination);printf("\nShortest Distance: %d\n", dist[destination]); int maiGraph graph;int numNodes, numEdges, source, destination, weight;int i;//初始化图initGraph(&graph);//输入节点数和边数printf("Enter the number of nodes: ");scanf("%d", &numNodes);printf("Enter the number of edges: ");scanf("%d", &numEdges);graph.numNodes = numNodes;//输入边的信息for (i = 0; i < numEdges; i++)printf("Enter source, destination, and weight for edge %d: ", i + 1);scanf("%d %d %d", &source, &destination, &weight);addEdge(&graph, source, destination, weight);}//输入起点和终点printf("Enter the source node: ");scanf("%d", &source);printf("Enter the destination node: ");scanf("%d", &destination);//执行迪杰斯特拉算法dijkstra(&graph, source, destination);return 0;```上述代码中,我们首先定义了一个图的结构体,里面包括节点间的距离矩阵和节点数。

11基于遗传算法的机器人路径规划MATLAB源代码

11基于遗传算法的机器人路径规划MATLAB源代码

基于遗传算法的机器人路径规划MATLAB源代码基本思路是:取各障碍物顶点连线的中点为路径点,相互连接各路径点,将机器人移动的起点和终点限制在各路径点上,利用最短路径算法来求网络图的最短路径,找到从起点P1到终点Pn的最短路径。

上述算法使用了连接线中点的条件,因此不是整个规划空间的最优路径,然后利用遗传算法对找到的最短路径各个路径点Pi (i=1,2,…n)调整,让各路径点在相应障碍物端点连线上滑动,利用Pi= Pi1+ti×(Pi2-Pi1)(ti∈[0,1] i=1,2,…n)即可确定相应的Pi,即为新的路径点,连接此路径点为最优路径。

function [L1,XY1,L2,XY2]=JQRLJGH(XX,YY)%% 基于Dijkstra和遗传算法的机器人路径规划% GreenSim团队——专业级算法设计&代写程序% 欢迎访问GreenSim团队主页→/greensim%输入参数在函数体内部定义%输出参数为% L1 由Dijkstra算法得出的最短路径长度% XY1 由Dijkstra算法得出的最短路径经过节点的坐标% L2 由遗传算法得出的最短路径长度% XY2 由遗传算法得出的最短路径经过节点的坐标%程序输出的图片有% Fig1 环境地图(包括:边界、障碍物、障碍物顶点之间的连线、Dijkstra的网络图结构)% Fig2 由Dijkstra算法得到的最短路径% Fig3 由遗传算法得到的最短路径% Fig4 遗传算法的收敛曲线(迄今为止找到的最优解、种群平均适应值)%% 画Fig1figure(1);PlotGraph;title('地形图及网络拓扑结构')PD=inf*ones(26,26);for i=1:26for j=1:26if D(i,j)==1x1=XY(i,5);y1=XY(i,6);x2=XY(j,5);y2=XY(j,6);dist=((x1-x2)^2+(y1-y2)^2)^0.5;PD(i,j)=dist;endendend%% 调用最短路算法求最短路s=1;%出发点t=26;%目标点[L,R]=ZuiDuanLu(PD,s,t);L1=L(end);XY1=XY(R,5:6);%% 绘制由最短路算法得到的最短路径figure(2);PlotGraph;hold onfor i=1:(length(R)-1)x1=XY1(i,1);y1=XY1(i,2);x2=XY1(i+1,1);y2=XY1(i+1,2);plot([x1,x2],[y1,y2],'k');hold onendtitle('由Dijkstra算法得到的初始路径')%% 使用遗传算法进一步寻找最短路%第一步:变量初始化M=50;%进化代数设置N=20;%种群规模设置Pm=0.3;%变异概率设置LC1=zeros(1,M);LC2=zeros(1,M);Yp=L1;%第二步:随机产生初始种群X1=XY(R,1);Y1=XY(R,2);X2=XY(R,3);Y2=XY(R,4);for i=1:Nfarm{i}=rand(1,aaa);end% 以下是进化迭代过程counter=0;%设置迭代计数器while counter<M%停止条件为达到最大迭代次数%% 第三步:交叉%交叉采用双亲双子单点交叉newfarm=cell(1,2*N);%用于存储子代的细胞结构Ser=randperm(N);%两两随机配对的配对表A=farm{Ser(1)};%取出父代AB=farm{Ser(2)};%取出父代BP0=unidrnd(aaa-1);%随机选择交叉点a=[A(:,1:P0),B(:,(P0+1):end)];%产生子代ab=[B(:,1:P0),A(:,(P0+1):end)];%产生子代bnewfarm{2*N-1}=a;%加入子代种群newfarm{2*N}=b;for i=1:(N-1)A=farm{Ser(i)};B=farm{Ser(i+1)};newfarm{2*i}=b;endFARM=[farm,newfarm];%新旧种群合并%% 第四步:选择复制SER=randperm(2*N);FITNESS=zeros(1,2*N);fitness=zeros(1,N);for i=1:(2*N)PP=FARM{i};FITNESS(i)=MinFun(PP,X1,X2,Y1,Y2);%调用目标函数endfor i=1:Nf1=FITNESS(SER(2*i-1));f2=FITNESS(SER(2*i));if f1<=f2elsefarm{i}=FARM{SER(2*i)};fitness(i)=FITNESS(SER(2*i));endend%记录最佳个体和收敛曲线minfitness=min(fitness);meanfitness=mean(fitness);if minfitness<Yppos=find(fitness==minfitness);Xp=farm{pos(1)};Yp=minfitness;endif counter==10PPP=[0.5,Xp,0.5]';PPPP=1-PPP;X=PPP.*X1+PPPP.*X2;Y=PPP.*Y1+PPPP.*Y2;XY2=[X,Y];figure(3)PlotGraph;hold onfor i=1:(length(R)-1)x1=XY2(i,1);y1=XY2(i,2);x2=XY2(i+1,1);y2=XY2(i+1,2);plot([x1,x2],[y1,y2],'k');hold onendtitle('遗传算法第10代')hold onfor i=1:(length(R)-1)x1=XY1(i,1);y1=XY1(i,2);x2=XY1(i+1,1);y2=XY1(i+1,2);plot([x1,x2],[y1,y2],'k','LineWidth',1);hold onendendif counter==20PPP=[0.5,Xp,0.5]';PPPP=1-PPP;X=PPP.*X1+PPPP.*X2;Y=PPP.*Y1+PPPP.*Y2;XY2=[X,Y];figure(4)PlotGraph;hold onfor i=1:(length(R)-1)x1=XY2(i,1);y2=XY2(i+1,2);plot([x1,x2],[y1,y2],'k');hold onendtitle('遗传算法第20代')hold onx1=XY1(i,1);y1=XY1(i,2);x2=XY1(i+1,1);y2=XY1(i+1,2);plot([x1,x2],[y1,y2],'k','LineWidth',1);hold onendendif counter==30PPP=[0.5,Xp,0.5]';PPPP=1-PPP;X=PPP.*X1+PPPP.*X2;Y=PPP.*Y1+PPPP.*Y2;XY2=[X,Y];figure(5)PlotGraph;hold onfor i=1:(length(R)-1)x1=XY2(i,1);y1=XY2(i,2);x2=XY2(i+1,1);y2=XY2(i+1,2);plot([x1,x2],[y1,y2],'k');hold onendtitle('遗传算法第30代')hold onfor i=1:(length(R)-1)x1=XY1(i,1);y2=XY1(i+1,2);plot([x1,x2],[y1,y2],'k','LineWidth',1);hold onendendif counter==40PPP=[0.5,Xp,0.5]';PPPP=1-PPP;X=PPP.*X1+PPPP.*X2;Y=PPP.*Y1+PPPP.*Y2;XY2=[X,Y];figure(6)PlotGraph;hold onx1=XY2(i,1);y1=XY2(i,2);x2=XY2(i+1,1);y2=XY2(i+1,2);plot([x1,x2],[y1,y2],'k');hold onendtitle('遗传算法第40代')hold onfor i=1:(length(R)-1)x1=XY1(i,1);y1=XY1(i,2);x2=XY1(i+1,1);y2=XY1(i+1,2);plot([x1,x2],[y1,y2],'k','LineWidth',1);hold onendendif counter==50PPP=[0.5,Xp,0.5]';PPPP=1-PPP;X=PPP.*X1+PPPP.*X2;Y=PPP.*Y1+PPPP.*Y2;XY2=[X,Y];figure(7)PlotGraph;hold onfor i=1:(length(R)-1)x1=XY2(i,1);y1=XY2(i,2);x2=XY2(i+1,1);y2=XY2(i+1,2);plot([x1,x2],[y1,y2],'k');hold onendtitle('遗传算法第50代')hold onfor i=1:(length(R)-1)x1=XY1(i,1);y1=XY1(i,2);x2=XY1(i+1,1);y2=XY1(i+1,2);plot([x1,x2],[y1,y2],'k','LineWidth',1);hold onendendLC2(counter+1)=Yp;LC1(counter+1)=meanfitness;%% 第五步:变异for i=1:Nif Pm>rand&&pos(1)~=iAA=farm{i};AA(POS)=rand;farm{i}=AA;endendcounter=counter+1;disp(counter);end%% 输出遗传算法的优化结果PPP=[0.5,Xp,0.5]';PPPP=1-PPP;X=PPP.*X1+PPPP.*X2;Y=PPP.*Y1+PPPP.*Y2;XY2=[X,Y];L2=Yp;%% 绘制Fig3figure(8)PlotGraph;hold onhold onfor i=1:(length(R)-1)x1=XY1(i,1);y1=XY1(i,2);x2=XY1(i+1,1);y2=XY1(i+1,2);plot([x1,x2],[y1,y2],'k','LineWidth',1);hold onendfor i=1:(length(R)-1)x1=XY2(i,1);y1=XY2(i,2);x2=XY2(i+1,1);y2=XY2(i+1,2);plot([x1,x2],[y1,y2],'k');hold onendtitle('遗传算法最终结果')figure(9)PlotGraph;hold onfor i=1:(length(R)-1)x1=XY1(i,1);y1=XY1(i,2);x2=XY1(i+1,1);y2=XY1(i+1,2);plot([x1,x2],[y1,y2],'k','LineWidth',1);hold onendhold onfor i=1:(length(R)-1)x1=XY2(i,1);y1=XY2(i,2);x2=XY2(i+1,1);y2=XY2(i+1,2);plot([x1,x2],[y1,y2],'k','LineWidth',2);hold onendtitle('遗传算法优化前后结果比较')%% 绘制Fig4figure(10);plot(LC1);hold onplot(LC2);xlabel('迭代次数');title('收敛曲线');源代码运行结果展示。

最短路径算法(dijkstra)经典例题

最短路径算法(dijkstra)经典例题

最短路径算法(dijkstra)经典例题
以下是一个经典的最短路径算法(dijkstra)的例题:
假设有一张地图,如下所示:
```
A--2--B
| |
4 3
| |
C--5--D
```
其中,A、B、C、D代表地点,数字代表两个地点之间的距离。

从A出发,要求找到到达D的最短路径。

首先,我们需要初始化节点的距离。

假设A节点的距离初始
为0,其他节点的距离初始为无穷大。

1. 选择起始节点A,并将其距离设为0。

2. 从A开始,计算A的邻居节点的距离。

B距离为2,C距离
为4。

3. 选择距离最小的节点,即B。

将B的距离设为已知最小距离,并标记为已访问。

4. 计算B的邻居节点C和D的距离。

C距离为6,D距离为5。

5. 选择距离最小的节点,即D。

将D的距离设为已知最小距离,并标记为已访问。

6. 计算D的邻居节点C的距离。

C距离为7。

7. 选择距离最小的节点,即C。

将C的距离设为已知最小距离,并标记为已访问。

8. 计算C的邻居节点B和D的距离。

B距离为9,D距离为12。

9. 选择距离最小的节点,即B。

将B的距离设为已知最小距离,并标记为已访问。

10. 到达目标节点D,找到最短路径。

最终的最短路径为A -> B -> D,距离为2 + 3 = 5。

在实际应用中,为了更高效地计算最短路径,可以使用优先队列或者最小堆来实现节点的选择过程。

dijkstra算法步骤例题表格

dijkstra算法步骤例题表格

Dijkstra算法是一种用于计算图中从一个顶点到其他所有顶点的最短路径的算法。

它由荷兰计算机科学家艾兹赫尔·戴克斯特拉于1956年提出。

Dijkstra算法的基本思想是通过不断更新起始顶点到其他顶点的最短路径长度,逐步找到最短路径。

以下将详细介绍Dijkstra算法的步骤,并给出一个例题和表格供读者参考。

一、算法步骤1. 初始化- 设置起始顶点的最短路径为0,其余顶点的最短路径为无穷大。

- 将起始顶点加入已访问的顶点集合。

2. 更新- 从未访问的顶点中选择离起始顶点最近的顶点,将其加入已访问的顶点集合。

- 更新起始顶点到其他顶点的最短路径长度,如果经过新加入的顶点到其他顶点的路径长度小于当前已知的最短路径长度,则更新最短路径长度。

3. 重复更新直到所有顶点都被访问过。

二、算法实例为了更好地理解Dijkstra算法的具体应用步骤,我们通过一个实际的例题来演示算法的执行过程。

假设有以下带权重的图,起始顶点为A:顶点 A B C D EA 0 3 4 ∞ ∞B ∞ 0 ∞ 1 7C ∞ 4 0 2 ∞D ∞ ∞ ∞ 0 5E ∞ ∞ ∞ ∞ 0表中每个元素表示从对应顶点到其它顶点的边的权重,"∞"表示没有直接相连的边。

我们按照Dijkstra算法的步骤来计算从顶点A到其他顶点的最短路径长度。

1. 初始化起始顶点为A,初始化A到各顶点的最短路径长度为0,其余顶点的最短路径长度为∞。

将A加入已访问的顶点集合。

2. 更新选择A到B的路径长度最短,将B加入已访问的顶点集合。

更新A到C和A到D的最短路径长度。

3. 重复更新依次选择离起始顶点最近的顶点,并更新最短路径长度,直到所有顶点被访问。

通过不断的更新,最终得到从顶点A到其他顶点的最短路径长度表格如下:顶点 A B C D E最短路径长度 0 3 4 5 9三、总结通过以上Dijkstra算法的步骤和实例计算,我们可以清晰地了解该算法的执行过程和原理。

最短路径问题的优化算法

最短路径问题的优化算法

最短路径问题的优化算法最短路径问题是计算网络中两个节点之间最短路径的一个经典问题。

在许多实际应用中,如导航系统、交通规划和物流管理等领域,寻找最短路径是一个重要的任务。

然而,当网络规模较大时,传统的最短路径算法可能会面临计算时间长、耗费大量内存等问题。

为了解决这些问题,研究人员提出了许多优化算法,以提高最短路径问题的计算效率。

一、Dijkstra算法的优化Dijkstra算法是最短路径问题中最经典的解法之一,但当网络中的节点数量较大时,其计算时间会显著增加。

为了优化Dijkstra算法,研究者提出了以下几种改进方法:1. 堆优化Dijkstra算法中最耗时的操作是从未访问节点中选取最短路径的节点。

传统的实现方式是通过线性搜索来选择下一个节点,时间复杂度为O(N),其中N是节点的数量。

而使用堆数据结构可以将时间复杂度降低到O(lgN),从而提高算法的效率。

2. 双向Dijkstra算法双向Dijkstra算法是通过同时从起点和终点开始搜索,以减少搜索的范围和时间。

在搜索过程中,两个搜索方向逐渐靠近,直到找到最短路径为止。

双向Dijkstra算法相比传统的Dijkstra算法能够减少搜索空间,因此在网络规模较大时可以提供更快的计算速度。

二、A*算法A*算法是一种启发式搜索算法,常用于解决最短路径问题。

与传统的Dijkstra算法不同,A*算法通过引入启发函数来优先搜索距离终点较近的节点。

启发函数的选择对算法的效率有重要影响,一般需要满足启发函数低估距离的性质。

A*算法的时间复杂度取决于启发函数,如果启发函数选择得恰当,可以在大规模网络中快速找到最短路径。

三、Contraction Hierarchies算法Contraction Hierarchies(CH)算法是近年来提出的一种高效解决最短路径问题的方法。

CH算法通过预处理网络,将网络中的节点进行合并,形成层次结构。

在查询最短路径时,只需在层次结构上进行搜索,大大减少了计算复杂度。

基于最短路径优化问题Dijkstra算法程序的设计和实现

基于最短路径优化问题Dijkstra算法程序的设计和实现
其中 ∞ 都不等于 0 m , 或 .
上式表示对某一个 j0 sn 1 , 有 Байду номын сангаас∞ < ∞ 这 ( 一 )若 , 意味着 '至 有一 条长度小于等于 3的路径且边权值之和 1 2 比长度小于等于 2的路径 的边权值之和小 , 于是我们选取边
设 c < ,> = E 是一 简单加权 图( 有向或无向图且 不合平行 边 )其 中 = , , { 。 … , , 并 约定 了所 有顶点 的一个 l , 次序 , 是起点 , 。 3 / 是终点. 用矩阵 A ( ) 将带权 图的权 = 值存放在矩 阵 A 中. 在加权 图中 , o(v, )r 0当且仅 权 J< > =>
个顶点 的最短路径权值之和; (的第 kk 0 l2…/ 从A・ ’ (= ,,, 1 , 一
收稿 日期 :0 7 1- 8 20 —0 0
作者简介 : 菊(97 )女 , 兰州人 , 岳秋 17一 , 甘肃 兰州城市学院计算机系教师 , 从事离散数学教学与研究.
引 言
求最短路径 以及最短距离 的问题在各个 领域都经 常用 到 ,九十年代公认 的求最短路径 的最好的算法是由 Ew.i . D— jsa提出的标 号算法 . kn 但是该算法采用手工求解 , 算量太 计 大, 尤其是规模较大 的问题 , 手工求解几乎是不可 能的. 随着 计算机科学技术的飞速发展 , 完全能够解决这类问题. 本文将 求解 EW.i s a . Dj t 算法的过程采用二维矩 阵存储数据 ,利用 kr
) 都不等于 0或 m,= , , , 一 . , s2 34 …n 1
其 中 a= , i r表示 至 有一条长度为 1 t 且边权值为 r 的 路 , m( = m是一个 比 r 大好 多倍 的数 , 这样就 不会影 响计算

Dijkstra算法描述

Dijkstra算法描述

Dijkstra算法描述目录一、算法概述1二、算法原理及计算12.1算法原理12.2计算过程22.3改良的算法〔Dijkstra-like〕分析5三、源码分析6四、接口调用7一、算法概述Dijkstra〔迪杰斯特拉〕算法是典型的单源最短路径计算算法,用于解决源点到所有结点最短路径计算的问题,它采用了分治和贪心〔动态规划的特殊形式〕的思想搜索全局最优解。

本系统采用了主流、开源的JAVA图论库——Jgrapht来解决源点到终点间所有可能路径输出的问题,它的核心计算引擎采用了一种Dijkstra-like算法,由经典的Dijkstra〔迪杰斯特拉〕算法演化和改良而来。

二、算法原理及计算2.1算法原理Dijkstra算法思想为:设(,)= 是带权有向图,V代表图中顶点集合,E代G V E表图中含权重的边集合。

将全部顶点集合V分成两组,第一组为已求出最短路径的顶点集合,用S表示〔初始时S中只有一个源点,以后每求得一条最短路径,就将该路径的终点参加到集合S中〕;第二组为其余待确定最短路径的顶点集合,用U表示。

按最短路径长度的递增次序依次把U集合的顶点逐个参加到S集合中,约束条件是保持从源点v到S中各顶点的最短路径长度不大于从源点v到U 中任何顶点的最短路径长度。

算法的终止条件是集合U为空集,即集合U的顶点全部参加到集合S中。

2.2计算过程以图1为例讨论Dijkstra算法的计算过程,即计算某源点到网络上其余各结点的最短路径,设源点为①,逐步搜索,每次找出一个结点到源点①的最短路径,直至完成所有结点的计算。

图1 带权有向图记()D v为源点①到某终点v的距离,是源点①到终点v某条路径的所有链路长度之和。

记(,)l w v 是源点w到终点v的距离。

Dijkstra算法归纳如下:S=,U是其余未确〔1〕初始化,令S是已求出最短路径的顶点集合,{}U=,可写出:定最短路径的顶点集合,{}(1,)()l v D v ⎧=⎨∞⎩(1-1) 公式1-1中,(1,)l v 是源点①与终点v 的直连路径长度,而∞代表源点①与终点v 不相连,初始化结果如表1所示;〔2〕遍历集合U 中的所有结点v 并计算[]min (),()(,)D v D w l w v + 。

dijkstra标号法

dijkstra标号法

dijkstra标号法
Dijkstra标号法是一种用于解决最短路径问题的算法。

该算法是由荷兰计算机科学家EdsgerW.Dijkstra在1956年提出的,被广泛应用于路由协议、网络规划、城市规划等领域。

该算法的基本思想是从一个起点开始,逐步扩展到周围的点,直到到达目标点。

在这个过程中,每个点都被赋予一个标号,表示从起点到该点的最短距离。

算法使用一个称为“优先队列”的数据结构来维护待扩展的点,以保证每次扩展的点都是当前距离起点最近的点。

Dijkstra标号法的具体步骤如下:
1. 初始化:将起点的标号设为0,其余点的标号设为无限大。

2. 将起点加入优先队列中。

3. 从优先队列中取出距离起点最近的点,更新与该点相邻的点的标号值。

4. 将更新后的点加入优先队列。

5. 重复步骤3和4,直到到达目标点或者优先队列为空。

6. 如果到达目标点,则返回该点的标号值,否则表示不存在从起点到目标点的路径。

Dijkstra标号法的时间复杂度为O(ElogV),其中E表示边数,V 表示点数。

虽然该算法在解决最短路径问题方面表现出色,但是它不能处理带有负权边的图,因为负权边会导致优先队列的错误排序。

对于带有负权边的图,应该使用另一种算法——Bellman-Ford算法。

- 1 -。

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

两个指定顶点之间的最短路径
问题如下:给出了一个连接若干个城镇的铁路网络,在这个网络的两个指定城镇间,找一条最短铁路线。

以各城镇为图G 的顶点,两城镇间的直通铁路为图G 相应两顶点间的边,得图G 。

对G 的每一边e ,赋以一个实数)(e w —直通铁路的长度,称为e 的权,得到赋权图G 。

G 的子图的权是指子图的各边的权和。

问题就是求赋权图G 中指定的两个顶点00,v u 间的具最小权的轨。

这条轨叫做00,v u 间的最短路,它的权叫做00,v u 间的距离,亦记作),(00v u d 。

求最短路已有成熟的算法:迪克斯特拉(Dijkstra )算法,其基本思想是按距0u 从近到远为顺序,依次求得0u 到G 的各顶点的最短路和距离,直至0v (或直至G 的所有顶点),算法结束。

为避免重复并保留每一步的计算信息,采用了标号算法。

下面是该算法。

(i) 令0)(0=u l ,对0u v ≠,令∞=)(v l ,}{00u S =,0=i 。

(ii) 对每个i S v ∈(i i S V S \=),用
)}()(),({min uv w u l v l i
S u +∈ 代替)(v l 。

计算)}({min v l i
S v ∈,把达到这个最小值的一个顶点记为1+i u ,令}{11++=i i i u S S 。

(iii). 若1||-=V i ,停止;若1||-<V i ,用1+i 代替i ,转(ii)。

算法结束时,从0u 到各顶点v 的距离由v 的最后一次的标号)(v l 给出。

在v 进入i S 之前的标号)(v l 叫T 标号,v 进入i S 时的标号)(v l 叫P 标号。

算法就是不断修改各项点的T 标号,直至获得P 标号。

若在算法运行过程中,将每一顶点获得P 标号所由来的边在图上标明,则算法结束时,0u 至各项点的最短路也在图上标示出来了。

例1 某公司在六个城市126,,,c c c L 中有分公司,从i c 到j c 的直接航程票价记在下述矩阵的),(j i 位置上。

(∞表示无直接航路),请帮助该公司设计一张城市1c 到其它城市间的票价最便宜的路线图。

⎥⎥⎥⎥⎥⎥⎥⎦⎤⎢⎢⎢⎢⎢⎢⎢⎣⎡∞∞∞∞∞∞
05525251055010202525100102040
2010015252015050102540500
解 用矩阵n n a ⨯(n 为顶点个数)存放各边权的邻接矩阵,行向量pb 、1index 、2index 、d 分别用来存放P 标号信息、标号顶点顺序、标号顶点索引、最短通路的值。

其中分量

⎨⎧=顶点未标号当第顶点已标号当第i i i pb 01)(; )(2i index 存放始点到第i 点最短通路中第i 顶点前一顶点的序号;
)(i d 存放由始点到第i 点最短通路的值。

求第一个城市到其它城市的最短路径的Matlab 程序如下:
clear;
clc;
M=10000;
a(1,:)=[0,50,M,40,25,10];
a(2,:)=[zeros(1,2),15,20,M,25];
a(3,:)=[zeros(1,3),10,20,M];
a(4,:)=[zeros(1,4),10,25];
a(5,:)=[zeros(1,5),55];
a(6,:)=zeros(1,6);
a=a+a';
pb(1:length(a))=0;pb(1)=1;index1=1;index2=ones(1,length(a)); d(1:length(a))=M;d(1)=0;temp=1;
while sum(pb)<length(a)
tb=find(pb==0);
d(tb)=min(d(tb),d(temp)+a(temp,tb));
tmpb=find(d(tb)==min(d(tb)));
temp=tb(tmpb(1));
pb(temp)=1;
index1=[index1,temp];
index=index1(find(d(index1)==d(temp)-a(temp,index1))); if length(index)>=2
index=index(1);
end
index2(temp)=index;
end
d, index1, index2。

相关文档
最新文档