接上篇需求分析:

https://www.cnblogs.com/Shevewinyei/p/13849379.html

一、算法描述:

迪杰斯特拉算法(Dijkstra)是由荷兰计算机科学家狄克斯特拉于1959 年提出的,因此又叫狄克斯特拉算法。是从一个顶点到其余各顶点的最短路径算法,解决的是有权图中最短路径问题。迪杰斯特拉算法主要特点是从起始点开始,采用贪心算法的策略,每次遍历到始点距离最近且未访问过的顶点的邻接节点,直到扩展到终点为止。

完整代码的github地址:https://github.com/Shevewinyei/SubwayChange

二、核心代码:

public static int Dijkstra(int startId,int endId,int[][] graph,int[] visit,int[] pre) {

//节点个数

int n = graph.length;

PriorityQueue pq = new PriorityQueue<>(new Node());

//将起点加入pq

pq.add(new Node(startId, 0));

while (!pq.isEmpty()){

Node t = pq.poll();

//当前节点是终点,即可返回最短路径

if(t.node == endId)

return t.cost;

//t节点表示还未访问

if (visit[t.node]==0){

//将节点设置为已访问

visit[t.node] = -1;

//将当前节点相连且未访问的节点遍历

for (int i = 0; i < n; i++) {

if (graph[t.node][i]!=0 && visit[i]==0) {

pq.add(new Node(i, t.cost + graph[t.node][i]));

pre[i] = t.node;

}

}

}

}

return -1;

}

三、解题思路:

四、station站点类代码:

public class station {

String stationName = ""; //站点名称

ArrayList LineID = new ArrayList();//站点所在的线路

ArrayList AdjacentStations = new ArrayList(); //相邻站点

boolean IsTransfer = false; //站点是否是换乘站

//设置站点名称

public void setName(String name) {

this.stationName = name;

}

//添加站点所在线路信息

public void addLineName(String id) {

this.LineID.add(id);

//如果站点所在线路出现多条,则可作为换乘点

if(LineID.size()>1) {

IsTransfer = true;

}

}

public void addAdjacentStations(station t) {

this.AdjacentStations.add(t);

}

public String getStationName() {

return this.stationName;

}

public ArrayList getLineName() {

return this.LineID;

}

public ArrayList getAdjacentStations(){

return this.AdjacentStations;

}

public boolean getIsTransfer() {

return this.IsTransfer;

}

}

如果觉得代码比较繁琐难读懂,可以直接看下面的图。

五、读取txt文件中的数据,构造包含所用station的集合(不重复)。在读取数据过程中,不断更新邻接矩阵。

/ /读取地铁线路数据,创建站点数组

public static void AddStation() throws FileNotFoundException {

Scanner in = new Scanner(new File("/Users/shenwenyan/eclipse-workspace/subwayChange/src/SubwayMessage.txt"));

while(in.hasNextLine()) {

String temp = in.nextLine();

String[] tokens = temp.split(" ");

//线路名称

String lineName = tokens[0];

for(int i=1;i

//先搜索list中是否存在该站点名称,则只添加线路和相邻节点(去重)

boolean t = false; //判断是否存在arraylist中

for(int j=0;j

if(stations.get(j).getStationName().equals(tokens[i])) {

stations.get(j).addLineName(lineName);

t = true;

break;

}

}

if(t==false) {

station a = new station();

a.setName(tokens[i]);

a.addLineName(lineName);

stations.add(a);

}

}

//添加相邻站点

for(int i=1;i

ADDAdjacentStations(tokens[i], tokens[i+1]);

}

}

}

//添加相邻节点并更新邻接矩阵

public static void ADDAdjacentStations(String name1,String name2) {

station t1 = findStation(name1);

station t2 = findStation(name2);

if(t1!=null && t2!=null) {

t1.addAdjacentStations(t2);

t2.addAdjacentStations(t1);

int x = findStationIndex(name1);

int y = findStationIndex(name2);

edges[x][y] = 1;

edges[y][x] = 1;

}

else {

//System.out.println("未找到该名称的站点!!!");

}

}

六、邻接矩阵更新完毕后,运用Dijkstra算法得出最短路径,并把结果打印出来。打印路径代码如下:

//打印路径并在其中判断是否换乘

public static void PrintPath(int startId,int endId) {

Stack Path = new Stack();

int end = endId;

//前置节点入栈,使得输出时候为正序

while(endId!=startId) {

Path.add(endId);

int temp = pre[endId];

endId = temp;

}

String lineString = "";

String nextLineString = "";

lineString = IsinOneLine(stations.get(startId), stations.get(Path.peek()));

System.out.println(stations.get(startId).getStationName()+lineString);

int i;

while(true){

i = Path.pop();

if(Path.isEmpty()) break;

nextLineString = IsinOneLine(stations.get(i), stations.get(Path.peek()));

//判断是否换线

if(nextLineString.equals(lineString)) {

//不换线

System.out.print(" ");

System.out.print("------->");

System.out.println(stations.get(i).getStationName());

}

else {

//换线

lineString = nextLineString;

System.out.print(" ");

System.out.print("------->");

System.out.println(stations.get(i).getStationName());

System.out.println("在 "+stations.get(i).getStationName()+" 换乘 "+lineString);

}

}

System.out.print(" ");

System.out.print("------->");

System.out.println(stations.get(end).getStationName());

}

七、主函数代码:

public static void main(String[] args) throws FileNotFoundException {

AddStation();

//特殊站点,手动加入连接

ADDAdjacentStations("T2航站楼", "三元桥");

ADDAdjacentStations("T3航站楼", "T2航站楼");

//输入起点站和终到站

System.out.print("请输入起点站:");

Scanner in = new Scanner(System.in);

String startNameString = in.next();

System.out.print("请输入终点站:");

in = new Scanner(System.in);

String endNameString = in.next();

//找到起点站和终点站

station startStation = findStation(startNameString);

station endStation = findStation(endNameString);

if(startStation==null&&endStation!=null){

System.out.println("起点站不存在!!!");

}

else if(endStation==null&&startStation!=null){

System.out.println("终点站不存在!!!");

}

else if(endStation==null&&startStation==null) {

System.out.println("起点站和终点站都不存在!!!");

}

else {

System.out.println("正在搜索.....");

int startId = findStationIndex(startNameString);

int endId = findStationIndex(endNameString);

//找最短路径

int[] visit = new int[Max]; //是否访问

int dis = Dijkstra(startId, endId,edges,visit,pre);

System.out.println("经过总站点数:"+ dis);

if(dis!=-1 && dis!=0) {

//打印路径

PrintPath(startId, endId);

}

else if(dis == -1){

System.out.println("无法到达!");

}

else if(dis == 0){

System.out.println("起点站和终点站为同一站!!!");

}

}

}

八、运行测试:

(1)测试输入时候起点站输入有误的情况

(2)测试输入时候终点站输入有误的情况

(3)测试输入时候起点和终点都不存在的情况

(4)测试输入同一个站点的情况

以上都是出现特殊情况的处理。以下测试正常查询:

(1)测试同一线路上乘车情况

(2)测试换乘的情况

九、总结:

(1)这次的个人项目的实践,对于我自己的编程能力有很大的帮助。学会如何去分析一个项目的需求,学会如何通过代码实现。

(2)以上代码还存在一定的不足之处,会通过后期的学习努力让代码更加完善完整。

java地铁最短距离_北京地铁最短路径(Java+Dijkstra算法)相关推荐

  1. 数据结构——最短路径之Dijkstra算法(与最小生成树的prime算法很像,建议一起看)

    最短路径之Dijkstra算法 (一)Dijkstra算法 单源最短路径:就是从某一个顶点出发,到图中任意顶点之间的最短路径: [算法概述]:Dijkstra算法适用于解决单源最短路径的问题.即:从源 ...

  2. python路径规划算法可视化_路径规划问题:DIJKSTRA算法 以及Python实现

    一. DJKSTRA算法概述 我们可以将地图抽象为Graph的数据结构,然后利用Graph的广度优先遍历算法(Breadth-First Search, BFS)解决无权重的High-Level的地图 ...

  3. dijkstra算法PHP,单源最短路径(dijkstra算法)php实现

    做一个医学项目,其中在病例评分时会用到单源最短路径的算法.单源最短路径的dijkstra算法的思路如下: 如果存在一条从i到j的最短路径(Vi.....Vk,Vj),Vk是Vj前面的一顶点.那么(Vi ...

  4. 最短路径之Dijkstra算法

    今天看了最短路径之Dijkstra算法,对这算法,写上自己的心得和感悟! 1.Dijkstra算法,(迪杰斯特拉)--单源最短路径 求的是一个源点到其他顶点的最短路径 算法描述 1).算法思想 设G= ...

  5. 最短路径问题——Dijkstra算法详解(单源最短路径)

    单源最短路径 单源最短路径,是指从图中任一点出发到其他各点之间的最短路径. Dijkstra算法介绍 Dijkstra算法又称迪杰特斯拉算法,dijkstra算法的核心思想是将全部结点所在集合V分成两 ...

  6. 最短路径(Dijkstra算法),一文必看懂最短路径的方法

    最短路径问题(Dijkstra算法) 从图中的某一个顶点出发到达另一个顶点的所经过的边的权重和最小的一条路径,称为最短路径. Dijkstra算法适用于求一个节点到其他节点的最短路径,主要特点是通过广 ...

  7. 最短路径的Dijkstra算法(邻接表)

    原文:http://blog.csdn.net/axiqia/article/details/50984464 描述 以邻接表作为存储结构实现,求解从给定源点到给定结束点的最短路径. 输入 从1开始表 ...

  8. 图的单源最短路径:Dijkstra算法实现

    本文介绍的是图的非负权值的单源最短路径问题.问题的提出是,对于有权图D,t提供源点v,要找到从v到其他所有点的最短路径,即单源最短路径问题,在本文中,解决这一问题,是普遍比较熟悉的Dijkstra算法 ...

  9. java地铁最短距离_地铁线路最短路径问题

    项目介绍 主要功能 提供一副地铁线路图,计算指定两站之间最短(最少经过站数)乘车路线:输出指定地铁线路的所有站点.以北京地铁为例,地铁线路信息保存在data.txt中,格式如下: 地铁线路总数 线路名 ...

  10. java地铁最短距离_动手构建地铁关系网,实现最短路径查询

    一.前言 打开手机'北京地铁'APP,输入起始点:霍营,终点:北京南站,发现系统给我们推荐了两条路线. 最短时间路线与最少换乘路线,并且分别给出了耗时与乘坐里程费.看到这里,不禁开启了靓仔疑问,假如给 ...

最新文章

  1. 30行Python代码实现高分辨率图像导航
  2. 去除行块级标签之间的默认间距
  3. 虚拟机上的ubuntu安装vmware tools
  4. JavaScript中的作用域、作用域链、预解析
  5. 349. 两个数组的交集 golang
  6. R语言基础入门(6)之向量下标和子集
  7. Hadoop HIVE 基本函数
  8. 在taobao上安家了,欢迎大家来选购呀
  9. linux非编工作站,高清EDIUS非编网络系统建设 在线非编系统
  10. 阿里面试题,深入理解Java类加载机制
  11. html可编辑下拉选项卡,bootstrap可编辑下拉框jquery.editable-select
  12. oem10g grid control
  13. 项目管理十大知识领域之项目整合管理
  14. Java 链表元素如何从键盘输入 面试 笔试高频
  15. Bat文件的创建及其命令大全
  16. 您的服务器组件没有得到合法授权,服务器将会受限模式运行
  17. 天龙八部3d最新服务器,天龙八部3D妙笔生花新服务器开启公告
  18. 一个留美女博士的七年----分享给所有还相信梦想的朋友(zz 喜欢~~)
  19. 笔记本开热点手机一直显示正在获取ip
  20. python发送图片邮件exchangelib_Python3.5 执行发邮件Exchangelib(=)

热门文章

  1. 计算机主板自动重启,电脑开机后自动重启,详细教您电脑开机后自动重启如何解决...
  2. 30岁人生进度条_人生的进度条
  3. 表面氨基/羧基/巯基/甲氨基功能化修饰的Fe3O4磁性纳米颗粒
  4. 路由在电话网和计算机网中的区别,计算机猫和路由器之间有什么区别
  5. 联想贺志强:联想专利其实很牛 只是你不知道
  6. 无线信道的选择性衰落
  7. xp系统总是弹出宽带连接服务器,XP系统电脑总是弹出拨号连接怎么办-系统城...
  8. 计算n阶行列式的C语言实现
  9. lamp平台构建和phpMyAdmin工具
  10. 计算机设计大赛参赛作品——疫情看板