全国交通咨询模拟系统实验报告
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
全国交通咨询模拟系统
实验报告
Company Document number:WUUT-WUUY-WBBGB-BWYTT-1982GT
一、问题描述全国交通咨询模拟:处于对不同目的的旅客对交通工具有不同的要求。
例如,因公出差的旅客希望在旅途中的时间尽可能短,出门旅游的游客则希望旅费尽可能省,而老年旅客则要求中转次数最少。
编制一个全国城市间的交通咨询程序,为旅客提供两种或三种最优决策的交通咨询。
【基本要求】(1)提供对城市信息进行编辑(如:添加或删除)的功能。
(2)城市之间有两种交通工具:火车和飞机。
提供对列车时刻表和
飞机航班进行编辑(增设或删除)的功能。
(3)提供两种最优决策:最快到达或最省钱到达。
全程只考虑一种
交通工具。
(4)旅途中耗费的总时间应该包括中转站的等候时间。
(5)咨询以用户和计算机的对话方式进行。
由用户输入起始站、终
点站、最优决策原则和交通工具,输出信息:最快需要多长时
间才能到达或者最少需要多少旅费才能到达,并详细说明依次
于何时乘坐哪一趟列车或哪一次班机到何地。
二、
1、根据题目中的基本要求分析,可以创建系统概念模型,流程设计框图如下:
班次
辑结构拆分:
而为了便于数据的存储、添加、删除等操作,我选择了储存文件对这些数据进行了存储。
将每个信息量放在不同的文件中,可以更有效、直观地对这些数据进行处理。
流程图中的7个主要功能模块在主函数中,采用输入选项进入子菜单,但是其他操作都是在路线添加好后进行的,并且为了每一项功能进行完后,系统可以及时回到主交互界面,我采用的是无限循环形式,即while(1)。
以邻接表作交通图的存储结构,表示边的结点内除含有邻接点的信息外,包括交通工具、路程中消耗的时间和花费以及出发和到达的时间等多项属性。
三、主控及功能模块层次结构:
1、模块说明:本系统分为个模块
1、)主函数
2、)添加城市
3、)查找城市并返回序号
4、)删除城市
5、)添加列车
6、)添加航班
7、)删除列车或航班
8、)找出最小费用路线
9、)初始化系统数据(读入内存)
10、)找出最快路线
11、)计算最快路线耗费的时间并打印
12、)计算最小费用路线
13、)主界面
14、)存储信息到文件
15、)退出、
2、下面是各模块示意图:
基本操作:
函数变量声明:
#include <>
#include <>
#define ERR 0
#define OK 1
#define Dij_MAXN 33
#define MAX_VERTEX_NUM 31
#define MAX_STRING_NUM 10
#define MAX_TRAFFIC_NUM 10
const char CityFile[] ="D:\\";
const char TrainFile[] ="D:\\";
const char FlightFile[] ="D:\\";
typedef short int CityType;
typedef struct TrafficNode
{
char name[MAX_STRING_NUM]; rainNum;
}
fprintf(fp,"%d\n",total);
for (i=0;i<CityNum;i++)
{
for (j=0;j<AdjList[i].TrainNum;j++)
{
fprintf(fp,"%s %s %s ", AdjList[i].Train[j].name,
CityName[i],
CityName[AdjList[i].Train[j].EndCity]);
fprintf(fp,"%2d:%2d %2d:%2d %d\n", AdjList[i].Train[j].StartTime/60, AdjList[i].Train[j].StartTime%60,
AdjList[i].Train[j].StopTime/60,
AdjList[i].Train[j].StopTime%60,
AdjList[i].Train[j].Cost);
}
}
fclose(fp);total=0;
fp=fopen(FlightFile,"w");
for (i=0;i<CityNum;i++)
{
total+=AdjList[i].FlightNum;
}
fprintf(fp,"%d\n",total);
for (i=0;i<CityNum;i++)
{
for (j=0;j<AdjList[i].FlightNum;j++)
{
fprintf(fp,"%s %s %s ", AdjList[i].Flight[j].name,
CityName[i],
CityName[AdjList[i].Flight[j].EndCity]);
fprintf(fp,"%2d:%2d %2d:%2d %d\n", AdjList[i].Flight[j].StartTime/60, AdjList[i].Flight[j].StartTime%60,
AdjList[i].Flight[j].StopTime/60,
AdjList[i].Flight[j].StopTime%60,
AdjList[i].Flight[j].Cost);
}
}
fclose(fp);return 1;
}
(4)添加城市:
int InsertCity (char *Name)
{
strcpy(CityName[CityNum],Name);
AdjList[CityNum].city=CityNum;
AdjList[CityNum].FlightNum=0;
AdjList[CityNum].TrainNum=0;
CityNum++;
return 1;
}
(5)删除城市:
int DelCity (char *Name)
{
int city,i,j;
city=SeekCity(Name);
for (i=city;i<CityNum-1;i++)
{
strcpy(CityName[i],CityName[i+1]);
AdjList[i].FlightNum=AdjList[i+1].FlightNum;
AdjList[i].TrainNum=AdjList[i+1].TrainNum;
for (j=0;j<AdjList[i].FlightNum;j++)
{
AdjList[i].Flight[j].Cost=AdjList[i+1].Flight[j].Cost;
AdjList[i].Flight[j].EndCity=AdjList[i+1].Flight[j].EndCity;
strcpy(AdjList[i].Flight[j].name,AdjList[i+1].Flight[j].name);
AdjList[i].Flight[j].StartTime=AdjList[i+1].Flight[j].StartTime; AdjList[i].Flight[j].StopTime=AdjList[i+1].Flight[j].StopTime;
}
}
CityNum--;
return 1;
}
(6)添加火车路线:
int InsertTrain (char *train,char *StartCity,char *EndCity,int StartTime,int EndTime,int cost)
{
int i,j;
i=SeekCity(StartCity);
j=SeekCity(EndCity);
AdjList[i].Train[AdjList[i].TrainNum].Cost=cost;
AdjList[i].Train[AdjList[i].TrainNum].EndCity=j;
AdjList[i].Train[AdjList[i].TrainNum].StartTime=StartTime;
AdjList[i].Train[AdjList[i].TrainNum].StopTime=EndTime;
strcpy(AdjList[i].Train[AdjList[i].TrainNum].name,train);
AdjList[i].TrainNum++;
return 1;
}
(7)添加航班路线:
int InsertFlight(char *flight,char *StartCity,char *EndCity,int StartTime,int EndTime,int cost)
{
int i,j;
i=SeekCity(StartCity);
j=SeekCity(EndCity);
AdjList[i].Flight[AdjList[i].FlightNum].Cost=cost;
AdjList[i].Flight[AdjList[i].FlightNum].EndCity=j;
AdjList[i].Flight[AdjList[i].FlightNum].StartTime=StartTime;
AdjList[i].Flight[AdjList[i].FlightNum].StopTime=EndTime;
strcpy(AdjList[i].Flight[AdjList[i].FlightNum].name,flight);
AdjList[i].FlightNum++;
return 1;
}
(8)删除路线:
int DelPath (char *name)
{
int i,j,flag=0;
for (i=0;i<CityNum;i++)
{
for (j=0;j<AdjList[i].FlightNum;j++)
if (strcmp(AdjList[i].Flight[j].name,name)==0)
{
flag=1;
break;
}
if (flag)
{
for (;j<AdjList[i].FlightNum-1;j++)
{
AdjList[i].Flight[j].Cost=AdjList[i].Flight[j+1].Cost;
AdjList[i].Flight[j].EndCity=AdjList[i].Flight[j+1].EndCity;
strcpy(AdjList[i].Flight[j].name,AdjList[i].Flight[j+1].name); AdjList[i].Flight[j].StartTime=AdjList[i].Flight[j+1].StartTime; AdjList[i].Flight[j].StopTime=AdjList[i].Flight[j+1].StopTime;
}
AdjList[i].FlightNum--;
break;
}
for (j=0;j<AdjList[i].TrainNum;j++)
if (strcmp(AdjList[i].Train[j].name,name)==0)
{
flag=1;break;
}
if (flag)
{
for (;j<AdjList[i].TrainNum-1;j++)
{
AdjList[i].Train[j].Cost=AdjList[i].Train[j+1].Cost;
AdjList[i].Train[j].EndCity=AdjList[i].Train[j+1].EndCity;
strcpy(AdjList[i].Train[j].name,AdjList[i].Train[j+1].name);
AdjList[i].Train[j].StartTime=AdjList[i].Train[j+1].StartTime;
AdjList[i].Train[j].StopTime=AdjList[i].Train[j+1].StopTime;
}
AdjList[i].TrainNum--;
break;
}
}
return 1;
}
(9)打印最小费用路线:
void Dijkstra_Output(int matx[Dij_MAXN][Dij_MAXN],int PreCity[Dij_MAXN],int
p_end,int TravelType)
{
int track[Dij_MAXN];
int i=0,j,k,min,tmp,end,cost=0;
int startH, startM, endH, endM;rainNum;k++)
if
(AdjList[track[i]].Train[k].EndCity==end&&min>AdjList[track[i]].Train[k].Cost)
{
min=AdjList[track[i]].Train[k].Cost;
tmp=k;
}
printf("%s ",AdjList[track[i]].Train[tmp].name);
startH = AdjList[track[i]].Train[tmp].StartTime/60 ;
startM =
AdjList[track[i]].Train[tmp].StartTime%60;
endH = AdjList[track[i]].Train[tmp].StopTime/60 ;
endM = AdjList[track[i]].Train[tmp].StopTime%60 ;
if( !(startH/10) )
{
printf("0");
}
printf("%d:",startH);
if( !(startM/10) )
{
printf("0");
}
printf("%d -- ",startM);
if( !(endH/10) )
{
printf("0");
}
printf("%d:",endH);
if( !(endM/10) )
{
printf("0");
}
printf("%d\n",endM);
rain[tmp].StartTime/60,AdjList[track[i]].Train[tmp].StartTime%60,AdjList[track[i]].Tr ain[tmp].StopTime/60,AdjList[track[i]].Train[tmp].StopTime%60);
}
}
else
{
for(i--;i>0;i--)
{
printf("\n%s:",CityName[track[i]]);
end=track[i-1];min=32767;
for (k=0;k<AdjList[track[i]].FlightNum;k++)
rain[k].EndCity改为
AdjList[track[i]].Flight[k].EndCity!
/*if
(AdjList[track[i]].Train[k].EndCity==end&&min>AdjList[track[i]].Flight[k].Cost)
{ */
if
(AdjList[track[i]].Flight[k].EndCity==end&&min>AdjList[track[i]].Flight[k].Cost)
{
min=AdjList[track[i]].Flight[k].Cost;
tmp=k;
}
printf("%s",AdjList[track[i]].Flight[tmp].name);
startH =
AdjList[track[i]].Flight[tmp].StartTime / 60 ;
startM =
AdjList[track[i]].Flight[tmp].StartTime % 60;
endH =
AdjList[track[i]].Flight[tmp].StopTime / 60 ;
endM =
AdjList[track[i]].Flight[tmp].StopTime % 60 ;
if( !(startH/10) )
{
printf("0");
}
printf("%d:",startH);
if( !(startM/10) )
{
printf("0");
}
printf("%d -- ",startM);
if( !(endH/10) )
{
printf("0");
}
printf("%d:",endH);
if( !(endM/10) )
{
printf("0");
}
printf("%d\n",endM);
light[tmp].StartTime / 60,AdjList[track[i]].Flight[tmp].StartTime %
60,AdjList[track[i]].Flight[tmp].StopTime / 60,AdjList[track[i]].Flight[tmp].StopTime % 60);
}
}
printf("\n%s: DESTINATION!",CityName[track[0]]);
printf("\nMin Cost : %d\n",cost);
}
(10)找出最小费用路线
void Dijkstra(int matx[Dij_MAXN][Dij_MAXN],int p_start,int p_end,int TravelType) {
int PreCity[Dij_MAXN]; .\n");
return -1;
}
fscanf(fp,"%d",&CityNum);
for (i=0;i<CityNum;i++)
{
fscanf(fp,"%s",&CityName[i]);
AdjList[i].city=i;
AdjList[i].TrainNum=0;
AdjList[i].FlightNum=0;
}
fclose(fp);
fp=fopen(TrainFile,"r");
if (!fp)
{
printf("\nError:Cannot Open Train File...\n");
return -1;
}
fscanf(fp,"%d",&num);
for (i=0;i<num;i++)
{
fscanf(fp,"%s",&stmp1);
fscanf(fp,"%s",&stmp2);
fscanf(fp,"%s",&stmp3);
j=SeekCity(stmp2);
AdjList[j].Train[AdjList[j].TrainNum].EndCity=SeekCity(stmp3); strcpy(AdjList[j].Train[AdjList[j].TrainNum].name,stmp1);
fscanf(fp,"%d:%d",&hour,&minute);
AdjList[j].Train[AdjList[j].TrainNum].StartTime=hour*60+minute; fscanf(fp,"%d:%d",&hour,&minute);
AdjList[j].Train[AdjList[j].TrainNum].StopTime=hour*60+minute; fscanf(fp,"%d",&cost);
AdjList[j].Train[AdjList[j].TrainNum].Cost=cost;
AdjList[j].TrainNum++;
}
fclose(fp);
fp=fopen(FlightFile,"r");
if (!fp)
{
printf("\nError:Cannot Open Flight File...\n");
return -1;
}
fscanf(fp,"%d",&num);
for (i=0;i<num;i++)
{
fscanf(fp,"%s",&stmp1);
fscanf(fp,"%s",&stmp2);
fscanf(fp,"%s",&stmp3);
j=SeekCity(stmp2);
AdjList[j].Flight[AdjList[j].FlightNum].EndCity=SeekCity(stmp3); strcpy(AdjList[j].Flight[AdjList[j].FlightNum].name,stmp1);
fscanf(fp,"%d:%d",&hour,&minute);
AdjList[j].Flight[AdjList[j].FlightNum].StartTime=hour*60+minute; fscanf(fp,"%d:%d",&hour,&minute);
AdjList[j].Flight[AdjList[j].FlightNum].StopTime=hour*60+minute; fscanf(fp,"%d",&cost);
AdjList[j].Flight[AdjList[j].FlightNum].Cost=cost;
AdjList[j].FlightNum++;
}
fclose(fp);
return 1;
}
(12)找出最快路线:
int SearchMinTime (CityType City,CityType EndCity,int CurTime,int curPathNo,int TravelType)
{
int i;
if (City==EndCity)
{
if (MinTime>CurTime-StartTime)
{
for (i=0;i<=curPathNo;i++)
{
MinPath[i].City=Path[i].City;
MinPath[i].TraNo=Path[i].TraNo;
curPath=curPathNo;
}
MinTime=CurTime-StartTime;
}
}
else
{
curPathNo++;
Path[curPathNo].City=City;
if (!TravelType)
{
for (i=0;i<AdjList[City].TrainNum;i++)
{
if
((AdjList[City].Train[i].StartTime>=(CurTime%1440))&&(AdjList[City].Train[i].StopT ime+(CurTime/1440)*1440-StartTime<MinTime))
{
Path[curPathNo].TraNo=i;
SearchMinTime(AdjList[City].Train[i].EndCity,EndCity,AdjList[City].Train[i].StopTim e+(CurTime/1440)*1440,curPathNo,TravelType);
}
if
((AdjList[City].Train[i].StartTime<(CurTime%1440))&&(AdjList[City].Train[i].StopTi me+(CurTime/1440)*1440-StartTime<MinTime))
{
Path[curPathNo].TraNo=i;
SearchMinTime(AdjList[City].Train[i].EndCity,EndCity,AdjList[City].Train[i].StopTim e+(CurTime/1440+1)*1440,curPathNo,TravelType);
}
}
}
else
{
for (i=0;i<AdjList[City].FlightNum;i++)
{
if
((AdjList[City].Flight[i].StartTime>=CurTime)&&(AdjList[City].Flight[i].StopTime+(C urTime/1440)*1440-StartTime<MinTime))
{
Path[curPathNo].TraNo=i;
SearchMinTime(AdjList[City].Flight[i].EndCity,EndCity,AdjList[City].Flight[i].StopTi me+(CurTime/1440)*1440,curPathNo,TravelType);
}
if
((AdjList[City].Flight[i].StartTime<CurTime)&&(AdjList[City].Flight[i].StopTime+(Cur Time/1440)*1440-StartTime<MinTime))
{
Path[curPathNo].TraNo=i;
SearchMinTime(AdjList[City].Flight[i].EndCity,EndCity,AdjList[City].Flight[i].StopTi me+(CurTime/1440+1)*1440,curPathNo,TravelType);
}
}
}
}
return 1;
}
(13)计算最快路线所需时间并打印:
int CalcMinTime (int StartCity,int EndCity,int TravelType)
{
int i;
int startH, startM, endH, endM;ity=StartCity;
if (!TravelType)
{
for (i=0;i<AdjList[StartCity].TrainNum;i++)
{
Path[0].TraNo=i;
StartTime=AdjList[StartCity].Train[i].StartTime;
SearchMinTime(AdjList[StartCity].Train[i].EndCity,EndCity,AdjList[StartCity].Train[i ].StopTime,0,TravelType);
}
}
else
{
for (i=0;i<AdjList[StartCity].FlightNum;i++)
{
Path[0].TraNo=i;
StartTime=AdjList[StartCity].Flight[i].StartTime;
SearchMinTime(AdjList[StartCity].Flight[i].EndCity,EndCity,AdjList[StartCity].Flight[ i].StopTime,0,TravelType);
}
}
if (MinTime==32767)
{
printf("\nNo access to that destination!");
return 0;
}
rain[MinPath[0].TraNo].StartTime;
light[MinPath[0].TraNo].StartTime;
printf("\nPath:\n");
for (i=0;i<=curPath;i++)
{
if (!TravelType)
printf("%s : %s
",CityName[MinPath[i].City],AdjList[MinPath[i].City].Train[MinPath[i].TraNo].name); else
printf("%s : %s
",CityName[MinPath[i].City],AdjList[MinPath[i].City].Flight[MinPath[i].TraNo].name);
startH =
AdjList[MinPath[i].City].Train[MinPath[i].TraNo].StartTime / 60 ;
startM =
AdjList[MinPath[i].City].Train[MinPath[i].TraNo].StartTime % 60 ;
endH =
AdjList[MinPath[i].City].Train[MinPath[i].TraNo].StopTime / 60 ;
endM =
AdjList[MinPath[i].City].Train[MinPath[i].TraNo].StopTime % 60 ;
if( !(startH/10) )
{
printf("0");
}
printf("%d:",startH);
if( !(startM/10) )
{
printf("0");
}
printf("%d -- ",startM);
if( !(endH/10) )
{
printf("0");
}
printf("%d:",endH);
if( !(endM/10) )
{
printf("0");
}
printf("%d\n",endM);
rainNum)
{
min=32767;
end=AdjList[i].Train[j].EndCity;
while
(end==AdjList[i].Train[j].EndCity&&j<AdjList[i].TrainNum)
{
if (AdjList[i].Train[j].Cost<min)
{
min=AdjList[i].Train[j].Cost;
}
j++;
}
ma[i][end]=min;
}
}
}
else
{
for (i=0;i<CityNum;i++)
{
min=32767;j=0;
while (j<AdjList[i].FlightNum)
{
min=32767;
end=AdjList[i].Flight[j].EndCity;
while
(end==AdjList[i].Flight[j].EndCity&&j<AdjList[i].FlightNum)
{
if (AdjList[i].Flight[j].Cost<min)
{
min=AdjList[i].Flight[j].Cost;
}
j++;
}
ma[i][end]=min;
}
}
}
Dijkstra(ma,StartCity,EndCity,TravelType);
return 1;
}
五、功能模块间函数的调用关系,如下图所示:
1、主界面:
2、添加城市:输入命令1后,按提示输入城市名,而后返回主界面
原city文件:
添加城市后的city文件:
3、删除城市:输入命令2后,按提示输入城市名,而后返回主界面
4、添加路线:输入命令3后,按提示依次输入起始站、终点站、类型、起始时刻、到达时刻、票价等信息,而后返回主界面
添加路
线后的train文件:
5、删除路线:输入命令4后,按提示输入,而后返回主界面
删除路线后的train文件:
6、查找最小费用花费:输入命令5后,按提示输入起始城市、终点城市、类型,而后返回主界面
结果正确!
7、查找最小时间花费:输入命令6后,按提示输入城市名,而后返回主界
面
结果正确!
8、退出:输入命令0后,退出系统
七、课程设计小结:
1、实验过程中的注意点
1)遇到逻辑问题,然后设断点,调试跟踪看哪步出了问题.比如说全局变量和局部变量设置出现问题,导致运行过程各变量的取值不对。
2)使用全局变量和局部变量时,要注意他们的作用范围和使用方法。
全局变量作用于整个程序,局部变量作用于函数内部。
3)函数里面调用之后定义的函数时要在前面声明。
4)注意指针的使用。
在应用指针时,要注意判断结点是否为空,为空的话要给其分配地址,而不用的结点要用"free"回收地址空间
5)注意switch条件判断语句的使用规则。
每个case结束后都要break 一下,不然会继续执行下一个case的.
2、实验体会
1)数据结构的基础知识欠缺,不够扎实。
2)平时缺少编程练习,代码输入不熟练,经常要翻书查找一些基本的语法。
比如函数之间的互相调用,在函数有形参时,互相调用经常出错。
对文件的操作还是没有完全掌握。
3)程序是写出来的,不是想出来的。
开始阶总是在想,总感觉很困难做不了,但是真正投入其中之后才发觉其实只要用心,只要有克服一切的勇气和信心就可以把程序做好,错误总是越改越少的。
4)要用愉悦的心情去做,从编程的过程中体会乐趣,兴趣是最好的老师。
当费劲地解决掉编译错误、程序能顺利的实现预定功能时,心里还是很有些自豪和成就感的。
5)学会利用辅助程序去发现问题
3、课程设计小结:
通过这次课程设计,虽然程序设计和调试能力有所提升,但虽然最终还是没能独立完成课程设计的课程要求,其中某个功能没能得以实现,没能独立作出此次要求的全国交通咨询模拟系统。
这次课程设计也使我认识到了我在程序设计方面的严重不足,以及专业知识的严重匮乏。
我的程序设计思想和代码的编写和调试能力在此次课程设计期间有所提高。
这样一种更贴近实际的课程设计,大大地提高了我的学习效率,希望能够在平时教学中也能加入一些类似的课程设计的程序设计题。