地铁线路最短路径
一、主要功能
提供一副地铁线路图,计算指定两站之间最短(最少经过站数)乘车路线;输出指定地铁线路的所有站点。以北京地铁为例

地铁线路信息保存在data.txt中,格式如下:
地铁线路总数
线路名1 站名1 站名2 站名3 ...
线路名2 站名1 站名2 站名3 ...
线路名3 站名1 站名2 站名3 ......
二、实现语言
Java
三、实现算法
Floyd算法
从图的带权邻接矩阵A=[a(i,j)] n×n开始,递归地进行n次更新,即由矩阵D(0)=A,按一个公式,构造出矩阵D(1);又用同样地公式由D(1)构造出D(2);……;最后又用同样的公式由D(n-1)构造出矩阵D(n)。矩阵D(n)的i行j列元素便是i号顶点到j号顶点的最短路径长度,称D(n)为图的距离矩阵,同时还可引入一个后继节点矩阵path来记录两点间的最短路径。
四、类职责划分
1.
public class ReadData
数据读入类
2.
public class SubwayMain
主函数运行类
3.
public class Floyd
最短路径算法实现类
4.
public class LineMap<T>
图结构储存
5.
public class Station
站点信息储存
五、核心代码
1.文件读入
package FileData; import java.io.*; import java.util.*; import Model.Station; public class ReadData { public List<Station> readText(String Path){ List<Station> routes=new ArrayList<Station>(); try { File file=new File(Path); if(file.isFile() && file.exists()){ InputStreamReader reader = new InputStreamReader(new FileInputStream(file)); BufferedReader bufferedReader = new BufferedReader(reader); String stationline = null; while((stationline = bufferedReader.readLine()) != null){ Station station = new Station(); String string = ""; String tmp[] = stationline.split(" "); string = tmp[0]; station.setStationnum(string); List<String> stations = new ArrayList<>(); //遍历后添加经过站点 for(String s:tmp) { stations.add(s); } stations.remove(0); station.setStationinfo(stations); routes.add(station); } reader.close(); bufferedReader.close(); } else System.out.println("文件路径错误"); } catch (Exception e) { System.out.println("文件名字或格式有误"); e.printStackTrace(); } return routes; } }
2.Floyd实现
int[][] length = null;// 任意两点之间路径长度 int[][][] route = null;// 任意两点之间的路径 public Floyd(int[][] R) { int row = R.length; int [][] site = new int [row][row];// 定义任意两点之间经过的点 int [] singleroute = new int [row];// 记录一条路径 this.length = R; route = new int [row][row][]; for (int i = 0;i<row;i++) {// 初始化为任意两点之间没有路径 for(int j = 0;j<row;j++) { site[i][j] = -1; } } for(int i = 0;i<row;i++) {// 假设任意两点之间的没有路径 singleroute[i] = -1; } for(int i=0;i<row;++i) { for(int j=0;j<row;++j) { for(int k=0;k<row;++k) { if(length[j][k]>length[j][i]+length[i][k]) {// 如果存在更短路径则取更短路径 length[j][k] = length[j][i]+length[i][k]; site[j][k] = i;// 把经过的点加入 } } } } for(int i = 0;i<row;i++) {// 求出所有的路径 int[] point = new int [1]; for(int j=0;j<row;j++) { point[0] = 0; singleroute[point[0]++] = i; Route(site,i,j,singleroute,point); route[i][j] = new int [point[0]]; for(int num=0;num<point[0];num++) { route[i][j][num] = singleroute[num];//保存中转节点信息 } } } }
3.查找换乘车站
public String transferStation(String x,String y,List<Station> route) { String routes=""; List<String> routes1=new ArrayList<>(); List<String> routes2=new ArrayList<>(); for(Station r:route) { for(String s:r.getStationinfo()) { if(s.equals(x)) routes1.add(r.getStationnum()); if(s.equals(y)) routes2.add(r.getStationnum()); } } for(int i=0;i<routes1.size();i++) for(int j=0;j<routes2.size();j++) if(routes1.get(i).equals(routes2.get(j))) routes=routes1.get(i); return routes; }
4.查找起点到终点点最短路径
public StringBuilder search(T begin,T stop,int[][] subway,List<Station> route) { List<String> transfer = new ArrayList<>(); Floyd floyd = new Floyd(subway); int beginsite = getVertexSite(begin);//开始站点 int stopsite = getVertexSite(stop);//目的站点 int[] path = floyd.getRoute(beginsite, stopsite);//调用getRoute函数求出路径 StringBuilder line = new StringBuilder(); line.append(begin + " 前往 " + stop + " 的线路为: "); int k=0; for (int i : path) { k++; line.append(vertex.get(i) + " --> "); if(k%6==0) { line.append(System.lineSeparator()); } } line.delete(line.lastIndexOf(" --> "), line.length()); for(int j=1;j<(path.length)-1;j++) { int i=path[j]; String s1=transferStation(vertex.get(path[j-1])+"", vertex.get(i)+"", route); String s2=transferStation(vertex.get(i)+"", vertex.get(path[j+1])+"", route); if(!s1.equals(s2)) { transfer.add(vertex.get(i)+""); } } System.out.println(line.toString()); System.out.println("换乘站:"); line.append(System.lineSeparator()+"换乘站:"+System.lineSeparator()); for(String s:transfer) { System.out.println(s); line.append(s+System.lineSeparator()); } System.out.println(begin + " -> " + stop + " 距离目的地站数: " + path.length); line.append(begin + " -> " + stop + " 距离目的地站数: " + path.length); return line; }
其余函数已上传GitHub.
https://github.com/825809797/Subway.git
六、测试用例
1.同一线路上站点

2.错误站点名字

3.不同线路换乘

七、总结
1.通过本次实验进一步掌握Java,以及发现对部分基础知识掌握不足。
2.学习如何把算法运用到具体到实例,对最短路径的求解进一步了解
3.本次实验没有写UI,后一阶段制作简易的UI

浙公网安备 33010602011771号