实现一个帮助进行地铁出行路线规划的命令行程序。
GitHub项目地址:
https://github.com/ldjkwx/TianJing-Subway
程序由Java语言编写,利用Dijkstra算法实现路径的选择,模块间的依赖关系如下图:
估计开发时间如下图:
PSP 2.1 | Personal Software Process Stages | Time |
---|---|---|
Planning | 计划 | |
· Estimate | · 估计这个任务需要多少时间 | 18 |
Development | 开发 | |
· Analysis | · 需求分析 (包括学习新技术) | 1 |
· Design Spec | · 生成设计文档 | 1 |
· Design Review | · 设计复审 (和同事审核设计文档) | 1 |
· Coding Standard | · 代码规范 (为目前的开发制定合适的规范) | 1 |
· Design | · 具体设计 | 1 |
· Coding | · 具体编码 | 5 |
· Code Review | · 代码复审 | 2 |
· Test | · 测试(自我测试,修改代码,提交修改) | 2 |
Reporting | 报告 | |
· Test Report | · 测试报告 | 2 |
· Size Measurement | · 计算工作量 | 1 |
· Postmortem & Process Improvement Plan | · 事后总结, 并提出过程改进计划 | 1 |
合计 | 18 |
PSP 2.1 | Personal Software Process Stages | Time |
---|---|---|
Planning | 计划 | |
· Estimate | · 估计这个任务需要多少时间 | 20 |
Development | 开发 | |
· Analysis | · 需求分析 (包括学习新技术) | 1 |
· Design Spec | · 生成设计文档 | 1 |
· Design Review | · 设计复审 (和同事审核设计文档) | 1 |
· Coding Standard | · 代码规范 (为目前的开发制定合适的规范) | 1 |
· Design | · 具体设计 | 1 |
· Coding | · 具体编码 | 8 |
· Code Review | · 代码复审 | 2 |
· Test | · 测试(自我测试,修改代码,提交修改) | 2 |
Reporting | 报告 | |
· Test Report | · 测试报告 | 2 |
· Size Measurement | · 计算工作量 | 1 |
· Postmortem & Process Improvement Plan | · 事后总结, 并提出过程改进计划 | 1 |
合计 | 21 |
在读取了文件中的数据后,首先以 ”: “ 作为分隔,将每一行的数据分为三部分,第一部分为每条地铁的标号,第二部分为每条地铁的名称,第三部分为每条地铁的站点信息。
1:1号线:刘园,西横堤,果酒厂,本溪路,勤俭道,洪湖里,西站,西北角,西南角,二纬路,海光寺,鞍山道,营口道,小白楼,下瓦房,南楼,土城,陈塘庄,复兴门,华山里,财经大学,双林,李楼
2:2号线:曹庄,卞兴,芥园西道,咸阳路,长虹公园,广开四马路,西南角,鼓楼,东南角,建国道,天津站,远洋国际中心,顺驰桥,靖江路,翠阜新村,屿东城,登州路,国山路,空港经济区,滨海国际机场
3:3号线:小淀,丰产河,华北集团,天士力,宜兴埠,张兴庄,铁东路,北站,中山路,金狮桥,天津站,津湾广场,和平路,营口道,西康路,吴家窑,天塔,周邓纪念馆,红旗南路,王顶堤,华苑,大学城,高新区,学府工业区,杨伍庄,南站
5:5号线:北辰科技园北,丹河北道,北辰道,职业大学,淮河道,辽河北道,宜兴埠北,张兴庄,志成路,思源道,建昌道,金钟河大桥,月牙河,幸福公园,靖江路,成林道,津塘路,直沽,下瓦房,西南楼,文化中心,天津宾馆,肿瘤医院,体育中心,凌宾路,昌凌路,中医一附院,李七庄南
6:6号线:南孙庄,南何庄,大毕庄,金钟街,徐庄子,金钟河大桥,民权门,北宁公园,北站,新开河,外院附中,天泰路,北运河,北竹林,西站,复兴路,人民医院,长虹公园,宜宾道,鞍山西道,天拖,一中心医院,红旗南路,迎风道,南翠屏,水上公园东路,肿瘤医院,天津宾馆,文化中心,乐园道,尖山路,黑牛城道,梅江道,左江道,梅江公园,梅江会展中心,解放南路,洞庭路,梅林路
................
程序将识别所有的转乘站点,作为一个结点,这样可以避免在计算最短路径过程中,将所有站点的距离都计算一遍,并且以map的形式记录其编号和线路总长度在这里。 为了方便后续的路径计算,我们以距离为模拟将每个站点计算出其编号,公式为(地铁线路标号*1000 + 当条地铁线第几个站点 +1)。 同时,在计算最短路径的同时,要保存每个结点最后被更新前的上一个结点,这样可以方便我们后续输出其完整路径。
包括的函数:
public void loadLineFile(String strSubwayFileName) {}//加载地铁线路数据
void parseSubwayStationsData() {}//地铁数据处理
void parseSubwayLineData(String strSubwayLine) {}//地铁路线处理,包括对地铁线的划分处理,以及对中转站的判定。
Path Dijkstra(String strStartStationName, String strEndStationName){}//利用迪杰斯特拉最短路径算法求最短的地铁路线。
void printPath(String start,String end, String strOutFileName){}//打印一个路径
String formatPath(String start,String end) {}//将读取的地铁站数据返回
Vector<String> stationsInLine(Station stationStart, Station stationEnd) {}//同时在打印两个中间转站点之间的站点时,当两个站点的id差值为正的时候,就将step设置为正1,每次加1,并通过得到的编号输出站点名;同样,当两个站点的id 差值为负的时候,就将step设置为-1即可,最后,通过计算出的地铁线路编号和地铁名称的map,输出地铁名称以及地铁线路的信息,最后将其输入到txt文件中去。
void printLineInfo(String LineName, String strOutFile) {}//获取特定地铁线路数据
int getLineNumber(int nStationId){}//获取subway.txt中第一列的地铁号数
int getLineNumber(String strLine){}//获取subway.txt中第二列的地铁线
int getLineNumber(Station S1, Station S2) {}//获取两个站点之间所需的地铁线路
int getStationsDistance(Station S1, Station S2) {}//获取两个站点之间距离的站数
void toFile(String strContent, String strOutFile) {}//将地铁站点输入到文件
对于算法的性能我们并没有进行过多的关注,但是在选择算法时,还是选的迪杰斯特拉算法求的最短路径,因为该算法不仅容易理解,而且网上有很多已经实现该算法的源代码,所以选择了该算法。
对于迪杰斯特拉算法:
a.初始时,S只包含起点s;U包含除s外的其他顶点,且U中顶点的距离为”起点s到该顶点的距离”[例 如,U中顶点v的距离为(s,v)的长度,然后s和v不相邻,则v的距离为∞]。
b.从U中选出”距离最短的顶点k”,并将顶点k加入到S中;同时,从U中移除顶点k。
c.更新U中各个顶点到起点s的距离。之所以更新U中顶点的距离,是由于上一步中确定了k是求出最短路径的顶点,从而可以利用k来更新其它顶点的距离;例如,(s,v)的距离可能大于(s,k)+(k,v)的距离。
d.重复步骤(b)和(c),直到遍历完所有顶点。
命令:java subway -b 北宁公园 顺驰桥 -map`
输出:
c:\Users\YunChunRui\Downloads\TianJing-Subway\bin>java -Dfile.encoding-UTF-8 subway -b北宁公园 顺驰桥 -map
【参数错误】-map参数后无文件。
`java subway -b 北宁公园 顺驰桥 -map subway.txt -o`
输出:
c:\Users\YunChunRui\Downloads\TianJing-Subway\bin>java -Dfile.encoding-UTF-8 subway -b 北宁公园 顺驰桥 -map subway.txt -o
【参数错误】-o参数后无文件。
`java subway -b 北宁公园 -map subway.txt -o routine`
输出:
c:\Users\YunChunRui\Downloads\TianJing-Subway\bin>java -Dfile.encoding-UTF-8 subway -b 北宁公园 -map subway.txt -o routine`
【参数错误】地址错误,缺少地址,或者输入错误
`java subway -a 8号线 -map subway.txt -o station.txt`
输出:
c:\Users\YunChunRui\Downloads\TianJing-Subway\bin>java -Dfile.encoding-UTF-8 subway -a 8号线 -map subway.txt -o station.txt`
【数据错误】地铁线路不存在
`java subway -a 9号线 -map subway.txt -o station.txt`
结果:
地铁:9号线
天津站
大王庄
十一经路
直沽
东兴路
中山门
一号桥
二号桥
张贵庄
新立
东丽开发区
小东庄
军粮城
钢管公司
胡家园
塘沽
泰达
市民广场
太湖路
会展中心
东海路
`java subway -b 张兴庄 肿瘤医院 -map subway.txt -o routine.txt`
结果:
地铁:3号线
丰产河
华北集团
天士力
宜兴埠
张兴庄
铁东路
北站
中山路
金狮桥
天津站
津湾广场
和平路
营口道
西康路
吴家窑
天塔
周邓纪念馆
红旗南路
王顶堤
华苑
大学城
`java subway -b 张兴庄 肿瘤医院 -map subway.txt -o routine.txt`
结果:
地铁:3号线
铁东路
北站
中山路
金狮桥
天津站
地铁:9号线
大王庄
十一经路
直沽
地铁:5号线
下瓦房
西南楼
文化中心
天津宾馆
肿瘤医院
通过这次结对项目让我对于数据结构+算法=程序有了更加深刻的认识
本次程序的难点主要在对于数据结构的设计,
一是数据的处理:读取.txt文件需要处理地铁线和站点的之间的站点和所属线路、相邻站点之间的约束关系,代码量和复杂度就相应的增大了不少。
二是路线的设计,为了便于处理路线间与路线内的站点之间的关系,通过设计LineNumber,进一步简化节点边的权重设计。使得LineNumber可以承载线路以及站点间的距离多重信息,使得使用Dijkstra算法更加便捷。
三是算法的设计:Dijkstra算法虽然原理简单,但是对于数据结构的实现和使用有一定的要求。需要妥善的处理搜索过的站点以及添加路径的选择。以及最终路径通过保存到栈中,依次输出。
同时,通过结对编程,我认为软件以及程序的开发。需要程序的模块间进一步的实现高内聚低耦合,这样才能产出复用性强,质量有保证的程序;同时结对编程能够帮助组队人互相提高,并且保证产出代码和软件的质量; 通过这次的学习,也让我和队友对于软件工程有了新的领悟。
原文:https://www.cnblogs.com/LDJkwx/p/11809217.html