北京地铁规划项目总结

一、项目介绍

  实现一个帮助进行地铁出行路线规划的命令行程序。

  github链接:https://github.com/blakeyoungc/subway

  主要需求:1、地铁线路图信息的导入

         2、查询指定地铁线经过的站点

       3、计算从出发到目的站点之间的最短(经过的站点数最少)路线,并输出经过的站点的个数和路径(包括出发与目的站点)。

采用https://map.bjsubway.com/上的北京地铁线路图:

 二、需求实现

  

主要模块介绍:

序号 模块名 功能 对应java类
1 主模块(main函数) 对输入参数的控制 Main.java
2 文件输入输出模块 txt文件的读写 Manager.java
3 求最短路径(dij算法) 实现两个站点的最短路线查找 Subway.java

Main函数中区分输入不同参数时执行的操作。

public class Main {
    public static void main(String[] args)  {
        if(args.length==2||args.length==6||args.length==7) {                        //通过case分别处理不同参数输入时的操作
         switch(args[0]) {
         case "-map":
            Manager.loadfile();
            break;
         case "-a":
            Manager.loadfile();
            Manager.searchstations(args[1]);
            break;
         case "-b":
            Manager.loadfile();
            Route results=Subway.getRoutine(args[1],args[2]);
            Manager.outputroute(results);
            break;
         }
        }
        else
            System.out.println("格式错误!");
    }
}

车站及线路类以及其方法的设计

车站类:

import java.util.*;

public class Station {
    private String stationName;                                               //站点名
    private String lineName;                                                  //所在路线名
    private List<Station> linkStations = new ArrayList<>();                   //存储相邻的站点
    public Station(String stationName){
        this.stationName = stationName;
    }

    public Station(String stationName,String lineName){
        this.stationName = stationName;
        this.lineName = lineName;
    }

    public String getStationName() {
        return stationName;
    }

    public void setStationName(String stationName) {
        this.stationName = stationName;
    }

    public String getLineName() {
        return lineName;
    }

    public void setLineName(String lineName) {
        this.lineName = lineName;
    }

    public List<Station> getLinkStations() {
        return linkStations;
    }

    public void setLinkStations(List<Station> linkStations) {
        this.linkStations = linkStations;
    }
}

线路类:

public class Route {
    private Station startstation;                                                 //起点
    private Station destination;                                                  //终点
    private List<Station>passedStations=new ArrayList<>();                        //存储最短路径经过的路线站点
    public Station getStartStation() {
        return startstation;
    }

    public void setStartStation(Station startstation) {
        this.startstation = startstation;
    }

    public Station getDestination() {
        return destination;
    }

    public void setDestination(Station destination) {
        this.destination = destination;
    }

    public List<Station> getPassedStations() {
        return passedStations;
    }

    public void setPassedStations(List<Station> passedStations) {
        this.passedStations = passedStations;
    }
}

需求1、地铁线路图信息的导入

程序启动时需要通过读取 -map 参数来获得对应的自定义地铁文件(命名为 subway.txt),从而得到地铁线路图的信息。

示例: java subway -map subway.txt

通过Hashmap存储subway.txt中的线路站点信息,其中key存线路名,value存站点类的表,存到subwaymap中以供后面使用。

public  static HashMap<String, List<Station>> subwaymap = new HashMap<>();
    public static void loadfile() {
        File file=new File("C://subway.txt");
        try {
            InputStreamReader inputStreamReader=new InputStreamReader(new FileInputStream(file),"GBK");
            BufferedReader reader=new BufferedReader(inputStreamReader);
            String data=null;
            while((data=reader.readLine())!=null) {
            String[] linedata=data.trim().split(" ");                                              //按空格分割读取txt文件的数据
            List<Station>stations=new ArrayList<>();
            for(int i = 1;i<linedata.length;i++){
                Station station = new Station(linedata[i],linedata[0]);
                stations.add(station);
                }
                subwaymap.put(linedata[0], stations);                                              //按序存入subwaymap
            }
        } catch (UnsupportedEncodingException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

subway.txt中的北京地铁线路信息截图

需求2、查询指定地铁线经过的站点。

程序启动时需要通过读取 -a 参数来获得线路名,并输出该线路的站点到文件“station.txt”。

示例: -a 10号线 -map subway.txt -o station.txt

把之前subwaymap中的数据根据用户输入的线路名进行筛选,有序读取该线路经过的站点并写入“station.txt”文件。

public static void searchstations(String routename) {
        File file=new File("C://station.txt");
        try {
            OutputStreamWriter outputStreamWriter = new OutputStreamWriter(new FileOutputStream(file),"GBK");
            BufferedWriter writer = new BufferedWriter(outputStreamWriter);
            List<Station> list = subwaymap.get(routename);
            writer.write(routename+" ");
                for(int i=0;i<list.size();i++){
                    writer.write(list.get(i).getStationName()+" ");
                        }
                writer.close();
        } catch (UnsupportedEncodingException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

   

查询10号线的所有站点,运行完成后station.txt结果截图 

需求3、查询两个站点的最短路径线路及换乘信息

程序启动时需要通过读取 -b 参数来获得输入的起点和终点,输出两个站点之间的最短路径经过的站点。

示例: -b 巴沟 土桥 -map subway.txt -o routine.txt 

查询从巴沟到土桥的最短路线站点及换乘线路。

通过Dijkstra算法求最短路径。

步骤如下:

1:遍历所有节点找到未访问过的节点中累积权值(其实就是从源节点到当前节点的路径值和)最小的(设为A)。

2:遍历该节点所有可达边(连通到目标节点B),如果节点A累积权值加可达边权值小于目标节点B自身的累积权值,则对目标节点B进行更新。

3:将节点A设定为已访问。

4:重复(1)直到所有节点均访问完毕。

public Route Dijkstra(Route routine) {
        Station s;
        Station S;
        HashMap<Station,Station> D = new HashMap<>();
        HashMap<Station,Station> prev = new HashMap<>();
        HashMap<Station,Integer> searched = new HashMap<>();
        HashMap<HashMap<Station,Station>,Integer> distance = new HashMap<>();
        for (String key :allStation.keySet()){
            s = allStation.get(key);
            searched.put(s,new Integer(0));
            if (!routine.getStartStation().equals(s)){
                if (routine.getStartStation().getLinkStations().contains(s)){
                    D = new HashMap<>();
                    D.put(routine.getStartStation(),s);
                    distance.put(D,new Integer(1));
                    prev.put(s,routine.getStartStation());
                }
                else{
                    D = new HashMap<>();
                    D.put(routine.getStartStation(),s);
                    distance.put(D,new Integer(Integer.MAX_VALUE));
                }
            }
            else{
                D = new HashMap<>();
                D.put(routine.getStartStation(),s);
                distance.put(D,new Integer(0));
            }
        }
        searched.put(routine.getStartStation(),1);
        while (true){
            S = FindMinDist(routine,distance,searched);
            if (S.getStationName().equals("-1"))
                break;
            searched.put(S,1);
            for (String key:allStation.keySet()){
                if (S.getLinkStations().contains(allStation.get(key))&&searched.get(allStation.get(key))==0){
                    if (distance.get(getFromtoFin(routine,S))+1<distance.get(getFromtoFin(routine,allStation.get(key)))){
                        distance.put(getFromtoFin(routine,allStation.get(key)),distance.get(getFromtoFin(routine,S))+1);
                        prev.put(allStation.get(key),S);
                    }
                }
            }
        }
        S = prev.get(routine.getDestination());
        while(!S.equals(routine.getStartStation())){
            routine.getPassedStations().add(0,S);
            S = prev.get(S);
        }
        routine.getPassedStations().add(0,routine.getStartStation());
        routine.getPassedStations().add(routine.getDestination());
        return routine;
    }

通过算法生成最短路径后,再进行换乘线路的判断,同时将数据输出到“routine.txt”文件中。

public static void outputroute(Route routine) {
        // TODO Auto-generated method stub
        File file=new File("C://routine.txt");
        try {
            OutputStreamWriter outputStreamWriter = new OutputStreamWriter(new FileOutputStream(file),"GBK");
            BufferedWriter writer = new BufferedWriter(outputStreamWriter);
            writer.write(routine.getPassedStations().size()-1+" ");
            String linename="0";
             for (int i = 0; i < routine.getPassedStations().size();i++)
                {
                    writer.write(routine.getPassedStations().get(i).getStationName()+" ");
                    if (i<routine.getPassedStations().size()-1){
                        if (!routine.getPassedStations().get(i).getLineName().equals(routine.getPassedStations().get(i+1).getLineName())){      //换乘线路的判断
                            linename = routine.getPassedStations().get(i+1).getLineName();
                            if(linename!="0")
                            writer.write("换乘"+linename+"  ");
                        }
                    }
                }
            writer.close();
        }catch(IOException e){
            e.printStackTrace();
        }
    }

routine.txt中的最短路线站点及换乘信息

异常情况处理:

起点与终点相同:-b 土桥 土桥 -map subway.txt -o routine.txt

输出:起点与终点相同

起点或终点不存在: -b 123 456 -map subway.txt -o routine.txt

输出:起点或终点不存在

查询线路不存在: -a 1000号线 -map subway.txt -o station.txt

输出:线路不存在

三、小结

本次个人作业中间出现了各种错误,其实还是对java代码的熟悉度不够,实验中多次出现Exception in thread "main" java.lang.NullPointerException的错误,主要因为数组为null了,没有初始化,浪费了很多时间找错,后续还要继续学习熟悉。

原文地址:https://www.cnblogs.com/31701085yc/p/11661278.html

时间: 2024-10-27 16:46:27

北京地铁规划项目总结的相关文章

北京地铁规划项目总结报告

本项目已上传Github: 问题重述: 任务: 实现一个帮助进行地铁出行线路规划的命令行程序 实现加载地铁线路信息 实现查询指定地铁线路信息 实现从指定出发地到目的地的最短路径查询 设计: 采用语言:java GitHub链接:https://github.com/xixihaha54/subway 主要模块介绍: 序号 模块名 功能 对应java类 1 主模块(subway) 对输入参数的控制 Subway.java 2 文件输入输出模块 txt文件的读写 DataBuilder.java 3

地铁规划项目需求理解和设计思路

地铁规划项目需求理解和设计思路 需求理解 将地铁线路保存成一个可读入,简洁明了的文本 程序能正确读入这个文件,并获取地铁线路信息 程序能正确处理输入的命令行 地铁能正确输出指定地铁线经过的站点 程序能正确输出两个站点间的最短路径 程序要有健壮性,能通过各类性能测试 按要求编写博客,详细说明花费时间,代码,各个模块和测试用例 设计思路 文本格式 1号线 刘园 西横堤 果酒厂 本溪路 勤俭道..... 2号线 曹庄 卞兴 荠园西道 咸阳路...... 3号线 小淀 丰产河 华北集团...... 按照

个人项目——北京地铁线路规划

一.前言 现实和理想的差距总是那么大,在过程中碰到的坑比预期的还多(说那么多,其实就是自己菜),过程中复习了淡忘已久的许多算法和数据结构,一边深刻的体会着自己是多菜,一边也体会到了自身一点点微小的进步,大概. 二.项目简介 实现北京地铁查询功能 附上一张北京地铁的图: 三.项目地址 https://github.com/fireworks-EX/MetroLinePlanning 四.需求分析 1.确定储存及读取地铁线路数据文件的格式 2.支持用户输入的地铁线路的查询 3.提供用户指定两站点间的

个人项目--北京地铁线路规划(已完成)

一.任务: 实现一个帮助进行北京地铁出行路线规划的命令行程序. 二.需求分析及实现 需求1 在程序启动时,自动获取到地图信息 需要实现一个支持自动加载subway.txt 文件的程序 需求2 查询指定地铁线经过的站点 在应用程序上,需要支持一个新的命令行参数  -a ,指定用户希望查询的地铁线路. 在给定地铁线路时,程序需要从线路的起始站点开始,依次输出该地铁线经过的所有站点,直到终点站.输出的文件使用-o参数来指定. 一个调用应用程序的示例如下: java subway -a 1号线 -map

北京地铁线路规划

北京地铁线路规划 任务 个人项目的主要任务就是通过地铁出行的人能够通过该软件很快找到最快到达目的地的出行线路规划. 项目需求 用户根据-map参数来获得所有北京地铁线路信息 java subway -map subway.txt 那么这里的重点就在于如何存储这个subway.txt文件了,首先我们还是看一张北京地铁1号线的图 ![](https://img2018.cnblogs.com/blog/1806411/201909/1806411-20190922113916097-18761194

北京地铁最短线路规划

一.项目需求 设计一个能进行北京地铁最短线路规划的程序. 二.文件存储 用一个名为data.txt的文件来存储所有北京地铁线路及站点信息,如下所示. 三.算法代码 本次项目的设计用到的语言是java语言,主要的规划最短路径的算法采用dijkstra算法 public class PathControl { private static List<Station> analysisList = new ArrayList<>(); private static HashMap<

北京地铁_结对项目_附加题

地铁出行项目(续)- 附加题 团队成员:杨金键 谢振威 金豪 要求描述: 使程序支持不同城市的地图.请让程序能处理上海的地铁地图,或者其它城市的地图.把程序由 “固定处理一个地图” 升级为 “能处理多个地图”, 程序的什么模块需要变化? 其实,在我们设计程序之初就已经考虑到了程序将来的可扩展性,所以无论是地图储存文件还是代码我们都是从这个角度出发考虑的. 具体来说: 取消所有对于北京地图的特殊化处理,针对特殊的地方,例如环线或者单行线则定义关键词统一处理 所有地图相关信息都靠文件读取,避免地图相

天津地铁出行线路规划项目需求分析与设计思路分析

天津地铁出行线路规划项目需求分析与设计思路分析 项目概要 以下是天津地铁线路总图,本项目的受众可以通过本软件,获得天津市地铁出行最便捷,最快速的线路推荐. 需求分析 实现一个帮助进行地铁出行路线规划的命令行程序. 支持地铁线路的更改,站点更改.取消与添加,以及线路的局部封闭. 支持查询线路的所有站点. 支持查询到某终止站点的途径最少站点的路线. 数据存储结构分析 由于单一的线路表与站点表是无法表示如此复杂的地铁线路情况的. 有多个前驱的站点如:,以及有多个后继的站点如:,这种情况无法只通过这两个

北京地铁项目

北京地铁项目 github:https://github.com/leo-xlz/Subway-beijing 模块分析----- zucc.edu.cn.model 存放站点信息和路径信息 station.java private String name;//站点名字 private String line;//所属路线 private List<Station> linkStations = new ArrayList<>();//相邻连接站点 routine.java · p