C++ || 数据结构 -- 邻接矩阵&最短路径Dijsktra算法

问题描述:

 

一张地图包括n个城市,假设城市间有m条路径(有向图),每条路径的长度已知。给定地图的一个起点城市和终点城市,利用 Dijsktra算法求出起点到终点之间的最短路径。

输入要求:

多组数据,每组数据有m+3行。第一行为两个整数n和m,分别代表城市个数n和路径条数m。第二行有n个字符,代表每个城市的名字。第三行到第m+2行每行有两个字符a和 b和一个整数d,代表从城市α到城市b有一条距离为d的路。最后一行为两个字符,代表待求最短路径的城市起点和终点。当n和 m都等于0时,输入结束。

输出要求:

每组数据输出2行。第1行为一个整数,为从起点到终点之间最短路的长度。第2行为一串字符串,代表该路径。每两个字符之间用空格隔开。

输入样例:

3 3

A B C

A B 1

B C 1

C A 3

A C

6 8

A B C D E F

A F 100

A E 30

A C 10

B C 5

C D 50

D E 20

E F 60

D F 10

A F

0 0

输出样例:

2

A B C

70

A E D F

#include <iostream>

using namespace std;

#define MaxInt 32567 //表示极大值,即正无穷
#define MVNum 100 //最大定点数
#define OK 1

typedef char VerTexType;//假设顶点的数据类型为字符型 vertex顶点
typedef int ArcType;//假设边的权值类型为整型
typedef struct {
    VerTexType vexs[MVNum];//顶点表
    ArcType arcs[MVNum][MVNum];//邻接矩阵
    int vexnum, arcnum;//图的当前点数和边数
}AMGraph;

VerTexType IndexVex(AMGraph G, int u) {//存在则返回u在顶点表中的下标,否则返回-1
    return G.vexs[u];
}

int LocateVex(AMGraph G, VerTexType v) {
    for (int i = 0; i < G.vexnum; i++) {
        if (v == G.vexs[i])//输入的顶点v在G中找到
            return i;
    }
    return -1;
}

int CreateUDN(AMGraph& G) {//采用邻接矩阵表示法,创建无向网G
    char v1, v2;
    int w;
    cin >> G.vexnum >> G.arcnum;//输入总顶点数,总边数
    for (int i = 0; i < G.vexnum; ++i)
        cin >> G.vexs[i];
    for (int i = 0; i < G.vexnum; ++i)//初始化邻接矩阵,边的最大权值设置为极大值MaxInt
        for (int j = 0; j < G.vexnum; ++j)
            G.arcs[i][j] = MaxInt;
    int i, j;
    for (int k = 0; k < G.arcnum; ++k) {//构造邻接矩阵
        cin >> v1 >> v2 >> w;//输入一条边依附的顶点及权值
        i = LocateVex(G, v1);
        j = LocateVex(G, v2);//确定v1和v2在G中的位置,即顶点数组的下标
        G.arcs[i][j] = w;//边<v1,v2>的权值置为w
        G.arcs[j][i] = G.arcs[i][j];//置<v1,v2>的对称边<v2,v1>的权值为w
    }
    return OK;
}

int CreateDN(AMGraph& G,int vex,int edge) {//采用邻接矩阵表示法,创建有向网G
    char v1, v2;
    int w;
    
    //cin >> G.vexnum >> G.arcnum;//输入总顶点数,总边数
    G.vexnum = vex;//总顶点数
    G.arcnum = edge;//总边数
    for (int i = 0; i < G.vexnum; ++i)
        cin >> G.vexs[i];
    for (int i = 0; i < G.vexnum; ++i)//初始化邻接矩阵,边的最大权值设置为极大值MaxInt
        for (int j = 0; j < G.vexnum; ++j)
            G.arcs[i][j] = MaxInt;
            
    int i, j;
    for (int k = 0; k < G.arcnum; ++k) {//构造邻接矩阵
        cin >> v1 >> v2 >> w;//输入一条边依附的顶点及权值
        i = LocateVex(G, v1);
        j = LocateVex(G, v2);//确定v1和v2在G中的位置,即顶点数组的下标
        G.arcs[i][j] = w;//边<v1,v2>的权值置为w
        //G.arcs[j][i] = G.arcs[i][j];//置<v1,v2>的对称边<v2,v1>的权值为w
    }//for
    return OK;
}

int D[MVNum], Path[MVNum];
void ShortestPath_DIJ(AMGraph G, VerTexType V) {//用Dijkstra算法求有向网G的v0顶点到其余顶点的最短路径
    int n, w, v, min;
    int S[MVNum];
    n = G.vexnum;//n是顶点的个数
    int v0 = LocateVex(G, V);
    for (v = 0; v < n; v++) {
        S[v] = false;//S初始为空集
        D[v] = G.arcs[v0][v];//将v0到各个终点的最短路径长度初始化为弧上的权值
        if (D[v] < MaxInt) {
            Path[v] = v0;//如果v0和v之间有弧,则将v前驱置为v0
        }
        else {
            Path[v] = -1;//如果v0和v之间无弧,则将v前驱置为-1
        }
    }//for
    S[v0] = true;//将v0加入S
    D[v0] = 0;//源点到源点的距离为0
    
    /*————————初始化结束,开始主循环,每次求得v0到某个顶点v的最短路径,将v加到S集————————*/
    
    for (int i = 1; i < n; i++) {//对其余n-1个顶点,依次进行计算
        min = MaxInt;
        for (w = 0; w < n; ++w) {
            if (!S[w] && D[w] < min) {
                v = w; min = D[w];//选择一条当前的最短路径,终点为v 
            }
        }
        S[v] = true;//将v加入S
        for (w = 0; w < n; w++) {//更新从v0出发到集合V-S上所有顶点的最短路径长度
            if (!S[w] && (D[v] + G.arcs[v][w] < D[w])) {
                D[w] = D[v] + G.arcs[v][w];//更新D[w]
                Path[w] = v;//更改w的前驱为v
            }//if
        }
    }//for
}

void Search(AMGraph G, int v) {
    if (Path[v] == -1)
        return;
    else {
        Search(G, Path[v]);
        cout << IndexVex(G, Path[v]) << " ";
    }
}

int main() {
    char city1, city2;//城市名字,起点、终点
    char str[]={',','.','/','*',';',':','+','-','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'};
    int a, b;//n个城市,m条路径
    cout << "请输入城市个数以及路径条数(需用空格分隔)--注意:输入 0 0结束输入:\n";

    while (cin >> a >> b && a && b) {

        cout << "请输入城市之间路径距离(需用空格分隔):\n";
        AMGraph G;
        CreateDN(G, a, b);
        cin >> city1;
        ShortestPath_DIJ(G, city1);
        cin >> city2;
        int n = LocateVex(G, city2);
        cout << "最短路长为:" << D[n] << endl;
        cout << "最短路径为:";
        Search(G, n);
        cout << city2 << endl;
    }
    return 0;
}

验证:

输入:

3 3

A B C

A B 1

B C 1

C A 3

A C

6 8

A B C D E F

A F 100

A E 30

A C 10

B C 5

C D 50

D E 20

E F 60

D F 10

A F

0 0

输出结果如下图所示:

  • 5
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: SUMO是一个用于模拟城市交通流的软件,它可以生成最短路径。下面是使用SUMO生成最短路径的步骤: 1. 创建一个SUMO工程并导入地图数据,可以使用OSM格式的地图数据。 2. 在地图上标记起点和终点。 3. 使用SUMO自带的工具,如DUAROUTER,生成路径文件。DUAROUTER将使用Dijkstra或A*算法计算最短路径。 4. 将路径文件导入SUMO仿真环境中,并运行仿真。 在仿真过程中,SUMO将按照生成的路径模拟车辆的行驶过程。这可以用来评估不同路线对交通拥堵、车辆延迟等方面的影响。 ### 回答2: SUMO(Simulation of Urban Mobility)是一种用于模拟城市交通流动的开源软件。在SUMO中,我们可以使用SUMO软件的命令行工具或SUMO配置文件来生成最短路径。 首先,我们需要创建一个SUMO配置文件(.sumocfg),其中包含模拟的网络和车辆。在配置文件中,我们可以指定网络文件、车辆生成器和旅行路线等信息。 在创建配置文件后,我们可以使用SUMO的命令行工具来进行模拟和生成最短路径。通过命令行,我们可以指定SUMO配置文件和生成最短路径的起点和终点,并使用Dijkstra或A*等算法来计算最短路径。 例如,我们可以使用以下命令来生成最短路径: sumo-gui -c my_config.sumocfg --tripinfo-output output.xml --routing-algorithm dijkstra --route-output routes.rou.xml --seed 21 上述命令将打开SUMO图形界面,并使用my_config.sumocfg配置文件进行模拟。在模拟过程中,将使用Dijkstra算法生成最短路径,并将结果保存到routes.rou.xml文件中。而tripinfo-output标志用于指定生成的路线的详细信息。 当模拟完成后,我们可以通过解析routes.rou.xml文件来获取最短路径的详细信息,如起点、终点和路径等。 通过利用SUMO软件,我们可以灵活地生成最短路径,并能够根据需求选择不同的路径生成算法。这对于城市交通规划和交通流量研究等领域都具有重要意义。 ### 回答3: SUMO(Simulation of Urban MObility)是一个用于模拟城市交通的开源软件,可以用来生成最短路径。SUMO提供了一个强大的路网编辑器和路网导航工具,可以用来创建和编辑城市的道路网络,以及计算最短路径。 利用SUMO生成最短路径的过程可以分为以下几个步骤: 1. 创建路网:使用SUMO的路网编辑器,可以导入城市的地理数据,包括道路、交叉口、车道、交通信号灯等信息,并对其进行编辑和调整,以创建一个真实的城市路网。 2. 设置车辆和行驶规则:在路网中设置车辆的属性,例如车辆类型、车辆行驶规则、速限制等。这些设置可以帮助SUMO计算最短路径时考虑车辆的特性和行驶限制。 3. 导入起点和终点:在路网中指定起点和终点,即希望计算最短路径的起点和目的地。可以手动指定位置,也可以通过导入坐标或其他地理数据来设置起点和终点。 4. 计算最短路径:利用SUMO的最短路径计算算法,在指定的起点和终点之计算出最短路径。SUMO会考虑道路网络的拓扑结构、交通流量和行驶限制等因素,计算出最短路径。 5. 可视化结果:SUMO可以将计算得到的最短路径可视化呈现,以便用户查看和分析。可视化结果可以显示起点、终点和最短路径的具体线路,帮助用户理解路径的选择和优劣。 总结来说,利用SUMO生成最短路径的关键在于创建准确的路网和设置合适的车辆属性和行驶规则。通过计算和可视化,SUMO可以高效地找到起点和终点之最短的路径,并提供给用户以可视化的结果。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

小嘤嘤怪学

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

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

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

打赏作者

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

抵扣说明:

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

余额充值