目录
一、项目地址与成员博客
GitHub项目地址:Quick Subway
结对成员博客:FSMM
二、PSP表格
PSP2.1 | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
---|---|---|---|
Planning | 计划 | 60 | 30 |
·Estimate | ·估计这个任务需要多少时间 | 60 | 30 |
Development | 开发 | 2810 | 2570 |
·Analysis | ·需求分析(包括学习新技术) | 120 | 120 |
·Design Spec | ·生成设计文档 | 120 | 100 |
·Design Review | ·设计复审(和同事审核设计文档) | 60 | 60 |
·Coding Standard | ·代码规范(为目前开发制定合适的规范) | 30 | 30 |
·Design | ·具体设计 | 120 | 120 |
·Coding | ·具体编码 | 2000 | 1500 |
·Code Review | ·代码复审 | 60 | 40 |
·Test | ·测试(自我测试,修改代码,提交修改) | 300 | 600 |
Reporting | 报告 | 210 | 240 |
·Test Report | ·测试报告 | 60 | 60 |
·Size Measurement | ·计算工作量 | 30 | 30 |
·Postmortem & Process Improvement Plan | ·事后总结,并提出过程改进计划 | 120 | 150 |
合计 | 3080 | 2840 |
三、解题思路
3.1、项目需求分析
本项目需要完成输入某线路名称查找该线路上所有站点、输入两站点名称查找两点间最短线路以及输入一起始站点名称查找从该点遍历整个地铁站点的线路,其中最短路和全遍历部分可分为最少换乘和最少站点两种要求进行查询。
在此基础上,进行图形界面的绘制,通过用户输入信息调用相应后端函数,以实现更为友善的交互方式。
3.2、线路站点查询
线路站点信息全部存入输入时读取的文本文件,当用户输入线路名称时可直接打表输出。
3.3、最短路查询
考虑到项目要求和数据处理难度,本项目并未以站点信息的坐标作为根据,而是默认相邻站点间连线权重都为1,采用经典的最短路算法dijkstra进行实现。dijkstra的时间复杂度是,经过堆优化到
,由于站点数目较少,可在较短时间内完成查询。对于最少换乘部分考虑换乘1站等于乘坐3站,在每次换乘时将距离+3即可。
3.4、全遍历查询
本项目中全遍历的实现是NP问题,尚未有最优解法,这也是本项目的难点部分。经过对不同算法的考察,选用了欧拉回路算法,该算法可以求得将地图线路图各边不重复遍历一圈。首先,我们通过对数据的处理,将地铁线路进行适当的增删,在删减过程中考虑到使添加的线路长度尽可能短,从而得到一个欧拉图,然后在对欧拉图进行以欧拉回路算法的求解。其中对于度为奇数的点进行增添边或删减的操作以变为度为偶数的点,进行了如下图的增改:
上图中将所有单只不成环的线路进行边的增添使其成环(上图将所有单只线路擦除默认已增添为环路),再对奇数度顶点的边适当删减以使线路更为简洁。最后将所有剩余奇数度点与距离较近的奇数度点进行增添边的连接。
四、设计实现
4.1、程序流程图
4.2、后端实现部分
后端主要采用C++进行编写,主要类为Subway类进行算法实现,Input类进行参数输入的判断。
4.3、前端界面实现部分
前端主要采用C#编写,通过调用后端DLL进行参数传递,DLL返回参数后通过参数处理进行输出与绘图。其窗体主要包括主窗体Form1,最短路查询输入窗体Shortest和全遍历查询输入窗体All,并包含绘图类Draw和窗体大小适应类AutoSizeFormClass。
五、性能分析
由于全遍历较为费时,故本项目对于 "/a 知春路 " 进行性能分析,结果如图:
根据性能分析可以发现,读取文件函数Input为消耗最大的函数。关于全遍历的方法是经过多次讨论以及查找资料得到的最优算法,解决问题较快可以满足项目需求,并且暂时未能想到更好的算法,所以未做改进。
六、文本格式说明
6.1、文本文件存储
文本文件存储方式简单易用,容易测试和编辑,但读取慢,尺寸大。由于本项目较小,开发周期较短,为了操作简单考虑,采用了文本文件储存的方法。由于项目要求每次运行程序需读入地铁文本信息,经过对于算法以及存储结构的设计,做出如下格式规定:
1.以 "#" 开头存储 "站点编号 站点名 站点横坐标 站点纵坐标 " , 通过读入存储站点位置信息。
2.以 "%" 开头存储 "地铁线路名称 站点数 站点编号..." , 通过读入存储不同线路的站点。
3.以 "@" 开头存储 "站点编号 站点编号 地铁线路名称 " , 通过读入存储站点连接信息。
4.以 "+" 开头存储 "站点编号 站点编号 地铁线路名称 " , 通过读入存储站点在全遍历时形成欧拉回路的线路增添。
5.以 "-" 开头存储 "站点编号 站点编号 地铁线路名称 " , 通过读入存储站点在全遍历时形成欧拉回路的线路删减。
其中通过 "%" 存储不同线路的站点信息可以方便线路查询,但也同时存在更新地铁信息时需要更改线路上站点信息的情况,造成人工成本较大。由于 "四惠 " 与 "四惠东 " 之间存在"1号线 " 与"八通线 " 两种线路方式,将其当作一种线路方式进行输入方便路线查找,"+" 和"-" 是用于全遍历时欧拉回路的搜索,通过增删路线形成欧拉图,其增删线路都为进行讨论后得出的较优选择。连接站点部分仅有单向表示,由于地铁是个无向图,对于无向图在程序中进行双向的存储,机场线做单独处理。
6.2、XML存储
XML存储使得内容和结构完全分离,其互操作性强,可在不同的操作系统间通信;有标准语法格式,规范统一;支持多种编码;可扩展性较好。且XML格式的文件多用于网页信息储存,如果将程序移植到web端,可考虑采用此方法存储数据。
6.3、数据库
其优点为技术成熟、应用广泛;数据管理能力强,安全程度高。当需要存储的信息内容较多时,如扩展为多地铁信息查询程序,则可以考虑使用数据库存储。
6.4、自定义二进制格式
其优点为尺寸小、存取快。
七、测试
7.1、单元测试
通过对各线路查找、最短路查询、全遍历查询的正确输入与错误输入进行测试,设置不同输入的预期输出结果,对错误输入判断测试结果是否与预期输出结果相符,对正确输入判断测试结果是否满足项目要求。
7.2、后端黑盒测试
1、线路信息查询
房山线
阎村东
苏庄
良乡南关
良乡大学城西
良乡大学城
良乡大学城北
广阳城
篱笆房
长阳
稻田
大葆台
郭公庄
2、最短路径查询(最少站点)
QuickSubway.exe /b 霍营 安立路
6
霍营
立水桥 换乘5号线
立水桥南
北苑路北
大屯路东 换乘15号线
安立路
3、最短路径查询(最少换乘)
QuickSubway.exe /c 霍营 安立路
11
霍营
育新
西小口
永泰庄
林萃桥
森林公园南门
奥林匹克公园 换乘15号线
安立路
4、机场线特判
QuickSubway.exe /b 2号航站楼 3号航站楼
3
2号航站楼
三元桥
3号航站楼
QuickSubway.exe /b 3号航站楼 2号航站楼
2
3号航站楼
2号航站楼
全遍历结果测试/z:
分别测试结果的正确性、是否有遗漏站点、遍历次序是否合理、起点和终点是否相同。测试内容已随项目上传到GitHub。
7.3、前端黑盒测试
完成界面后,对项目功能进行测试。
7.3.1.对错误输入
7.3.2.对不同需求下
选取 "霍营 " 到 "安立路 ":
最少换乘:
最少站数:
八、界面功能
界面展示如下,其中使用截止到2019.1.11最新的北京地铁图做完背景:
8.1、线路查询
8.2、最短路查询
8.3、全遍历查询
九、项目总结
9.1、遇到难点
这次的项目为结对项目,我主要负责前端页面设计,队友主要负责后端开发。由于考试周时间较为紧张,便选择在考试结束后进行集中开发。
项目在考试前进行了初步计划,在1月11日开始开发,在前三天主要由队友进行后端开发和测试,我进行输入数据的编写和前端的设计。当两端都几乎完成之后进行了后端C++编写的项目的DLL封装,并在前端以C#进行调用。
由于是初次使用C#进行前端开发,在前端编写的过程中遇到了一些小问题。首先是在画图的时候出现了进程阻塞,使得界面的时间和站数等控件无法更新,因此对于绘图部分开了一个线程,以使其能够更新显示。然后是在线程处理过程中发现无法在新线程里访问主线程控件,故在定时触发器里实时更新时间、站点等显示信息。最后是由于开了线程,在打断线程时出现了错误退出的情况,所以在每次操作的界面刷新部分进行了线程的Abort,使得用户可以随时放弃当前操作而开启另一个操作。此外对于不同电脑的不同分辨率的可移植性问题,也通过对控件尺寸和分辨率的获取进行控件的缩放,以给用户更为良好的体验。
9.2、心得体会
与个人项目不同,在结对项目中增加了组内交流,使得遇到的问题可以更块得到解决,并且通过讨论可以得到更好的处理方法。在本次项目中,我不仅感受到合作开发的优势,也学习到了DLL的封装已经C#窗体相关功能的使用,并且知道了GitHub多人管理项目的方法。
这次项目的开发时间并不算长只是较为集中。我们最先选这个项目的时候并未进行太多的考量,觉得实现起来并不算太困难,但是当我们深入讨论的时候,如何进行全遍历,如何进行数据存储,如何编写输入的文本文件的问题一一向我们袭来,我们才意识到这个项目存在的难度。对此,我们首先进行了相关资料的检索,知道了别人做这个项目时的文本存储格式,也了解了求全遍历的相关算法,我们按照项目的需求选用了最新的地铁图,对文本存储内容进行了改进,并选用了最适合项目的较优求解办法。在项目不断的如期推进过程中,我们发现项目正在一点点被拆解,变得容易。我们整个项目耗时约五天,基本完成项目的所有需求。
此次项目仍有一部分不足,由于时间限制未能完成拓展需求提到的移植到手机端,以后有时间将进一步推进。