个人项目——北京地铁最短路径查询

 

北京地铁线路图

题目要求

题目目的

  • 完成一个可以实现北京地铁最短路径的问题

题目所使用环境

  • Windows10 64-bits系统,采用语言为java,使用jdk为1.8,使用jet beans idel开发软件
  • 使用GitHub进行代码的存储,版本的管理

作业提交方式

  • 通过博客园定期汇报作业情况
  • 最后的代码存在于GitHub上上传保存并提交作业文件
  • 测试用例一并以txt文件保存在GitHub中

需求分析

  • 需要完成一个输入地铁两个站点返回最近路程的程序
  • 确认文本输入输出的基本格式
  • 经过多次测试保持程序的稳定产生结果

设计思路

本次实验准备采用已经学过的Floyd算法

地铁图输入格式

  本次实验的线路输入采用文件输入进行标准输入格式,每行的第一个string表示的是线路名称,之后由空格间隔出包含在此线路中的站点名称。

 

  本次实验的站点查询输入采用GUI所绘制的界面的方式进行查询,即输入两个站点的名称即可返回各项数据,并且在此UI界面中可以查询各条线路中包含的站点

地铁图输出格式

  上图所示的是易于使用的GUI图所操作的界面,除此之外,项目还带有文件的输出方式,当查询完后,在后台会自动生成一个subwayout,txt的文件用来记录详细信息

 

算法设计

  本次使用的算法是Floyd算法,是通过动态规划来实现最短路径实现的一种方法

核心算法

  Floyd算法核心代码:

  通过类中的邻接矩阵可以很方便的了解到各两个站点间最短的路线,并且通过onepath数组可以保存此线路中的路线站点顺序

    public Floyd(int[][] G) {
        int row = G.length;// 图G的行数
        int[][] spot = new int[row][row];// 定义任意两点之间经过的点
        int[] onePath = new int[row];// 记录一条路径
        this.length = G;
        path = new int[row][row][];
 
        for (int i = 0; i < row; i++)
            // 初始化为任意两点之间没有路径
            for (int j = 0; j < row; j++)
                spot[i][j] = -1;
 
        for (int i = 0; i < row; i++)
            // 假设任意两点之间的没有路径
            onePath[i] = -1;
 
        for (int u = 0; u < row; ++u)
            for (int v = 0; v < row; ++v)
                for (int w = 0; w < row; ++w)
                    if (length[v][w] > length[v][u] + length[u][w]) {
                        length[v][w] = length[v][u] + length[u][w];// 如果存在更短路径则取更短路径
                        spot[v][w] = u;// 把经过的点加入
                    }
 
        for (int i = 0; i < row; i++) {
            // 求出所有的路径 i -> j
            int[] point = new int[1];// 经过的点数
            for (int j = 0; j < row; j++) {
                point[0] = 0;
                onePath[point[0]++] = i;// 起i点为自身
                outputPath(spot, i, j, onePath, point);// 更新onePath
                path[i][j] = new int[point[0]];
                for (int s = 0; s < point[0]; s++)
                    path[i][j][s] = onePath[s];
            }
        }


    }
 
    private void outputPath(int[][] spot, int i, int j, int[] onePath,
            int[] point) {
        // 输出i 到j 的路径的实际代码,point[]记录一条路径的长度
        if (i == j)
            return;
        if (spot[i][j] == -1)
            onePath[point[0]++] = j;// 中间没有经过其他节点,即直接到达
        else {
            outputPath(spot, i, spot[i][j], onePath, point);
            outputPath(spot, spot[i][j], j, onePath, point);
        }
    }

特殊测试案例

1.同站点情况

 

2.超长路线

 

 3.线路内环线

 

 

4.站点不存在

 

 5.输入为空

 

总结

  本次的项目中的算法其实理解并不是太难,难点是在数据的初始化和如何输入变成邻接矩阵这块,而数据的输出我也选择了较为简单操作的GUI进行数据的输出,总体来说本次实验让我更加的熟练了java中算法中类的实现,并且也让我知道了作为一个程序员不能闭门造车,要多去看优秀的代码,从而在自己日常的编程中也来运用相应的习惯从而达到事倍功半的效果。

Github链接

  https://github.com/Clover-yee/Subway

 

posted on 2019-10-14 18:50  31705466叶力  阅读(498)  评论(0编辑  收藏  举报