最短路径(图)

Dijkstra算法

Dijkstra算法为求带权图中从一个顶点(此处假设为Vo)到其它各顶点的最短路径,按路径长度递增的次序产生最短路径,假设所有权值非负。
储存结构:
1.图采用邻接矩阵表示法,对角线元素初值均取0。
2.数组dist[]: dist[i]最终储存Vo到Vi的最短路径及最短路径上Vi的前驱顶点(计算过程为距离值,可能会被调整)。
说明:
1.dist[ ]看成V集合,其中U指从Vo到一个顶点最短路径的所有顶点,V-U指未确定最短路径的顶点集合。
2.初始化dist时,集合U只有Vo,其对应的距离值为0;集合V中Vi的距离值为边(Vo,Vi)的权,若Vo和Vi之间无直接边,则Vi的距离值为MAX。
基本思想:
1)从集合V中选择距离值最小的顶点Vmin加入到集合U(可通过修改对角线元素值为1来表示)

2)因为上面选出的Vmin放到U时,如果Vmin可能是Vo到其它顶点V[i]最短路径上的一个顶点,这使得dist[i]的距离值减小,所以这时,需要根据min值,对集合V-U中各顶点的距离值进行调整:如果Vo到Vi的距离值比原来的距离值小,则修改Vi的距离值dist[i].length,否则不修改。


3)重复1)2),直到从Vo可以到达的所有顶点都被放入集合U为止。
C++代码实现:
#include <iostream>
#define Vextype int
#define Adjtype int
#define VN 2018
#define MAX 10000
using namespace std;

typedef struct
{
    Vextype vex[VN][VN];
    Adjtype arc[VN][VN];
}GraphMatrix;

typedef struct{
    Adjtype length;//shortest path
    int prevex;//Vi的前驱顶点
}Path;
Path dist[VN];
void init(GraphMatrix *pgraph,Path *dist)
{
    dist[0].length=dist[0].prevex=0;
    pgraph->arc[0][0]=1;//用矩阵对角线元素表示U,为1表示在U中
    for(int i=1;i<VN;i++){//初始化U-V中顶点的距离值
        dist[i].length=pgraph->arc[0][i];
        if(dist[i].length!=MAX) dist[i].prevex=0;
        else dist[i].prevex=-1;
    }
}
void dijkstra(GraphMatrix *pgraph,Path *dist)
{
    init(pgraph,dist);//初始化,U中只有Vo
    Adjtype minw;
    int mv;
    for(int i=1;i<VN;i++){
        minw=MAX; mv=0;
        for(int j=1;j<VN;j++)//在V-U中选出距离Vo最近的顶点
            if(pgraph->arc[j][j]!=1 && minw>dist[j].length){
                minw=dist[j].length; mv=j;
            }
        if(mv==0)    break;//Vo与V-U的顶点不连通,结束
        pgraph->arc[mv][mv]=1;//顶点mv加入U
        for(int i=1;i<VN;i++){//调整V-U顶点的已知最短路径
            if(pgraph->arc[i][i]!=1 && dist[i].length>dist[mv].length+pgraph->arc[mv][i]){
                dist[i].prevex=mv;
                dist[i].length=dist[mv].length+pgraph->arc[mv][i];  }
        }
    }
}
时间复杂度为O(n^2)。

Floyd算法

为求带权图中每一对顶点间的最短路径,可以依次把图中每个顶点作为起始点,利用Dijkstra算法求出每对顶点之间的最短路径,时间复杂度为O(n^3)。
但另一种方法Floyd算法更易理解,时间复杂度也是O(n^3)。
储存结构:
1.图也是用邻接矩阵表示法,对角线元素初值均取0。
2.定义一个与原始关系矩阵一样的矩阵,处理过程中存放每对顶点间的距离值。
3.再定义一个与原始矩阵同样大小的整数数组,存放Vi到Vj最短路径上Vi的后继顶点的下标值。
基本思想:
Floyd算法以关系矩阵为基础,将其看作是没有经过任何中间结点的每对顶点间的最短路径,然后经过多次迭代修改,每次增加一个新的结点,如果该结点作为中间结点,判断此路径是否小于原来的路径,若是则修改原来的路径(取小的值)。直到所有结点都增加进去,得到每对顶点间的最短路径。比如,求V 0到V 1的最短路径,由ppath->a[0][1]可知最短路径的值,由ppath->nextvex[0][1]得到最短路径上,V 0的下一个顶点V k,由ppah->nextvex[k][1]得到V k的下一个顶点,以此类推,直到顶点V 1,从而得到最短路径。

C++代码实现:
typedef struct{
    Adjtype a[VN][VN];
    int nextvex[VN][VN];
}Shortpath;
void floyd(GraphMatrix *pgraph,Shortpath *ppath)
{
    for(int i=0;i<VN;i++)//initialize
        for(int j=0;j<VN;j++){
            ppath->a[i][j]=pgraph->arc[i][j];
            if(pgraph->arc[i][j]!=MAX)  ppath->nextvex[i][j]=j;
            else    ppath->nextvex[i][j]=-1;
        }
    for(int k=0;k<VN;k++)//iterate calculate *ppath
        for(int i=0;i<VN;i++)
            for(int j=0;j<VN;j++){
                if(pgraph->arc[i][k]==MAX||pgraph->arc[k][j]==MAX)  continue;
                if(ppath->a[i][j]>pgraph->arc[i][k]+pgraph->arc[k][j]){//revise *ppath
                    ppath->a[i][j]=pgraph->arc[i][k]+pgraph->arc[k][j];
                    ppath->nextvex[i][j]=ppath->nextvex[i][k];
                }
            }
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
最短路径算法是用来在中找到两个顶点之间的最短路径的一种算法。它被广泛应用于各个领域,例如导航系统、物流路径规划等。 Qt是一种跨平台的应用程序开发框架,能够帮助我们构建形用户界面和开发各种类型的应用程序。 在Qt中实现最短路径可以通过使用算法来实现。我们可以将地表示为一个有向,将地点表示为顶点,将路径表示为边,每个边上都有一个权重来表示从一个地点到另一个地点的距离。然后,我们可以使用最短路径算法,例如Dijkstra算法或Floyd-Warshall算法,在中计算出最短路径。 首先,我们需要构建一个,表示地。使用Qt的形用户界面,我们可以在地上显示不同的地点,并通过用户的交互来创建连接这些地点的路径。我们还可以为每个路径设置权重,表示它们之间的距离。然后,我们可以使用算法来计算从一个地点到另一个地点的最短路径,并将路径显示在地上。 除了显示最短路径,我们还可以使用Qt的其他功能来增强地应用程序。例如,我们可以显示每个路径上的距离信息,或根据交通状况调整路径。我们还可以使用Qt的导航功能,帮助用户导航到目的地,并提供详细的导航指示。 总之,使用Qt来实现最短路径可以为用户提供一个直观且易于使用的界面,帮助他们在地上找到最短路径。同时,Qt的跨平台性也使得这个地应用能够在不同的操作系统上运行,使其更具普适性和实用性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值