问题描述:
设计一个交通咨询系统,为自驾游旅行者客咨询从任一个城市到另一个城市之间的最短路径问题。设计分三个部分,一是建立交通网络图的存储结构;二是解决单源最短路径问题;最后再实现两个城市顶点之间的最短路径问题。
基本要求:
(1)对城市信息(城市名、城市间的里程)进行编辑:具备添加、修改、删除功能;
(2)咨询以用户和计算机对话方式进行,要注意人机交互的屏幕界面。由用户选择输入起点、终点,输出信息:旅行者从起点、终点经过的每一座城市。
(3)主程序可以有系统界面、菜单;也可用命令提示方式;选择功能模块执行,要求在程序运行过程中可以反复操作。
编写目的:
本博客是解决“交通咨询问题”程序的组成部分,编写此文档的目的是:确定本程序的程序结构、数据的数据结构,以及相关算法,用来作为后期程序改进的参照。本文档的读者对象是:需求人员、程序设计员,测试人员。
详细设计:
1.声明
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_VEX t
char cName[100][255];
char adjMatrix[100][100];//存城市号?
char start_point[100][255],final_point[100][255];
char a[100],m[100];
static int A[100][100];
int t=0;
int n,d,dist[100],b,k;//用来存暂时的数,d,dist存城市距离
bool final[100];
int pre[100] , dis[100] ;
int Ad[100][100] ;
int Path[100][100] ;
2.添加
void compare_city()
{
for(int j=0;j<t;j++)
{
if(strcmp(a,cName[j])== 0)
{
printf("该城市已存在!请输入其他城市:\n");
scanf_s("%s",&a);
break;
}
}
}
void add_city()
{
for(static int i=0;i<255;i++)
{
scanf("%s",&a);
for(int j=0;j<t;j++)
{
if(strcmp(a,cName[j])== 0)
{
printf("该城市已存在!请输入其他城市:\n");
scanf("%s",&a);
compare_city();
break;
}
}
if(strcmp(a,"quit")== 0)
{
printf("退出添加城市!\n");
i--;
break;
}
else
{
strcpy(cName[i],a);
printf("添加成功|,请继续添加!\n");
t++;
}
}
initial_matrix();//添加完成后初始化邻接矩阵
}
void initial_matrix()
{
for(int i=0;i<t;i++)
{
for(int j=0;j<t;j++)
{
if(i==j)A[i][j]=0;
else
A[i][j]=65535;
}
}
}
3.删除
void remove_city()
{
scanf("%s",&a);
for(int i=0;i<255;i++)
{
if(strcmp(a,"quit")== 0)
{
printf("退出删除城市!\n");
break;
}
if(strcmp(cName[i],a)== 0)
{
for(i;i<t-1;i++)
{
strcpy(cName[i],cName[i+1]);
}
cName[t-1][255]=NULL;
printf("城市删除成功!还需删除请再次操作!\n");
t--;
initial_matrix();
printf("请重新对各城市进行编辑:\n");
printf("\n");
break;
}
if(i==t)
{
printf("请输入已经存在的城市名!\n");
remove_city();
break;
}
}
}
4.编辑
void editc_info()
{
for(int i=0;i<255;i++)
{
printf("选择需要更改的城市名?(输入“不更改”进入创建城市图):");
scanf("%s",&a);
if(strcmp(a,"不更改")== 0)
{
printf("退出编辑城市名!\n");
break;
}
else
{
printf("更改为城市:");
scanf("%s",&m);
for(int j=0;j<255;j++)
{
if(strcmp(cName[j],a)== 0)
{
strcpy(cName[j],m);
break;
}
else if(j==t)
{
printf("您输入的城市不存在!请再次输入:\n");
editc_info();
break;
}
}
}
}
printf("*******************************************************\n");
printf("* 请编辑%d个城市之间的关系 *\n",t);
printf("* 即写出各城市之间的路径与距离 *\n");
printf("* 建立起城市关系图 *\n");
printf("*******************************************************\n");
printf("你想创建几条路径: ");
scanf("%d",&b);
if(b<=(t*(t-1))/2)
{
if(b==0){}
else
{
printf("请输入%d条路径信息如下: \n",b);
printf("起点城市 终点城市 路径长度\n");
for(int i=0;i<b;i++)
{
scanf("%s",&start_point[i]);
scanf("%s",&final_point[i]);
scanf("%d",&dist[i]);
}
adjacency_matrix();
printf("城市图建立完成! \n");
}
}
else
{
printf("输入的条数过多! \n");
create_path();
}
}
void create_path()
{
printf("你想创建几条路径:");
scanf_s("%d",&n);
if(n<=(t*(t-1))/2)
{
printf("请输入%d条路径信息如下:\n",n);
printf("起点城市 终点城市 路径长度¨¨\n");
for(int i=0;i<n;i++)
{
scanf_s("%s",&a);
}
}
else
{
printf("输入的条数过多!");
create_path();
}
}
5.显示
void display_city()
{
for(int i=0;i<t;i++)
{
printf("%d %s\n",i,cName[i]);
}
}
void buildCharm()
{
int i,j;
for(i=0;i<t;i++)
{
for(j=0;j<t;j++)
{
printf("%d\t",A[i][j]);
if(j==t-1)
{
printf("\n");
}
}
}
}
6.构建
void adjacency_matrix()
{
int i,j,m,n;
initial_matrix();
for(i=0;i<b;i++)
{
for(j=0;j<t;j++)
{
if(strcmp(start_point[i],cName[j])== 0)
{
m=j;
}
if(strcmp(final_point[i],cName[j])== 0)
{
n=j;
}
}
A[m][n]=A[n][m]=dist[i];
}
}
7.单源最短路
void Dijkstra_path (int v)
/* 从顶点出发到其余各顶点的最短路径 */
{
int j, k, m, s;
for ( j=0; j<t; j++)
{
pre[j]=v; final[j]=0;
dis[j]=A[v][j] ;
} /* 各数组的初始化 */
dis[v]=0 ; final[v]=1; /* 设置S={v} */
for ( j=0; j<t-1; j++ ) /* 其余n-1个顶点 */
{
static int min=65535;
for ( k=0; k<t; k++ )
{
if ( !final[k] && (dis[k]<min))
{
min=dis[k] ; m=k ;
}
} /* 求出当前最小的dis[k]值 */
final[m]=1; /* 将第k个顶点并入S中 */
for ( j=0; j<t; j++)
{
if ( !final[j] &&( dis[m]+A[m][j]<dis[j]))
{
dis[j]=dis[m]+A[m][j] ;
pre[j]=m ;
}
} /* 修改dist和pre数组的值 */
} /* 找到最短路径 */
printf("%s到其他各城市的最短路径如下:\n",cName[v]);
for(int w=0;w<t;w++)
{
int g;
g=w;
printf("%s - %s 最短径?为: %d ",cName[v],cName[w],dis[w]);
s=pre[g]; //获得第一个路径顶点下标
printf(" 路径为a:%s <- ",cName[w]); //打印终点
while(s!=v) //如果路径顶点下标不是终点
{
printf("%s <-",cName[s]); //打印路径顶点
s=pre[--g]; //得下?个路径顶点下标
}
printf(" %s",cName[v]); //打印源点
printf("\n");
}
}
8.多源最短路
void prn_pass(int j , int k)
{
if (Path[j][k]!=-1)
{
prn_pass(j, Path[j][k]) ;
printf("-> %s",cName[Path[j][k]]) ;
prn_pass(Path[j][k], k) ;
}
}
void Floyd_path()
{
int j, k, m ;
for ( j=0; j<t; j++)
{
for ( k=0; k<t; k++)
{
Ad[j][k]=A[j][k] ; Path[j][k]=-1 ;
}
}
/* 各数组的初始化 */
for ( m=0; m<t; m++)
{
for ( j=0; j<t; j++)
{
for ( k=0; k<t; k++)
{
if ((Ad[j][m]+Ad[m][k])<Ad[j][k])
{
Ad[j][k]=Ad[j][m]+Ad[m][k] ;
Path[j][k]=m ;
} /* 修改数组A和Path的元素值 */
}
}
}
for ( j=0; j<t; j++)
{
for ( k=0; k<t; k++)
{
if (j!=k)
{
printf("%s到%s的最短路径为:", cName[j], cName[k]) ;
printf("%s ",cName[j]) ;
prn_pass(j, k) ;
printf("->%s",cName[k]) ;
printf("\t最短路径长度为: %d\n",Ad[j][k]);
}
}
}
}
运行结果:
总结:
为了满足民众在出行时的需求,用Dijkstra算法和Floyd算法,设计实现了交通咨询系统,能求得两城市之间的最短路径问题。该系统操作简单,能较好满足民众在出行时需要得到的信息,以达到人们省时省钱的目的。当然系统仍然存在不足,运行时还是会出现一些问题,来不及去修复,问题主要是存储方面的问题,在以后有时间的话,将对这些问题进行修复。在编写代码的过程中遇到了很多的坎坷,需要我一步一步的修改,一步一步的完善自己的代码,在这个过程中,我学到了很多也收获了很多,我凭自己的付出得到了相应的成果,这是我最值得高兴的。
(第一次写,多有不足,望各位批评指正)