北京地铁线路最短路径
一、项目综述
提供一副地铁线路图,计算指定两站之间最短(最少经过站数)乘车路线;输出指定地铁线路的所有站点。以北京地铁为例,地铁线路信息保存在data.txt中,格式如下:具体格式如下:
线路名1 站名1 站名2 站名3 ......
线路名2 站名1 站名2 站名3 ......
一.主要功能
1. 查看地铁路线图,用户可以选择查询各个路线信息
2. 用户输入起点站和终点站后可以得到二者间的最短路线换乘图
3. 可以显示大地图
4. 输出的信息可以导入result.txt文本
二. 可靠性和可用性需求
1. 在生成最短线路时至少生成一条线路
三. 性能需求及报错信息
1. 用户输入信息能在有效时限内得到反馈。
2. 若得到错误输入,程序应该及时停止,并反馈用户错误情况
四. 约束
语言:Java
环境:eclipse
在代码关键位置应添加注释编译理解,可通过命令行进行数据交互。通过指定的地图数据和相关查询指令,可以实现所有的需求。
实现算法
-
Dijkstra
模块分析:
| 类名 | 功能 |
| shorttext_ptah.java | 计算最短路径时存储必要站点信息,包含起点站和终点站以及换乘信息和路径等等数据 |
| station.java | 存储每一个站点的必要信息,包含站点名,站点所在路线,以及该站点的临近站点 |
| Main.java | 程序主体部分,用于承载输入和输出 |
| ttt.java | 一个简单的Jlable 用于存放站点图 |
| algorithm.java | 使用迪杰斯特拉算法计算最短路径并存放在shorttest_path中 |
| date_create.java | 读入地图站图的信息,并将各站的信息存入station中 |
文件包预览图:
核心代码:
public class Shortest_path { private station star; //起始站 private station end; //终点站 private int distance; //距离 private station passStations; //到达该站的最短路径中的上一站 private String line; //该站在几号线上 private int linechange=0; //标记换乘情况,有换乘则置为1 #此处省略构造方法 }
public class station { private String name; //站点名 private List<String> line=new ArrayList<String>(); //所在线路 private List<station> linkStations = new ArrayList<station>(); //相邻站点 #此处省略构造方法 }
public ttt() {//构建包含地图路径图的一个Jlable setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setBounds(0, 0, 2618, 1392); contentPane = new JPanel(); contentPane.setBorder(new EmptyBorder(5, 5, 5, 5)); contentPane.setLayout(new BorderLayout(0, 0)); setContentPane(contentPane); ImageIcon img=new ImageIcon("C:\\\\Users\\\\1\\\\Desktop\\\\地铁最短路径\\\\png1.png");//设置图片路径,尽量设置为相对路径 img.setImage(img.getImage().getScaledInstance(2000, 1000,Image.SCALE_DEFAULT)); JLabel lblNewLabel = new JLabel(img);//在窗口中设一个任意大小的label,作为图片显示区域 contentPane.add(lblNewLabel, BorderLayout.CENTER); }
public static Shortest_path shortestPath(station star, station end) { //dijkstra计算最短路径 for(List<station> l:date_create.lineSet) { //初始化 for(int k=0 ; k<l.size() ; k++) { Shortest_path result = new Shortest_path(); result.setStar(star); result.setEnd(l.get(k)); result.setDistance(9527); result.setLinechange(0); shortmap.put(l.get(k), result);//放入最终路径 } } station s = new station(null); for(int i=0 ; i<star.getLinkStations().size() ; i++) { s = star.getLinkStations().get(i); shortmap.get(s).setDistance(1); shortmap.get(s).setPassStations(star); List<String> samelines=getSameLine(star.getLine(),s.getLine()); shortmap.get(s).setLine(samelines.get(0)); } shortmap.get(star).setDistance(0); analysisList.add(star); station next = next(); while(next!=null) { for(station s1:next.getLinkStations()) { if(shortmap.get(next).getDistance()+1<shortmap.get(s1).getDistance()) { //更新最短路径 shortmap.get(s1).setDistance(shortmap.get(next).getDistance()+1); shortmap.get(s1).setPassStations(next); List<String> samelines=getSameLine(next.getLine(),s1.getLine()); if(!samelines.contains(shortmap.get(next).getLine())) { //需要换乘 shortmap.get(s1).setLine(samelines.get(0)); shortmap.get(s1).setLinechange(1); } else { shortmap.get(s1).setLine(shortmap.get(next).getLine()); } } } analysisList.add(next); next = next();//指向下一站 } return shortmap.get(end); }
public date_create() throws IOException{//从data.txt拿到站点信息,将各个站点的信息存入station中 File A = new File("C:/Users/1/Desktop/ttcp/data.txt"); InputStream fop = new FileInputStream(A); BufferedReader br = new BufferedReader(new InputStreamReader(fop)); String line=""; //List<station> sum_station=new ArrayList<station>(); while ((line = br.readLine()) != null) { List<station> sum_station=new ArrayList<station>(); String[] linearr=line.split(" "); String linename=linearr[0];//存入线路名 // System.out.print(line+\'\n\'); for(int i=1 ; i<linearr.length; i++) {//i=1时是第一个站点 线路输入站点 int flag=0; for(List<station> stations:lineSet) { for(int k=0 ; k<stations.size() ; k++) {//换乘站点 if(stations.get(k).getName().equals(linearr[i])) {//站点比较 List<String> newline=stations.get(k).getLine(); newline.add(linename); stations.get(k).setLine(newline); sum_station.add(stations.get(k)); flag=1; break; } } if(flag==1) break; } if(i==linearr.length-1&&linearr[i].equals(linearr[1])) { //处理环线 sum_station.get(0).getLinkStations().add(sum_station.get(sum_station.size()-1)); sum_station.get(sum_station.size()-1).getLinkStations().add(sum_station.get(0)); flag=1; } if(flag==0) { station a = new station(linearr[i],linename); sum_station.add(a);//正常站点存入 } } for(int j=0;j<sum_station.size();j++) { //初始化每个车站相邻的车站//等待修改 List<station> newlinkStations=sum_station.get(j).getLinkStations(); if(j==0) { newlinkStations.add(sum_station.get(j+1)); sum_station.get(j).setLinkStations(newlinkStations); } else if(j==sum_station.size()-1) { newlinkStations.add(sum_station.get(j-1)); sum_station.get(j).setLinkStations(newlinkStations); } else { newlinkStations.add(sum_station.get(j+1)); newlinkStations.add(sum_station.get(j-1)); sum_station.get(j).setLinkStations(newlinkStations); } } lineSet.add(sum_station); } br.close();//关闭br }
File file = new File("./src/result.txt");//写入result.txt if(!file.exists()){ file.createNewFile(); } FileOutputStream outputStream = new FileOutputStream(file); byte[] bytes = context.getBytes("UTF-8"); outputStream.write(bytes); outputStream.close();
案例测试:
进入程序
测试1-5的测试结果均存入resule.text中
测试1:
测试2:
测试3
:
测试4:
测试5:
测试6:(地图可放大)
总结:
1.此次试验了解到了java功能的强大,自身对java运用的不熟练,还需努力学习java
2.将单纯的算法运用到实际中光了解算法是不够的,需要对算法进行透彻分析,才能熟练掌握
3.编写代码不仅仅要求能够运行,更要求精益求精,多使用csdn,博客园,github等工具多看看他人代码更加有助于提升自己