地铁路线规划

项目要求与实现

1、读出.txt文件上的路线数据 

2、实现北京地铁的线路查询和两站点最短路径查询

 

PSP表

PSP 2.1 Personal Software Process Stages Time
Planning 计划  
· Estimate · 估计这个任务需要多少时间 4h
Development 开发  
· Analysis · 需求分析 (包括学习新技术) 3h
· Design Spec · 生成设计文档 1h
· Design Review · 设计复审 (和同事审核设计文档) 2h
· Coding Standard · 代码规范 (为目前的开发制定合适的规范) 2h
· Design · 具体设计 2h
· Coding · 具体编码 2h
· Code Review · 代码复审 3h
· Test · 测试(自我测试,修改代码,提交修改) 3h
Reporting 报告  
· Test Report · 测试报告 2h
· Size Measurement · 计算工作量 2h
· Postmortem & Process Improvement Plan · 事后总结, 并提出过程改进计划 2h
--- 合计 3d

 

设计思路

  数据存储

    站点信息的数据存储在txt文件:

    地铁路线规划_第1张图片

 

 

 

测试

1、需求1: -map subway.txt  获得对应的自定义地铁文件

地铁路线规划_第2张图片

 

 

 地铁路线规划_第3张图片

  public static void writeFileString(String strings, String writeFileName) {
        File fileDir = new File(writeFileName);
        if(!fileDir.isFile()){
            try {
                fileDir.createNewFile();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        try {
            FileWriter fw = new FileWriter(fileDir);
            fw.write(strings);
            fw.flush();
            fw.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) throws IOException {
        String map = "-map \\S+ ";
        String line = "-a \\S+ -map \\S+ -o \\S+ ";
        String path = "-b \\S+ \\S+ -map \\S+ -o \\S+ ";

        String arge = "";

        for (String i : args) {
            arge += i + " ";
        }

        if (arge.matches(map)) {
            String readFile = args[1];
            StationIncludeLineName.readFile(readFile);
            for (List linename : StationIncludeLineName.lineSet) {
                for (int i = 0; i < linename.size(); i++) {
                    System.out.print(linename.get(i).getName() + "-->");
                }
                System.out.println();

            }
        } else if (arge.matches(line)) {
            String lineName = args[1];
            String readFile = args[3];
            String writeFile = args[5];
            StationIncludeLineName.readFile(readFile);
            Station station = new Station(lineName);
            String allStations = "";
            int flag = 0;//判断是否存在该路线
            for (List linename : StationIncludeLineName.lineSet) {
                if (linename.contains(station)) {
                    allStations+=linename.get(0).getName() + "包括的站点:"+"\n";
                    for (int i = 1; i < linename.size(); i++) {
                        allStations+=linename.get(i).getName() + "-->";
                    }
                    flag=1;
                }
            }
            if(flag==0){
                System.out.println("该路线不存在");

            }
            else{
                writeFileString(allStations, writeFile);
            }

        } else if (arge.matches(path)) {
            String start = args[1];
            String end = args[2];
            String readFile = args[4];
            String writeFile = args[6];
            DataBuilder.readFile(readFile);
            Subway sw = new Subway();
            String allStations = sw.calculate(new Station(start), new Station(end));
            writeFileString(allStations, writeFile);
        }else{
            System.out.println("输入参数有误");
        }
    }
}

2、需求2:-a 3号线 -map subway.txt -o station2.txt

地铁路线规划_第4张图片

 

 

地铁路线规划_第5张图片

 

 假如输入 -a 100号线 -map subway.txt -o station2.txt的命令,

 地铁路线规划_第6张图片

 

 系统会提示该路线不存在

假如输入错误的命令,例如-c 100号线 -map subway.txt -o station2.txt的命令,

地铁路线规划_第7张图片

 

 

3、需求3:-b 苹果园 北京西站 -map subway.txt -o routine.txt

寻找两站之间的最短路径:

public class Subway {

    private List outList = new ArrayList();//记录已经分析过的站点
    String allStations = "";

    //计算从s1站到s2站的最短经过路径, 并输出文件
    public String calculate(Station s1, Station s2) {

        //长度相等级找完了全部的路径,输出文件
        if (outList.size() == DataBuilder.totalStaion) {
//            System.out.println("找到目标站点:" + s2.getName() + ",共经过" + (s1.getAllPassedStations(s2).size() - 1) + "站");
            allStations+="找到目标站点:" + s2.getName() + ",共经过" + (s1.getAllPassedStations(s2).size() - 1) + "站"+"\n";

            for (Station station : s1.getAllPassedStations(s2)) {
//                System.out.print(station.getName() + "->");
                allStations+=station.getName() + ">>";
            }
            return allStations;
        }
        if (!outList.contains(s1)) {
            outList.add(s1);
        }
        //如果起点站的OrderSetMap为空,则第一次用起点站的前后站点初始化之
        if (s1.getOrderSetMap().isEmpty()) {
            List Linkedstations = getAllLinkedStations(s1);
            for (Station s : Linkedstations) {
                s1.getAllPassedStations(s).add(s);
            }
        }
        Station parent = getShortestPath(s1);//获取距离起点站s1最近的一个站(有多个的话,随意取一个)
        if (parent == s2) {
//            System.out.println("找到目标站点:" + s2 + ",共经过" + (s1.getAllPassedStations(s2).size() - 1) + "站");
            allStations+="找到目标站点:" + s2 + ",共经过" + (s1.getAllPassedStations(s2).size() - 1) + "站"+"\n";
            for (Station station : s1.getAllPassedStations(s2)) {
//                System.out.print(station.getName() + "->");
                allStations+=station.getName() + ">>";
            }
            return allStations;
        }
        for (Station child : getAllLinkedStations(parent)) {
            if (outList.contains(child)) {
                continue;
            }
            int shortestPath = (s1.getAllPassedStations(parent).size() - 1) + 1;//前面这个1表示计算路径需要去除自身站点,后面这个1表示增加了1站距离
            if (s1.getAllPassedStations(child).contains(child)) {
                //如果s1已经计算过到此child的经过距离,那么比较出最小的距离
                if ((s1.getAllPassedStations(child).size() - 1) > shortestPath) {
                    //重置S1到周围各站的最小路径
                    s1.getAllPassedStations(child).clear();
                    s1.getAllPassedStations(child).addAll(s1.getAllPassedStations(parent));
                    s1.getAllPassedStations(child).add(child);
                }
            } else {
                //如果s1还没有计算过到此child的经过距离
                s1.getAllPassedStations(child).addAll(s1.getAllPassedStations(parent));
                s1.getAllPassedStations(child).add(child);
            }
        }
        outList.add(parent);
        calculate(s1, s2);//重复计算,往外面站点扩展
        return allStations;
    }

    //取参数station到各个站的最短距离,相隔1站,距离为1,依次类推
    private Station getShortestPath(Station station) {
        int minPatn = Integer.MAX_VALUE;
        Station rets = null;
        for (Station s : station.getOrderSetMap().keySet()) {
            if (outList.contains(s)) {
                continue;
            }
            LinkedHashSet set = station.getAllPassedStations(s);//参数station到s所经过的所有站点的集合
            if (set.size() < minPatn) {
                minPatn = set.size();
                rets = s;
            }
        }
        return rets;
    }

    //获取参数station直接相连的所有站,包括交叉线上面的站
    private List getAllLinkedStations(Station station) {
        List linkedStaions = new ArrayList();
        for (List line : DataBuilder.lineSet) {
            if (line.contains(station)) {//如果某一条线包含了此站
                Station s = line.get(line.indexOf(station));
                if (s.prev != null) {
                    linkedStaions.add(s.prev);
                }
                if (s.next != null) {
                    linkedStaions.add(s.next);
                }
            }
        }
        return linkedStaions;
    }

    //文件写入
    public static void writeFileString(String strings, String writeFileName) {
        File fileDir = new File(writeFileName);
        if(!fileDir.isFile()){
            try {
                fileDir.createNewFile();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        try {
            FileWriter fw = new FileWriter(fileDir);
            fw.write(strings);
            fw.flush();
            fw.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

地铁路线规划_第8张图片

 

 

总结

 通过地铁项目的构建初步掌握了markdown及github工具的运用,但需要后续的操作练习。此外,该项目已被很多程序员们编写过,可以通过读他们已有代码来学习这个最短路径算法。

通过这次实验更加加深了最短路径算法的使用,但是还是有很多的不足,许多Java方法并不是很会。

 

 

 

你可能感兴趣的:(地铁路线规划)