地铁线路最短路径

一、主要功能

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

 

 

 

地铁线路信息保存在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

 

posted @ 2020-10-21 14:47  clementy  阅读(256)  评论(0)    收藏  举报