700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > java地铁最短距离_北京地铁最短路径(Java+Dijkstra算法)

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

时间:2023-09-08 20:23:43

相关推荐

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

接上篇需求分析:

/Shevewinyei/p/13849379.html

一、算法描述:

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

完整代码的github地址:/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)以上代码还存在一定的不足之处,会通过后期的学习努力让代码更加完善完整。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。