(1-3)Dijkstra算法:交通网络中的最短路径规划

Dijkstra算法在智能驾驶、无人机和机器人领域有着重要的应用。在智能驾驶中,该算法可用于规划车辆最短路径,以优化导航和避免交通拥堵。对于智能飞行器领域,Dijkstra算法可帮助规划飞行路径,确保无人机安全、高效地到达目的地。在机器人领域,算法可以用于路径规划,使机器人能够智能地导航和执行任务,例如在仓库中进行物流操作。其在这些领域的广泛应用体现了Dijkstra算法在实现智能导航和路径规划方面的关键作用。

在交通网络中,最短路径规划是一项关键任务,用于优化车辆导航、减少交通拥堵,提高交通系统的效率。Dijkstra算法在这一领域的应用十分重要。通过Dijkstra算法,交通网络中的最短路径规划可以实现以下目标。

  1. 导航优化:基于交通网络的拓扑结构和道路间的距离,Dijkstra算法能够计算出从起点到终点的最短路径,为驾驶员提供导航建议,使其能够选择最迅速到达目的地的路径。
  2. 交通拥堵避免:考虑到实时交通状况,Dijkstra算法可与实时交通数据集成,动态调整最短路径,以规避拥堵区域,减少行车时间。
  3. 交通流优化:通过最短路径规划,交通管理系统可以有效引导车流,平衡道路使用,减缓拥堵发生,提高整体交通系统的稳定性。
  4. 紧急情况响应:在紧急情况下,如救援任务或医疗急救,Dijkstra算法能够快速计算出最短路径,使紧急车辆能够迅速到达目的地。

总体而言,Dijkstra算法在交通网络中的最短路径规划中发挥着重要的作用,为实现更高效、更安全的交通系统提供了有力的支持。例如下面是一个实现 Dijkstra 算法的 C++ 程序,用于计算图中从给定起点到其他顶点的最短路径。通过 Dijkstra 算法计算了从用户输入的起点到图中所有其他顶点的最短路径,并输出了相关信息。如果用户输入的是预定义的图,最终输出将是该图中各个顶点的最短路径信息。

实例1-1:计算图中从给定起点到其他顶点的最短路径(codes/1/Dijkstra/Dijkstra.cpp

实例文件Dijkstra.cpp的具体实现代码如下所示。

#include<stdio.h>
#include<iostream>
#define maxsize 100
#define infinity 999
using namespace std;

class undigraph
{
public:
    //int vertexnum=0;
    int vertexnum = 7;
    //图以邻接矩阵的形式存储
    //int adjmatrix[maxsize][maxsize];//如果要自己输入图就把注释掉的取消注释并将对应代码注释掉
    int adjmatrix[7][7] =
    {
        {0,5,7,infinity,infinity,infinity,2},
        {5,0,infinity,9,infinity,infinity,3},
        {7,infinity,0,infinity,8,infinity,3},
        {infinity,9,infinity,0,infinity,4,infinity},
        {infinity,infinity,8,infinity,0,5,4},
        {infinity,infinity,infinity,4,5,0,6},
        {2,3,3,infinity,4,6,0}
    };
    int start = 0;
    //int start;
    int distance[maxsize];//起点与各顶点间最短距离数组
    int prev[maxsize];//起点与各顶点之间的最短路径的前驱数组
    int flag[maxsize];//顶点访问数组用来表示是否已经被访问
    //创建图
    void createundigraph();
    //初始化
    void initdistance();
    void initpre();
    void initflag();
    //打印数组
    void printdistance();//打印距离数组
    void printprev();//打印前驱数组
    void printpath();//打印最短路径
    //最短路径算法
    void dijkstra();
};

void undigraph::createundigraph()
{

    int tempdata;
    int adjvertex;
    int i = 0;
    for (;;i++)
    {
        cout << "请输入顶点" << i << "数据:" << endl;
        cin >> tempdata;
        vertexnum += 1;
        if (tempdata == -1)
        {
            break;
        }

        cout << "请输入该顶点的相邻顶点:" << endl;
        cin >> adjvertex;

        adjmatrix[i][adjvertex] = 1;
        adjmatrix[adjvertex][i] = 1;
    }
    cout << "邻接矩阵构建完毕" << endl;

}

void undigraph::initdistance()
{
    for (int i = 0; i < vertexnum; i++)
    {
        distance[i] = adjmatrix[start][i];//初始起点到达其他所有顶点的最短路径长度就是邻接矩阵中的权值  
    }
}

void undigraph::initpre()
{
    for (int i = 0; i < vertexnum; i++)
    {
        prev[i] = i;//初始所有的点所在的最短路径的前驱顶点都是自身
    }

}

void undigraph::initflag()
{
    for (int i = 0; i < vertexnum; i++)
    {
        flag[i] = 0;//初始所有顶点都未被访问过
    }

}

void undigraph::dijkstra()
{
    //用户输入起点
    cout << "请输入起点:" << endl;
    cin >> start;
    //初始化顶点
    //1.对顶点进行访问
    flag[start] = 1;
    //2.起点到起点的最短路径长度为0
    distance[start] = 0;
    //定义一个变量用来储存即将访问的顶点
    int k = start;
    //因为起点已经被初始化了,此时我们还剩下vertexnum-1个顶点需要进行访问和求取最短路径
    for (int i = 0; i < vertexnum - 1; i++)
    {
        //每次寻找当前顶点的最短路径的时候都要将最小权值初始化为无穷
        int min = infinity;
        //经过循环之后找出与当前点相连接的权值最小的顶点并记录其下标
        for (int j = 0; j < vertexnum; j++)
        {
            if (flag[j] == 0 && distance[j] < min)
            {
                min = distance[j];
                k = j;
            }
        }
        //对其进行访问
        flag[k] = 1;
        //对这个访问的顶点进行最短路径修正
        int temp;
        for (int p = 0; p < vertexnum; p++)
        {
            if (adjmatrix[k][p] == infinity)//如果最后访问的顶点k与当前所选中的顶点不连通的话
            {
                temp = infinity;//将当前最短距离设置为无穷
            }
            else
            {
                temp = min + adjmatrix[k][p];//若连通就将当前距离设置为起点到顶点k的最短距离加上(k,p)的权值
            }

            if (flag[p] == 0 && temp < distance[p])//如果顶点p未被访问过,且temp小于顶点直接到达顶点p的距离
            {
                distance[p] = temp;//就将temp设置为起点到达顶点p的最短距离
                prev[p] = k;//并将顶点p的前驱顶点设置为顶点k
            }

        }

    }

}

void undigraph::printdistance()
{
    cout << "=========distance=========" << endl;
    for (int i = 0; i < vertexnum; i++)
    {
        cout << distance[i] << "  ";
    }
    cout << endl;
}

void undigraph::printprev()
{
    cout << "=========prev=========" << endl;
    for (int i = 0; i < vertexnum; i++)
    {
        cout << prev[i] << "  ";
    }
    cout << endl;
}

void undigraph::printpath()
{
    for (int i = 0; i < vertexnum; i++)
    {
        cout << "顶点" << start << "到顶点" << i << "的最短路径为;" << endl;
        cout << i << "<---";
        int tmp = prev[i];
        while (true)
        {
            if (tmp == i)
            {
                break;
            }
            if (tmp == prev[tmp])
            {
                cout << tmp << "<---";
                break;
            }
            cout << tmp << "<---";
            tmp = prev[tmp];
        }
        cout << start << endl;
    }
}

int main()
{
    undigraph ug;
    ug.initdistance();
    ug.initflag();
    ug.initpre();
    ug.dijkstra();
    ug.printdistance();
    ug.printprev();
    ug.printpath();
    return 0;
}

上述代码的实现流程如下所示:

(1)定义类undigraph

  1. 类undigraph的成员包括图的顶点数 vertexnum、邻接矩阵 adjmatrix、起点 start、最短路径长度数组 distance、最短路径前驱数组 prev 以及顶点访问标志数组 flag。
  2. 在类undigraph中提供了一系列函数用于创建图、初始化、打印数组以及执行 Dijkstra 算法。

(2)定义函数createundigraph:通过用户输入构建图的邻接矩阵。用户输入每个顶点的数据和相邻顶点,直到输入 -1 停止。这一步是可选的,因为您的代码中已经提供了一个预定义的图。

(3)定义函数initdistance:用于初始化起点到各顶点的最短路径长度数组 distance,将其初始化为邻接矩阵中起点所在行的权值。

(4)定义函数initpre:用于初始化最短路径前驱数组 prev,将其初始化为各顶点的索引,表示初始时每个顶点的前驱都是自己。

(5)定义函数initflag:用于初始化顶点访问标志数组 flag,将其初始化为 0,表示所有顶点都未被访问过。

(6)定义函数dijkstra

  1. 用户输入起点,然后对起点进行初始化操作:标记为已访问,起点到起点的最短路径长度为 0。
  2. 循环处理剩余的顶点,每次选择未访问的顶点中最短路径长度最小的顶点,标记为已访问,更新其他顶点的最短路径长度和前驱。
  3. 循环结束后,最短路径计算完成。

(7)定义函数printdistance:打印输出起点到各顶点的最短路径长度数组。

(8)定义函数printprev:打印输出各顶点的最短路径前驱数组。

(9)定义函数printpath:打印起点到各顶点的最短路径。

(6)定义主函数main

  1. 创建 undigraph 对象。
  2. 初始化最短路径长度、前驱和标志数组。
  3. 执行 Dijkstra 算法。
  4. 打印最短路径长度数组、最短路径前驱数组以及最短路径。

执行后会先提示用户输入一个起点,例如输入0后的执行结果如下:

请输入起点:

请输入起点:
0
=========distance=========
0  5  5  12  6  8  2
=========prev=========
0  1  6  5  6  6  6
顶点0到顶点0的最短路径为;
0<---0
顶点0到顶点1的最短路径为;
1<---0
顶点0到顶点2的最短路径为;
2<---6<---0
顶点0到顶点3的最短路径为;
3<---5<---6<---0
顶点0到顶点4的最短路径为;
4<---6<---0
顶点0到顶点5的最短路径为;
5<---6<---0
顶点0到顶点6的最短路径为;
6<---0

  • 27
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

码农三叔

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值