一  问题重述

1.实现地铁线路的加载

2.实现查询指定线路所有站点(包括换乘信息)

3.实现查询指定两个站点间的最短路径


二  功能设计

1.实现地铁线路的加载

-map subway.txt //将存储在subway.txt文件里的地铁线路进行读取

 

2.实现查询指定线路所有站点

-a 地铁线路名称 -map subway.txt -o station.txt //读取subway.txt文件信息后,通过输入的地铁线路名称,将指定地铁线路的所有站点写入station.txt文件

3.实现查询指定两个站点间的最短路径

-b 起始站点 目的站点 -map subway.txt -o routine.txt //读取subway.txt文件信息后,通过输入的起始站点和目的站点,将最短路径的所有站点写入routine.txt文件

 


三  项目内容

1.文本地图存储方式

地铁线路名称
站点1 站点2[其它途经地铁线1][其它途经地铁线2……] …… 站点n

以地铁1号线为例

1号线
苹果园 古城 八角游乐园 八宝山 玉泉路 五棵松 万寿路 公主坟[10号线] 军事博物馆[9号线] 木樨地 南礼士路 复兴门[2号线] 西单[4号线] 天安门西 天安门东 王府井 东单[5号线] 建国门[2号线] 永安里 国贸[10号线] 大望路[14号线东段] 四惠[八通线] 四惠东[八通线]

注意:地铁站名使用中文字符以外,其它所有字符均采用英文半角字符。站点信息中也应不存在空格符,比如 公主坟[ 10号线]

2.文本与程序数据转换

class SubwayLine
{
	public String Name;
	public List<String> InLineSubwayStationsName;
}
class Station
{
	public String Name;
	public boolean IsTransferStation ;
	public List<String> PlacedSubwayLineName;
}

  

这里以两行为一个单位进行读取,能够读取地铁线路名称及对应的所有站点信息

while ((lineTxt = br.readLine()) != null) {//首先读取第一行的地铁线路名称

        sl.setName(lineTxt);
if((lineTxt = br.readLine()) != null) {//然后读取第二行站点信息 stations=lineTxt.split(" "); //对第二行站点信息进行以空格切分,并且存入String[]stations subwaystations=new ArrayList<>(stations.length); List<String> updatesubwaystations=new ArrayList<>(stations.length);
     Collections.addAll(subwaystations, stations);

然后用正则表达式对每个站点的信息进行提取,存入SubwayLine结构,然后合并所有SubwayLine为一个Hashtable SubwayLines的排序列表。结合所有路线信息,创建另一个排序列表List<String> subwaystationnames 实现站点名与邻接矩阵下标的对应关系,不会创建重复的站点名键

  

3.创建邻接矩阵(UDG)

	 public MatrixUDG(List<String> vexs, ArrayList<ArrayList<String>> edges) {//vexs为地铁所有站名集合,edges为二维数组存放每个站点所处所有线路的相邻站点信息

	        // 初始化"顶点数"和"边数"
	        int vlen = vexs.size();
	        int elen = edges.size();
	        // 初始化"顶点"
	        mVexs = new ArrayList<String>();
	        mVexs.addAll(vexs);

	        // 初始化邻接矩阵
	        mMatrix=new int[vlen][vlen];
	        for(int i=0;i<vlen;i++) {
	        	for(int j=0;j<vlen;j++)
	        		mMatrix[i][j] =INF;
	        }

	        for (int i = 0; i < elen; i++) {
	            // 读取边的起始顶点和结束顶点
	            int p1 = getPosition(edges.get(i).get(0));
	            int p2 = getPosition(edges.get(i).get(1));



	            mMatrix[p1][p2] = 1;
	            mMatrix[p2][p1] = 1;
	        }

	    }

  

4.Floyd算法(求多源最短路径)

 public  void floyd(int[][] matrix){//通过已经建立的mMatrix矩阵,进行floyd算法计算
  int size=matrix.length;
  for(int i=0;i<size;i++){
   for(int j=0;j<size;j++){
    path[i][j]=-1;
    dist[i][j]=matrix[i][j];
   }
  }
  for(int k=0;k<size;k++){
   for(int i=0;i<size;i++){
    for(int j=0;j<size;j++){
     if(dist[i][k]!=INF&&
      dist[k][j]!=INF&&
      dist[i][k]+dist[k][j]<dist[i][j]){//dist[i][k]+dist[k][j]>dist[i][j]-->longestPath
      dist[i][j]=dist[i][k]+dist[k][j];
      path[i][j]=k;
     }
    }
   }
  }

 }

采用Floyd最短路径算法进行计算,这个方法较为简单,一次计算所有的路径后存储于矩阵中,采用了递归的方式,不断在两点之间寻找最短中转点,直到两个点为相邻点,这样就可以通过Floyd路径矩阵找到完整的路径

5.测试

-map BJsubway.txt  ----->成功读取subway.txt文件

  

-a 1号线 -map BJsubway.txt -o station.txt  ----->已将结果写入station.txt文件     
station.txt内容

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

-b 大井 动物园 -map BJsubway.txt -o routine.txt  ----->已将结果写入routine. txt文件
routine.txt内容

  共计9个站点
  大井
  七里庄
  六里桥东
  北京西站
  军事博物馆
  白堆子
  白石桥南
  国家图书馆
  动物园


四 项目总结学习

本次个人项目共花费四天时间,虽然还有细节未完成

第一天计划并完成文本地图的存储和文本数据与程序的转化,对先前的地铁线路信息的存储格式进行修改,通过查询构建新的存储结构,之后在数据与程序的转化上,粗浅学习了正则表达式

第二天计划并完成无向图的邻接矩阵的创建,将vexs地铁站点名称集合和edges各站点相邻信息输入,得到以INF,1分布的邻接矩阵(mMatrix[i][j]==1表示站点i与站点相邻,INF表示无邻边)

第三天计划并完成Floyd算法实现两点最短路径,学习和比较了Floyd算法和Dijksta算法,Floyd算法的path[][]矩阵的更新比较难理解,将构建的邻接矩阵作为输入,得到两点的最短路径

第四天整理和完成代码修正,文档博客编写

整个项目完成下来,头是真的大,各种细小的东西都得自己研究,比如:各种类型之间的转换,subwaylines该用什么结构进行存储,List<String>的内容如何存入txt文件,如何将Object对象存入txt文件等等,总的来说,这次的个人项目对自己帮助挺大的,感觉学会了独立生存,别人的建议只能是咨询,自己的想法才是关键

Github地址:https://github.com/Kuzzri/JavSubway

02-13 21:38