C/C++:交通咨询系统设计

一、问题描述

在交通网络非常发达,交通工具和交通方式不断更新的今天,人们在出差、旅游或做其他出行时,不仅关心节省交通费用,而且对里程和所需要的时间等问题也感兴趣。对于这样一个人们关心的问题,可用一个图结构来表示交通网络系统,利用计算机建立一个交通咨询系统。图中的顶点表示城市,边表示城市之间的交通关系。这个交通系统可以回答出行旅客提出的各种路径选择问题。例如,问题之一:“一位旅客要从A城到B城,他希望选择一条途中中转次数最少的路线。”假设图中每一站都需要换车,那么这个问题反映到图上就是要找一条从顶点A到顶点B的所含边数目最少的路径。我们只需要从顶点A出发对图作广度优先搜索,一旦遇到顶点B就终止。由此所得广度优先生成树上,从根顶点A到顶点B的路径就是中转次数最少的路径。路径上A与B之间的顶点就是路径的中转站,但这只是一类最简单的图的最短路径问题。系统还可以回答诸如此类的等等的路径选择问题。
设计一个交通咨询系统,为出差、旅游或做其他出行的客人提供各种路径选择信息查询服务。

二、需求分析

设计一个交通咨询系统,能让旅客咨询从任一个城市顶点到另一城市顶点之间的最短路径(里程)或最低花费或最少时间等问题。对于不同的咨询要求,可输入城市间的路程或所需时间或所需费用。
本设计共分三部分,一是建立交通网络图的存储结构;二是解决单源最短路径问题;三是实现任两个城市顶点之间的最短路径问题。

2.1建立图的存储结构

邻接矩阵是表示图形中顶点之间相邻关系的矩阵。图的邻接矩阵是定义如下的n阶方阵:
设G=(V,E)是一个图,结点集为在这里插入图片描述

G的邻接矩阵 在这里插入图片描述
当邻接矩阵的行表头、列表头顺序一定时,一个图的邻接矩阵表示是唯一的。
图的邻接矩阵表示,除了需用一个二维数组存储顶点之间的相邻关系的邻接矩阵外,通常还需要使用一个具有n个元素的一维数组来存储顶点信息,其中下标为i的元素存储顶点i的信息。因此,图的邻接矩阵的存储结构定义如下:

#definf MVNum 50  //最大顶点数
typedef struct
      {	
  VertexType vexs[MVNum];         //顶点数组,类型假定为char型
  Adjmatrix arcs[MVNum][MVNum];   //邻接矩阵,假定为int型
}MGraph;

2.2单源最短路径(迪杰斯特拉算法)

最短路径的提法很多。在这里先讨论单源最短路径问题:即已知有向图(带权),我们希望找出从某个源点S V到G中其余各顶点的最短路径。
为了叙述方便,我们把路径上的开始点称为源点,路径的最后一个顶点为终点。
那么,如何求得给定有向图的单源最短路径呢?迪杰斯特拉(Dijkstra)提出按路径长度递增产生诸点的最短路径算法,称之为迪杰斯特拉算法。
迪杰斯特拉算法求最短路径的实现思想是:设G=(V,E)是一个有向图,结点集为, ,cost是表示G的邻接矩阵,cost[i][j]表示有向边<i,j>的权。若不存在有向边<i,j>,则cost[i][j]的权为无穷大(这里取值为32767)。设S是一个集合,其中的每个元素表示一个顶点,从源点到这些顶点的最短距离已经求出。设顶点v1为源点,集合S的初态只包含一个元素,即顶点v1。数组dist记录从源点到其他顶点当前的最短距离,其初值为dist[i]=cost[v1][i],i=1,2,……,n。从S之外的顶点集合V-S中选出一个顶点w,使dist[w]的值最小。于是从源点到达w只通过S中顶点,把w加入集合S中,调整dist中记录的从源点到V-S中每个顶点v的距离:从原来的dist[v]和dist[w]+cost[w][v]中选择较小的值作为新的dist[v]。重复上述过程,直到V-S为空。
最终结果是:S记录了从源点到该顶点存在最短路径的顶点集合,数组dist记录了源点到V中其余各顶点之间的最短路径,path是最短路径的路径数组,其中path[i]表示从源点到顶点i之间的最短路径的前驱顶点。
因此,迪杰斯特拉算法可用自然语言描述如下:

初始化S和D,置空最短路径终点集,置初始的最短路径值;
S[v1]=TRUE;  D[v1]=0;    //S集初始时只有源点,源点到源点的距离为0;
While (S集中顶点数<n)
{
开始循环,每次求得v1到某个v顶点的最短路径,并加v到S集中;
S[v]=TRUE;
更新当前最短路径及距离;
}

2.3任意一对顶点间最短路径(费洛伊德算法)

任意一对顶点间最短路径问题,是对于给定的有向网络图G=(V,E),要对G中任意一对顶点有序对“v,w(v 不等于w)”,找出v到w的最短路径。
要解决这个问题,我们可以依次把有向网络图中每个顶点作为源点,重复执行前面讨论的迪杰斯特拉算法n次,即可以求得每对顶点之间的最短路径。
这里还可以用另外一种方法,称作费洛伊德(Floyd)算法。
费洛伊德(Floyd)算法算法的基本思想是:假设求从顶点 vi到vj的最短路径。如果从vi到vj存在一条长度为arcs[i][j]的路径,该路径不一定是最短路径,还需要进行n次试探。首先考虑路径<vi,v1>和<v1,vj>是否存在。如果存在,则比较<vi,vj>和< vi,v1,vj >的路径长度,取长度较短者为当前所求得的最短路径。该路径是中间顶点序号不大于1的最短路径。其次,考虑从vi到vj是否包含有顶点v2为中间顶点的路径<vi,…,v2,…,vj>,若没有,则说明从vi到vj的当前最短路径就是前一步求出的;若有,那么<vi,…,v2,…,vj>可分解为<vi,…v2>和<v2,…,vj>,而这两条路径是前一次找到的中间顶点序号不大于1的最短路径,将这两条路径长度相加就得到路径<vi,…,v2,…,vj>的长度。将该长度与前一次中求出的从vi到vj的中间顶点序号不大于1的最短路径比较,取其长度较短者作为当前求得的从vi到vj的中间顶点序号不大于2的最短路径。依此类推,直到顶点vn加入当前从vi到vj的最短路径后,选出从vi到vj的中间顶点序号不大于n的最短路径为止。由于图G中顶点序号不大于n,所以vi到vj的中间顶点序号不大于n的最短路径,已考虑了所有顶点作为中间顶点的可能性,因此,它就是vi到vj的最短路径。

三、概要设计

1.设定邻接矩阵的抽象数据类型为:

ADT VertexType{
数据对象:D={ai,j|ai,j∈{},0≤i≤m+1,0≤j≤n+1,m,n≤10}
数据关系:R={ROW,COL}
ROW={<ai-1,j,ai,j>|ai-1,j,ai,j∈D,i=1,……,m+1,j=0,……,n+1}
COL={<ai,j-1,ai,j>|ai,j-1,ai,j∈D,i=0,……,m+1,j=1,……,n+1}
基本操作:
typedef struct {
		VertexType vexs[Vertex_NUM];			
		int arcs[Vertex_NUM][Vertex_NUM];		
		int	vn, en;								
} MGraph;		
操作结果:建立一个图的邻接矩阵	
}ADT VertexType


2.设定图的抽象数据类型定义为:

ADT Graph{
数据对象:D={ai|ai∈charset,i=1,2,……,n,n≥0}
数据关系:R1={<ai-1,ai>|ai-1,ai∈D,i=2……,n}
基本操作:
CreateMGraph()
操作结果:建立图的储存结构:有向图、无向图
void Floyd(G)
初始条件:建立一个图结构
操作结果:多源最短路,输出邻接矩阵
void Dijkstra(G)
初始条件:建立一个图结构
操作结果:所求结点到其他结点的最短路
void Inquiry( G)
初始条件:建立一个图结构
操作结果:查询图中两个节点的最短路径并输出
}ADT Graph
  1. 本程序包含三个模块
    1)主程序模块
    void main( )
    { 初始化
    do{
    接受命令;
    处理命令;
    }while(命令!=“退出”);
    }
    2)图模块----实现图抽象数据类型
    3)邻接矩阵模块----实现邻接矩阵抽象数据类型
    各模块之间的调用关系如下:
    在这里插入图片描述
  2. 迪杰斯特拉的伪码算法:
    1:找出未标记过的离起点最近的点(如果没有的话,就中止算法)
    2:以该点为中心点更新该点周围的点
    3:反复执行
void Graph::Dijkstra(int vertex)
{
    //注意:下标表示结点
    int count = 0; //用于记录访问过的结点数目,后面用于控制循环
    bool find[max_size]; //用于标记已经找到最短路径的结点
    int pre[max_size]; //用于存放当前结点的前驱结点的最短路径
    int distance[max_size]; //用于存放当前结点的最短路径
    //初始化在这里插入代码片
    for(int i=0;i<max_size;i++)
        pre[i] = vertex; //开始所有结点的前驱结点都是开始的vertex
    for(int i=0;i<max_size;i++)
        distance[i] = adjacent[vertex][i]; //邻接矩阵中存放的权值就是距离
    for(int i=0;i<max_size;i++)
        find[i] = false; //初始化所有结点都没有找到最短路径
ind[vertex] = true;
    int v = vertex; //用来迭代顶点的变量
    int d; //用来表示距离
    while(count < max_size)	//count用于记录访问过的次数
    {
        d = infinity;//开始置为无穷
        for(int i=0;i<max_size;i++) //找到离最初结点最短路径的一个未访问到的结点
        {
            if(!find[i] && distance[i]<d) //
            {
                d = diatance[i];
                v = i;
            }        
        }
find[v] = true;//表示节点放到S中
        
        //更新剩余的结点的前驱和最短距离
        for(int i=0;i<max_size;i++)
        {
            if(!find[i])
            {
                /*将上面找到的最短路径的结点作为起始点,
                *连到其他未访问过的结点上,
                *当比从最初结点到这个结点的路径短的时候,
                *就将上个结点作为前驱结点,更新一下即可*/
                d = distance[v] + adjacent[v][i];
                if(d < distance[i])
                {
                    pre[i] = v;
                    distance[i] = d;
                }
            }
        }
        count++;
    }
   }

4.弗洛伊德的伪码算法:

// dist(i,j) 为从节点i到节点j的最短距离
For i←1 to n do
   		For j←1 to n do
      		dist(i,j) = weight(i,j) 

For k←1 to n do // k为“媒介节点”
   		For i←1 to n do
      		For j←1 to n do
        		 if (dist(i,k) + dist(k,j) < dist(i,j)) then // 是否是更短的路径?
           		 dist(i,j) = dist(i,k) + dist(k,j)


1.邻接矩阵类型

typedef struct {
			int no;						//顶点编号
} VertexType;					//顶点类型

2.图类型

typedef struct {
	VertexType vexs[Vertex_NUM];			//存放顶点信息
	int arcs[Vertex_NUM][Vertex_NUM];		//邻接矩阵的边数组
	int	vn, en;								//顶点数,边数
} MGraph;									//完整的图邻接矩阵类型
void Floyd(G)
//多源最短路,输出邻接矩阵
void Dijkstra(G)
//所求结点到其他结点的最短路
void Inquiry( G)
//查询图中两个节点的最短路径并输出
MGraph* CreateMGraph()
//建立图的储存结构
其中部分操作的算法:
MGraph* CreateMGraph()
{
	int i, j, w;
	MGraph* G;
	int n, m;//顶点个数  边的个数
	G = (MGraph*)malloc(sizeof(MGraph));	//建立图的存储结构
	G->vn = n;
	G->en = m;
	for (i = 1; i <= G->vn; i++) {
		G->vexs[i].no = i;
	}
	for (i = 1; i <= G->vn; i++)
		for (j = 1; j <= G->vn; j++)
			G->arcs[i][j] = INF;
	for (i = 1; i <= n; i++)
		for (j = 1; j <= n; j++)
			G->arcs[i][j] = (i == j) ? 0 : INF;
	for (i = 1; i <= m; i++) {
		int t1, t2, d;//位置t1到位置t2的距离是d
		cin >> t1 >> t2 >> d;
		// G->arcs[t1][t2]=G->ar[t2][t1]=d;//无向图
		G->arcs[t1][t2] = d;//-----------------有向图
	}
	printf("\n图的存储建立完毕!\n");
	return	G;
}
void Inquiry(MGraph* G)
{
	int i;
	string t;
	string t1;
	cout << "请输入你要查询的城市名:";
	cin >> t >> t1;
	for (i = 1; i <= G->vn; i++) {
		if (citys[i] == t)
			break;
	}
	if (i == G->vn + 1) {
		cout << endl << "所查城市不在交通网络图中" << endl;
		getchar();
		return;
	}
	cout << endl << "所求城市" << citys[i] << "单源最短路径为:" << endl;
	for (int j = 1; j <= G->vn; j++) {
		if (i == j) continue;
		if (citys[j] == t1)
		{
			cout << citys[i] << "->" << citys[j] << ": " << G->arcs[i][j] << endl;
		}
	}
}

3.求最短路径的算法:

void Floyd(MGraph* G)//多源最短路
{
	for (int i = 1; i <= G->vn; i++)
		for (int j = 1; j <= G->vn; j++)
			for (int k = 1; k <= G->vn; k++)
				if (G->arcs[i][k] + G->arcs[k][j] < G->arcs[i][j])
					G->arcs[i][j] = G->arcs[i][k] + G->arcs[k][j];	
}// Floyd
void Dijkstra(MGraph* G)//贪心思想
{
	int dis[10], book[10]; //所求结点到其他结点的最短路  记录当前结点是否已经判断过了
	//初始化单源最短数组dis,这里是1号顶点到其余各顶点的初始路径
	for (int i = 1; i <= G->vn; i++)
		dis[i] = G->arcs[1][i];
	for (int i = 2; i <= G->vn; i++)
		book[i] = 0;//未知最短路顶点
	book[1] = 1;

	//Dijkstra 算法核心语句
	for (int i = 1; i <= G->vn - 1; i++) {
		int min = INF, t;
		for (int j = 1; j <= G->vn; j++)
			if (book[j] == 0 && dis[j] < min) { //找出未判断结点中到1号结点(单源最短路起点)距离最小结点
				min = dis[j];
				t = j;
			}
		book[t] = 1;//及时将选出的该结点标记为已判断过了
		for (int v = 1; v <= G->vn; v++) { //判断其他结点借助当前选出的结点,是否使得到1号结点的距离变短
			if (G->arcs[t][v] < INF) {
				if (dis[v] > dis[t] + G->arcs[t][v])
					dis[v] = dis[t] + G->arcs[t][v];//记录借助当前选出结点使得到1号结点更短路径的新距离
			}
		}
}//Dijkstra

4.主函数和其他函数的伪码算法

void main( ) 
{//主程序           
       Initialization();     //初始化
       do{
          ReadCommand(cmd);//读入一个操作命令符
           Interpret(cmd);     //解释执行操作命令符
         }while(输入信息);
}//main
void Initialization()
{ //系统初始化
   MGraph* G;
G = CreateMGraph();
}//Initialization
void ReadCommand(char &cmd)
{ //读入操作命令符
显示键入操作命令符的提示信息;
 do{
    Floyd(G);
Dijkstra(G);
}while(输入信息);
}//ReadCommand
void Interpret(char cmd)
{
Inquiry(G);
	return 0;
}//InterPret

5.函数的调用关系图反映了演示程序的层次结构
在这里插入图片描述

typedef struct {
    int no;                     //顶点编号
} VertexType;                   //顶点类型

typedef struct {
    VertexType vexs[Vertex_NUM];            //存放顶点信息
    int arcs[Vertex_NUM][Vertex_NUM];       //邻接矩阵的边数组
    int vn, en;                             //顶点数,边数
} MGraph;                                   //完整的图邻接矩阵类型

2. 迪杰斯特拉算法

void Dijkstra(MGraph*G)//贪心思想
{
    int dis[10],book[10]; //所求结点到其他结点的最短路  记录当前结点是否已经判断过了
    //初始化单源最短数组dis,这里是1号顶点到其余各顶点的初始路径
    for(int i=1; i<=G->vn; i++)
        dis[i]=G->arcs[1][i];
    for(int i=2; i<=G->vn; i++)
        book[i]=0;//未知最短路顶点
    book[1]=1;

    //Dijkstra 算法核心语句
    for(int i=1; i<=G->vn-1; i++) {
        int min=INF,t;
        for(int j=1; j<=G->vn; j++)
            if(book[j]==0&&dis[j]<min) { //找出未判断结点中到1号结点(单源最短路起点)距离最小结点
                min=dis[j];
                t=j;
            }
        book[t]=1;//及时将选出的该结点标记为已判断过了
        for(int v=1; v<=G->vn; v++) { //判断其他结点借助当前选出的结点,是否使得到1号结点的距离变短
            if(G->arcs[t][v]<INF) {
                if(dis[v]>dis[t]+G->arcs[t][v])
                    dis[v]=dis[t]+G->arcs[t][v];//记录借助当前选出结点使得到1号结点更短路径的新距离
            }
        }
    }

    cout<<"所求城市单源最短路径为:"<<endl;
    for(int i=2; i<=G->vn; i++)
        if(dis[i]<INF)//如果大于等于说明不存在该路径
            cout<<citys[1]<<"->"<<citys[i]<<": "<<dis[i]<<endl;

3. 费洛伊德算法

void Floyd(MGraph*G)//多源最短路
{
    for(int i=1; i<=G->vn; i++)
        for(int j=1; j<=G->vn; j++)
            for(int k=1; k<=G->vn; k++)
                if(G->arcs[i][k]+G->arcs[k][j]<G->arcs[i][j])
                    G->arcs[i][j]=G->arcs[i][k]+G->arcs[k][j];

    for(int i=1; i<=G->vn; i++)
        cout<<"\t"<<citys[i];
    cout<<endl;
    for(int i=1; i<=G->vn; i++) {
        cout<<citys[i];
    //-----------无向图--------------
        for(int j=1; j<=G->vn; j++)
        if(G->arcs[i][j]==INF){
            printf("\t");
        }else{
            printf("%8d",G->arcs[i][j]);
        }
        cout<<endl;
    }
}}

4. 运行主控程序

int main()
{

    MGraph *G;
    G = CreateMGraph();
    Floyd(G);
    Dijkstra(G);
    Inquiry(G);
    system("pause");
    return 0;
}

五、设计功能的实现(用C或C++语言描述)

#include <bits/stdc++.h>
using namespace std;
#define Vertex_NUM 50               // 最大顶点数
#define INF 32767                   // 无穷大∞
string citys[10]={"0","a","b","c","d","e","f","g"};//-----------------有向图
//邻接矩阵的类型定义如下:
typedef struct {
    int no;                     //顶点编号
} VertexType;                   //顶点类型

typedef struct {
    VertexType vexs[Vertex_NUM];            //存放顶点信息
    int arcs[Vertex_NUM][Vertex_NUM];       //邻接矩阵的边数组
    int vn, en;                             //顶点数,边数
} MGraph;                                   //完整的图邻接矩阵类型
void Floyd(MGraph*G)//多源最短路
{
    for(int i=1; i<=G->vn; i++)
        for(int j=1; j<=G->vn; j++)
            for(int k=1; k<=G->vn; k++)
                if(G->arcs[i][k]+G->arcs[k][j]<G->arcs[i][j])
                    G->arcs[i][j]=G->arcs[i][k]+G->arcs[k][j];
    for(int i=1; i<=G->vn; i++)
        cout<<"\t"<<citys[i];
    cout<<endl;
    for(int i=1; i<=G->vn; i++) {
        cout<<citys[i];
    //-----------有向图--------------
        for(int j=1; j<=G->vn; j++)
        if(G->arcs[i][j]==INF){
            printf("\t");
        }else{
            printf("%8d",G->arcs[i][j]);
        }
        cout<<endl;
    }
}
void Dijkstra(MGraph*G)//贪心思想
{
    int dis[10],book[10]; //所求结点到其他结点的最短路  记录当前结点是否已经判断过了
    //初始化单源最短数组dis,这里是1号顶点到其余各顶点的初始路径
    for(int i=1; i<=G->vn; i++)
        dis[i]=G->arcs[1][i];

    for(int i=2; i<=G->vn; i++)
        book[i]=0;//未知最短路顶点
    book[1]=1;

    //Dijkstra 算法核心语句
    for(int i=1; i<=G->vn-1; i++) {
        int min=INF,t;
        for(int j=1; j<=G->vn; j++)
            if(book[j]==0&&dis[j]<min) { //找出未判断结点中到1号结点(单源最短路起点)距离最小结点
                min=dis[j];
                t=j;
            }
        book[t]=1;//及时将选出的该结点标记为已判断过了
        for(int v=1; v<=G->vn; v++) { //判断其他结点借助当前选出的结点,是否使得到1号结点的距离变短
            if(G->arcs[t][v]<INF) {
                if(dis[v]>dis[t]+G->arcs[t][v])
                    dis[v]=dis[t]+G->arcs[t][v];//记录借助当前选出结点使得到1号结点更短路径的新距离
            }
        }
    }
    cout<<"所求城市单源最短路径为:"<<endl;
    for(int i=2; i<=G->vn; i++)
        if(dis[i]<INF)
            cout<<citys[1]<<"->"<<citys[i]<<": "<<dis[i]<<endl;
}
void Inquiry(MGraph*G )
{
    int i;
    string t;
    string t1;
    cout<<"请输入你要查询的城市名:";
    cin>>t>>t1;
    for(i=1; i<= G->vn; i++) {
        if(citys[i]==t)
        
            break;
    }
    if(i== G->vn+1) {
        cout<<endl<<"所查城市不在交通网络图中"<<endl;
        getchar();
        return ;
    }
    cout<<endl<<"所求城市"<<citys[i]<<"单源最短路径为:"<<endl;
    for(int j=1; j<= G->vn; j++) {
        if(i==j) continue;
        if(citys[j]==t1)
        {   cout<<citys[i]<<"->"<<citys[j]<<": "<< G->arcs[i][j]<<endl;
        }
    }

}
MGraph *CreateMGraph()
{
    int i, j, w;
    MGraph *G;
    int n,m;//顶点个数  边的个数
    G = (MGraph *)malloc(sizeof(MGraph));   //建立图的存储结构
    printf("\n输入图G的顶点个数 边数 ");
    cin>>n>>m;
    G->vn=n;
    G->en=m;
    for(i = 1; i <= G->vn; i++) {
        G->vexs[i].no = i;
        
    }

    for(i = 1; i <= G->vn; i++)
        for(j = 1; j <= G->vn; j++)
            G->arcs[i][j] = INF;
    for(  i=1; i<=n; i++)
        for( j=1; j<=n; j++)
            G->arcs[i][j]=(i==j)?0:INF;

    for( i=1; i<=m; i++) {
        int t1,t2,d;//位置t1到位置t2的距离是d
        cin>>t1>>t2>>d;
        // G->arcs[t1][t2]=G->ar[t2][t1]=d;//无向图
        G->arcs[t1][t2]=d;//-----------------有向图
    }
    printf("\n图的存储建立完毕!\n");
    return  G;
}
int main()
{
    MGraph *G;
    G = CreateMGraph();
    Floyd(G);
    Dijkstra(G);
    Inquiry(G);
    system("pause");
    return 0;
}

六、程序测试及运行结果

5.1 运行实例一
(求给定有向图3-1的最短路径)
在这里插入图片描述
具体要求之一:求顶点 到其余顶点的最短路径;分别求顶点b到顶点d之间的最短路径、顶点 到顶点d之间的最短路径。
在这里插入图片描述提示:为了操作方便,对于图的顶点都是用序号来表示的,所以顶点的字母就用其对应的序号来操作如 用1来代替用1来代替
5.2 运行实例二
(求给定无向图3-2的最短路径)
在这里插入图片描述图3-2 一个简单的交通网络图
图3-2 是一个简单的交通网络图。
具体要求之一:求顶点“北京”到其余各城市之间的最短路径;并分别求“成都”到“上海”之间以及“上海”到“西安”之间的最短路径。
提示:为了操作方便,对于图的顶点都是用序号来表示的,所以顶点的城市名称就用其对应的编号来操作:如北京用1来代替,……。

在这里插入图片描述

七、心得体会

  1. 迪杰斯特拉算法是从一个顶点到其余各顶点的最短路径算法,解决的是有权图中最短路径问题。迪杰斯特拉算法主要特点是从起始点开始,用一个数组int[ ]dist保存起点到其余各点的最短路径距离,采用贪心算法的策略,每次遍历到起点距离最近且未访问过的顶点的邻接节点并不断更新dist数组,直到扩展到终点为止。
  2. 弗洛伊德算法定义了两个二维矩阵:
    矩阵D记录顶点间的最小路径
    例如D[0][3]= 10,说明顶点0 到 3 的最短路径为10;
    矩阵P记录顶点间最小路径中的中转点
    例如P[0][3]= 1 说明,0 到 3的最短路径轨迹为:0 -> 1 -> 3。
    它通过3重循环,k为中转点,v为起点,w为终点,循环比较D[v][w] 和 D[v][k] + D[k][w] 最小值,如果D[v][k] + D[k][w] 为更小值,则把D[v][k] + D[k][w] 覆盖保存在D[v][w]中。
  3. 弗洛伊德算法作为求最短路径的经典算法,其算法实现相比迪杰斯特拉等算法是非常优雅的,可读性和理解都非常好。
  • 2
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
设计、实现一个全国大城市间的交通咨询程序,为旅客提供三种最优决策方案:一是建立交通网络图的存储结构,二实现两个城市间的最短路经问题。程序所具有的功能特色本程序主要目的是为了给用户提供路径咨询。实现了帮助用户了解全国各大城市间往来的最短路径问题,第二,可以提供用户查询各大城市的相关信息。本程序最大的特点是支持用户自己添加城市信息及城市,或添加城市的路径,既就有可扩展性 该程序所做的工作的是模拟全国交通咨询,为旅客提供三种最优决策的交通咨询。此程序规定: (1) 在程序中输入城市名称时,需输入10个字母以内的字母串;输入列车或飞机编号时需输入一个整型数据;输入列车或飞机的费用时需输入一个实型数据;输入列车或飞机开始时间和到达时间时均需输入两个整型数据(以hh:mm的形式);在选择功能时,应输入与所选功能对应的一个整型数据。 (2) 程序的输出信息主要是:最快需要多少时间才能到达,或最少需要多少旅费才能到达,或最少需要多少次中转到达,并详细说明依次于何时乘坐哪一趟列车或哪一次班机到何地。 (3) 程序的功能包括:提供对城市信息的编辑,提供列车时刻表和飞机航班表的编辑,提供三种最优决策:最快到达、最省钱到达、最少中转次数到达。
### 回答1: 基于C的全国交通咨询系统是一个用C语言开发的软件系统,旨在帮助用户查询和获取全国各地交通信息的系统。这个系统主要包括数据库、用户界面以及查询和显示模块。 首先,系统中的数据库可以存储全国各地的交通信息,如高速公路、铁路、航班等。通过C语言的数据库操作函数,我们可以实现数据的增删改查功能,方便用户进行交通信息的查询和更新。 其次,系统的用户界面可以通过C语言的图形界面库实现,将交通信息以直观、友好的方式展示给用户。用户可以通过地图选择特定城市或地区,然后在界面上选择所需交通信息,如路况、车票等。 另外,查询和显示模块是系统的核心功能之一。通过C语言的编程技术,我们可以实现不同查询功能的函数,如根据用户输入的起点和终点查询最佳交通路线,或者根据用户输入的日期和目的地查询航班信息。查询结果可以通过用户界面以图表、列表或文本等形式展示给用户。 需要注意的是,基于C的全国交通咨询系统还可以考虑与其他软件或系统的集成,例如与地图导航软件、天气预报系统等进行数据共享,提供更加全面、准确的交通信息。 总之,基于C的全国交通咨询系统以其高效、稳定的性能,能够为用户提供便捷、准确的交通信息查询服务,满足人们日常出行的需求。 ### 回答2: 基于C的全国交通咨询系统可以采用C语言编程来开发。该系统旨在为用户提供全国范围内的交通相关咨询服务,包括交通路线规划、交通实时情况、交通事故信息等。 系统中可以设计一个交互式的命令行界面,通过该界面用户可以输入查询指令,并获取相应的交通信息。通过C语言的编程,可以利用各种算法和数据结构实现对用户输入的指令进行解析和处理。 为了实现交通路线规划功能,可以利用C语言中的图算法来构建交通网络模型,并通过最短路径算法等技术来实现两个地点之间的最佳路线规划。 为了实现交通实时情况功能,可以利用C语言中的网络编程功能,通过获取交通监控数据接口的方式,实时获取各个地区的交通实时情况,并将其展示给用户。 为了实现交通事故信息功能,可以利用C语言中的文件读写功能,将各个地区的交通事故信息存储在文件中,并通过解析文件数据的方式获取事故信息,然后将其展示给用户。 在设计交通咨询系统时,还需要考虑用户登录、注册等功能,以及用户反馈和系统管理等功能。 总之,基于C的全国交通咨询系统可以通过利用C语言的各种特性和功能来实现用户的交通信息查询需求,并通过合理的算法设计和数据结构来提供准确、实时的交通咨询服务。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

@小冯@

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

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

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

打赏作者

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

抵扣说明:

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

余额充值