软工结对项目:地铁

学号1120161789
代码仓库地址:subway
结对搭档博客地址:https://blog.csdn.net/V5ZSQ/article/details/86554215?tdsourcetag=s_pctim_aiomsg

PSP2.1Personal Software Process Stages预估耗时(分钟)实际耗时(分钟)
Planning计划
· Estimate· 估计这个任务需要多少时间30
Development开发
· Analysis· 需求分析(包括学习新技术)180
· Design Spec· 生成设计文档60
· Design Review· 设计复审(和同事审核设计文档)60
· Coding Standard· 代码规范(为目前的开发制定合适的规范)30
· Design· 具体设计240
· Coding· 具体编码2400
· Code Review· 代码复审120
· Test· 测试(自我测试,修改代码,提交修改)960
Reporting报告
· Test Report· 测试报告120
· Size Measurement· 计算工作量30
· Postmortem & Process Improvement Plan· 事后总结,并提出过程改进30
合计4260

根据项目需求,subway需要实现以下功能:

  • 建立北京地铁线路图,保存地铁线路,站点,换乘信息和站点的坐标信息
  • 寻找两个站点之间的最短路径(换乘后站点数额外加3)
  • 从一个站点出发,遍历图中所有站点
  • 通过图形界面对结果进行展示

最终我们实现的功能包括:

  • 建立地铁线路图并保存站点信息等内容
    在这里插入图片描述
  • 将原本的txt格式文档修改为json格式以便适应之后的图形化
    在这里插入图片描述
  • 若第一个命令行参数为‘/g’则显示图形界面并将最短路搜索结果在图中进行展示,用户所要搜索的起始站点和终点站点将在图形界面中进行输入,程序从用户所输入的文本中获取站点名称并进行搜索最短路径
    在这里插入图片描述
  • 若第一个命令行参数为‘/b’则可直接在命令行键入起点和终点,程序运行后将反馈最佳路线(每次换乘额外加3站)
    在这里插入图片描述
    在这里插入图片描述
  • 若第一个命令行参数为‘/l’则在命令行中键入想要获取信息的线路名称如“九号线”,程序运行后将反馈线路中的所有站点
    在这里插入图片描述
    在这里插入图片描述
  • 若第一个命令行参数为‘/a’则在命令行键入起点,程序运行后反馈由该点出发遍历地图上所有节点的结果。该功能我们没能完全实现,最后输出的结果中虽然遍历了所有节点,但是存在不合理的遍历次序,比如:从“古城”到“莲花桥”
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
  • 若第一个命令行参数为‘/z’则在命令行中键入要测试的目标文件的绝对路径,可以检测出目标文件的内容是否出现以下两个方面的错误:
    1、车站的遍历次序不合理,比如从“知春路”到了“中关村”
    2、车站遍历次序合理,但有遗漏的站点,或者车站数量错误
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    使用VisualStudio的性能分析器分析结果如下:
    在这里插入图片描述
    在这里插入图片描述
    本项目中要实现输出两个站点之间的最短路径的部分并不难,可以采用Dijkstra算法或SPFA算法,由于在GUI的设计中需要使用C#,所以用C#实现了SPFA算法
private Dictionary<int, List<Edge>> adj;//用于存储返回的搜索出的最短路径结果

        public UndirectedGraph()
        {
            adj = new Dictionary<int, List<Edge>>();
        }

        public void AddEdge(int from, int to, int line)
        {
            if (!adj.ContainsKey(from))
                adj[from] = new List<Edge>();
            if (!adj.ContainsKey(to))
                adj[to] = new List<Edge>();

            adj[from].Add(new Edge(to, line));
            adj[to].Add(new Edge(from, line));
        }

        public KeyValuePair<int, List<KeyValuePair<int, int>>> ShortestPath(int source, int target)
        {
            Dictionary<int, int> dist = new Dictionary<int, int>();
            Dictionary<int, KeyValuePair<int, int>> pre = new Dictionary<int, KeyValuePair<int, int>>();
            foreach (int id in adj.Keys)
            {
                dist[id] = 0x3f3f3f3f;
            }
            dist[source] = 1;

            Queue<Edge> q = new Queue<Edge>();
            HashSet<Edge> vis = new HashSet<Edge>();
            q.Enqueue(new Edge(source, -1));
            vis.Add(new Edge(source, -1));

            while (q.Count != 0)
            {
                Edge x = q.Dequeue();
                foreach (Edge e in adj[x.To])
                {
                    int temp = dist[x.To] + 1;
                    if (x.Line != -1 && e.Line != x.Line) temp += 3;//若有换乘线路则+3
                    if (dist[e.To] > temp)
                    {
                        dist[e.To] = temp;
                        pre[e.To] = new KeyValuePair<int, int>(x.To, e.Line);
                        if (!vis.Contains(e))
                        {
                            q.Enqueue(e);
                            vis.Add(e);
                        }
                    }
                }
                vis.Remove(x);
            }

            List<KeyValuePair<int, int>> path = new List<KeyValuePair<int, int>>();
            for (int i = target; pre.ContainsKey(i); i = pre[i].Key)
                path.Add(pre[i]);
            return new KeyValuePair<int, List<KeyValuePair<int, int>>>(dist[target], path);
        }

在设计遍历功能的过程中,我们查阅了相关资料,了解到通过增加和删除边的方法将地铁图修改成为欧拉回路之后,再对欧拉回路进行深度优先搜索实现遍历的方法,但是最终没能将地铁图修改成为欧拉回路,采用深度优先搜索进行遍历,结果中出现了不合理的遍历次序。

void DFS(int a)
{
	int b;
	visited[a] = true;
	
	DFS_count++;
	path[DFS_count] = a;
	for (int i = 1; i <= graph[a].rear; i++) {
		b = graph[a].arclist[i].to;
		if(visited[b] == false || graph[a].rear == 1 )
			DFS(b);
	}
}

void searchAll(char *begin)
{
	DFS_count = 0;
	bool flag;
	flag = true;
	memset(visited, false, sizeof(visited));
	memset(dist, INF, sizeof(dist));
	for (int i = 1; i <= node_num; i++)
	{
		if (visited[i] == false)
		{
			flag = false;
		}
	}
	int a;
	a = locateStation(begin);
	if ( a == 0) {
		cout << "站点名称错误" << endl;
		return;
	}
	DFS(a);
	cout << DFS_count << endl;
	for (int i = 1; i <= DFS_count; i++)
	{
		cout << node[path[i]].name << endl;
	}
}

在编写GUI图形界面时,我们首先遇到的问题是插入北京地铁线路图。添加pictureBox之后,按常规思路将图片添加在Image处,却出现了因分辨率过大导致图片无法完全显示的问题,最终我们选择将图片添加在BackgroundImage处,并将SizeMode修改为Zoom,解决了问题,并且可以通过鼠标滚轮实现图片的放大和缩小。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在本项目中如果要处理其他地方的地铁线路,比如上海,则需要按照规范编写存储上海地铁线路信息的文档并修改GUI中的背景图等相关部分。

PSP2.1Personal Software Process Stages预估耗时(分钟)实际耗时(分钟)
Planning计划
· Estimate· 估计这个任务需要多少时间3020
Development开发
· Analysis· 需求分析(包括学习新技术)180160
· Design Spec· 生成设计文档6045
· Design Review· 设计复审(和同事审核设计文档)6030
· Coding Standard· 代码规范(为目前的开发制定合适的规范)3045
· Design· 具体设计240235
· Coding· 具体编码24002560
· Code Review· 代码复审120150
· Test· 测试(自我测试,修改代码,提交修改)960900
Reporting报告
· Test Report· 测试报告120100
· Size Measurement· 计算工作量3025
· Postmortem & Process Improvement Plan· 事后总结,并提出过程改进3045
合计42604240

在本次开发是首次两人一组进行项目开发的宝贵经历,在图形界面设计、遍历算法和两点之间最短路径算法的设计过程中,我们通过讨论和查阅资料解决了大部分问题(虽然还有一些问题没有解决,体现在了我们最终功能的缺陷上)。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值