GitHub:https://github.com/wakerh1/subwayBJ


北京地铁图片:

地铁出行路线规划项目需求及实现概要:

  1.设计一种文件格式用于存储地铁信息

  2.设计启动程序并读取地铁信息文件的命令行

  3.可以输出查询的具体地铁路线的所有途径地铁站点

  4.能够告知用户两个站点之间的最短路线

  5.进行代码复审

  6.进行测试

  7.进行性能检测

 

主要术语表:

中文名 英文 解释
线路 Line 地铁线路,线路上有很多的站点
站点  Station 地铁站点

主要模块介绍:

序号  模块名称 主要功能

对应java文件或方法类

1 主模块 流程控制、文件数据读入 src/subwayMap/subway_0
2 核心算法模块 实现Dijkstra算法和最短路径算法

src/subwayMap/subway_0中的

方法类

dijkstraTravel

shortestPath

3 输出模块 输出站点与线路信息 src/subwayMap/Main

   1.输出模块

  • -b 后 输入线路名,输出该线路对应的所有站点

    

示例:
-b
请输入线路名
1号线
  • -a后输入起始站和终点站,生成最短路径并生成:

  

示例:
-a
请输入起点:
苹果园
请输入终点:
白堆子
最短路径生成:

  2.核心算法模块:实现Dijkstra算法

  • 利用HashMap 存储全部的站点信息,并以站点名称为key

  

HashMap 存储全部的站点信息,并以站点名称为key
  • 使用for循环遍历后使所有站结点都为为访问状态
  • 定义flag遍历来控制循环开始
  • 通过循环遍历找出站点中未被访问过,同时路径总站数最少的路线各点

  具体代码如下:

  

private void dijkstraTravel(Station s){
Set<Station> set = map.keySet();
//for循环使所有站节点都为未访问状态
for (Station station : set) { station.visited = false;
station.dist = Integer.MAX_VALUE;
} s.dist = 0;//先令起点距离为0 boolean flag = true;//控制循环开始
while(flag){
Station v = null;//表示当前站节点
Station w;//表示当前站节点的邻接节点 //for循环找出站节点中未被访问 且距离(dist)最小的站节点
for (Station station : map.keySet()) {
if(station.visited == true)
continue;
if(v == null || station.dist < v.dist)
v = station;
} //访问当前节点
v.visited = true; //遍历当前节点的邻接节点
List<Edge> list = map.get(v);
for (int i = 0; i < list.size(); i++) {
w = list.get(i).station;
if(!w.visited){
int d = list.get(i).distance; //修改邻接节点的距离和路径
if(v.dist + d < w.dist){
w.dist = v.dist + d;
w.path = v;
}
}
} //遍历节点集 有未遍历的节点则while循环继续
Iterator<Station> iterator = map.keySet().iterator();
while(iterator.hasNext()){
if(!iterator.next().visited){
flag = true;
break;
}
}
if(!iterator.hasNext())
flag = false;
}
}

3.主模块

  •   文件数据读入

    

//部分代码:
private void fileReader(){
File f = new File("mapdata/subwayInfo_bj.txt");
if(f.exists()){ try {
FileReader out = new FileReader(f);
BufferedReader br = new BufferedReader(out); String line = null;//用于按行读取文件
int nums = Integer.parseInt(br.readLine());//记录一共多少条地铁线
  • 处理特殊情况(环路、起始站和终止站同站、不存在站名、不存在路线)

    

//1 始发站问题
if(j == 0){
head = s;
} //2 终点站问题(环路则处理 非环路不处理)
if(j == trackStationsNum-1 && nextDistance > 0){
//环路要在始发站 存储到达终点站的边信息
map.get(head).add(pre);
//对终点站存储始发站的边信息
map.get(s).add(new Edge(head,trackName,nextDistance));
}
  •   定义数据结构

    

private class Station{
String stationName;
boolean visited; //以下两个变量用于迪杰斯特拉算法
int dist;
Station path;
String trackName;
int SetTname=0;
String pretrackname; public Station(String stationName) {
super();
this.stationName = stationName;
this.visited = false;
this.dist = Integer.MAX_VALUE;//类似于无穷了
this.path = null;
this.trackName = null;
this.pretrackname = null;
}
}
private class Edge{
//String name;
Station station;
String lineName;
int distance; public Edge(Station station, String lineName, int distance) {
super();
this.station = station;
this.lineName = lineName;
this.distance = distance;
} @Override
public String toString() {
return "Edge [station=" + station + ", lineName=" + lineName + ", distance=" + distance + "]";
}
}

实现思路:

本次大作业我们要完成的主要任务有设计文件的存储格式、查询地铁线路和站点间最短路线问题。

首先对于站点信息的文件存储格式,可以使用xml格式或者json格式,如果使用json格式侧需要编写相应的json格式转换的代码,但是json格式的方便程度是比较高的。而xml格式则比较繁琐。

1.要查询地铁线路,可以建立一个线路(Line)的list,在Java中可以使用ArrayList,而每个线路又是一个站点(station)它的列表,那么只需要遍历线路列表找到查询的线路并输出就可以(但是这样性能上可能会差一些),也要记得处理异常情况——找不到查询线路的问题。

2.要得出两个站点之间的最短路径,那么迪杰斯特拉算法是一种不错的选择,广度优先遍历同样可行;对于广度优先遍历,只要明确一点,最先找到终点站的路线就是最短路线。这里的异常情况是——找不到要查询的站点。

本次大作业如果使用C/C++来实现的话,性能上会有一定的优势,但是本次大作业的结构与功能并不是很复杂,java语言也可以胜任;鉴于个人对C++、Json格式的练习较少,我打算使用Java语言来编写此次大作业。

以下是输入格式设计:

{
1号线 23
苹果园 1
古城 1
八角游乐园 1
八宝山 1
玉泉路 1
五棵松 1
万寿路 1
公主坟 1
军事博物馆 1
木樨路 1
南礼士路 1
复兴门 1
西单 1
天安门西 1
天安门东 1
王府井 1
东单 1
建国门 1
永安里 1
国贸 1
大望路 1
四惠 1
四惠东 -1
}

线路名后跟着线路总站点数,然后每条线路包含所有的站点名,每个站点名后跟着的1代表一站,计算最短路径

时采用的是对比路线所需要经过的站数是否最少。

测试分析:

  1)功能测试

    1.读入文件(已经在主模块中直接读取)

    2.查询线路,参数为:-b 1号线

    

测试结果:
-b
请输入线路名
1号线
苹果园
古城
八角游乐园
八宝山
玉泉路
五棵松
万寿路
公主坟
军事博物馆
木樨路
南礼士路
复兴门
西单
天安门西
天安门东
王府井
东单
建国门
永安里
显示路线成功

    3.查询最短线路:

    参数为-a  苹果园 白堆子(目前存在一些不足,个别乘坐线路的描述存在问题)

     

-a
请输入起点:
苹果园
请输入终点:
白堆子
最短路径生成:
乘1号线
苹果园
乘1号线
古城
乘1号线
八角游乐园
乘1号线
八宝山
乘1号线
玉泉路
乘1号线
五棵松
乘1号线
万寿路
乘1号线
公主坟
乘1号线
军事博物馆
乘9号线
白堆子
生成成功

   2)异常情况处理测试:

    1.起点与终点相同:-a 苹果园 苹果园

    

-a
请输入起点:
苹果园
请输入终点:
苹果园
最短路径生成:
起点与目的地重合
乘1号线
苹果园
生成成功

     

     2.起点或终点不存在: -a 苹果园 钱塘江

                  -a 钱塘江 西直门

 

-a
请输入起点:
苹果园
请输入终点:
钱塘江
最短路径生成:
不存在的目的地
钱塘江
-a
请输入起点:
钱塘江
请输入终点:
西直门
最短路径生成:
不存在的起点

      3.起点或终点不存在: -b 八十八号线

 

-b
请输入线路名
八十八号线
不存在该路线

参考文档:https://github.com/lihaibin921/subwayMap

修改部分:增加了输出在换乘点换乘的功能

     参考文档中不含有输出单条路线所有站点功能

      修改输出方式

      对原始的数据结构进行了修改

  

SubwayPlan的更多相关文章

随机推荐

  1. hibernate+spring mvc,解决hibernate对象懒加载,json序列化失败

    在使用spring MVC时,@ResponseBody 注解的方法返回一个有懒加载对象的时候出现了异常,以登录为例: @RequestMapping("login") @Resp ...

  2. 阶段3 1.Mybatis_07.Mybatis的连接池及事务_2 连接池介绍

  3. Jmeter接口测试系列之测试用例变量参数化处理

    在进行接口测试时,一组完整的接口测试用例,存在后一个测试用例使用前一个用例的请求结果中的数据,此时就需要参数化测试用例中值.直接使用变量调用会存在问题,此时就需要用到beanshell去改变. 举例说 ...

  4. 配置文件pytest.ini

    前言 pytest配置文件可以改变pytest的运行方式,它是一个固定的文件pytest.ini文件,读取配置信息,按指定的方式去运行. ini配置文件 pytest里面有些文件是非test文件 py ...

  5. anaconda3,将python版本回退(python3.7---python3.5)

    2019/6 安装anaconda3时,安装了默认的最新版本,但是由于不能兼容tensorflow,我又配置了一个python3.5的环境: 可惜这里真的不晓得咋回事,在python3.5中进入jup ...

  6. 20191127 Spring Boot官方文档学习(4.13)

    4.13.Messaging Spring框架为与消息传递系统集成提供了广泛的支持,从使用JmsTemplate简化JMS API到完整的异步接收消息的基础结构.Spring AMQP为高级消息队列协 ...

  7. k8s--资源控制器

    资源控制器 1.什么是控制器 Kubernetes中内建了很多controller (控制器) ,这些相当于一个状态机,用来控制Pod的具体状态和行为 Pod 的分类 自主式 Pod:Pod 退出了, ...

  8. 红帽学习笔记[RHCSA] 第四课[用户相关、破解root密码]

    第四课 关于Linux 的用户 用户分类: # UID 是用户ID ​ UID 0分配给超级用户(root) ​ UID 1-200 是一系列的 系统用户 静态分配给红帽的系统进程 ​ UID 201 ...

  9. django商城项目之用sentry管理日志

    之前写商城项目的时候,采用的日志处理方式为在终端输出或者写入文件,这样的话,项目部署上线之后,若服务器出现错误,需要到服务器查看相关的错误日志,很不方便.后期在学习别人开源项目的时候,学习到一个开源的 ...

  10. pathlib模块替代os.path

    pathlib模块替代os.path 在Python 3.4之前和路径相关操作函数都放在os模块里面,尤其是os.path这个子模块,可以说os.path模块非常常用.而在Python 3.4,标准库 ...