java实现Dijkstra最短路径算法

任务描述:在一个无向图中,获取起始节点到所有其他节点的最短路径描述

Dijkstra(迪杰斯特拉)算法是典型的最短路径路由算法,用于计算一个节点到其他所有节点的最短路径。主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止。

Dijkstra一般的表述通常有两种方式,一种用永久和临时标号方式,一种是用OPEN, CLOSE表方式
用OPEN,CLOSE表的方式,其采用的是贪心法的算法策略,大概过程如下:

1.声明两个集合,open和close,open用于存储未遍历的节点,close用来存储已遍历的节点
2.初始阶段,将初始节点放入close,其他所有节点放入open
3.以初始节点为中心向外一层层遍历,获取离指定节点最近的子节点放入close并从新计算路径,直至close包含所有子节点

代码实例如下:

Node对象用于封装节点信息,包括名字和子节点

public class Node {
 private String name;
 private Map<Node,Integer> child=new HashMap<Node,Integer>();
 public Node(String name){
 this.name=name;
 }
 public String getName() {
 return name;
 }
 public void setName(String name) {
 this.name = name;
 }
 public Map<Node, Integer> getChild() {
 return child;
 }
 public void setChild(Map<Node, Integer> child) {
 this.child = child;
 }
}

MapBuilder用于初始化数据源,返回图的起始节点

public class MapBuilder {
 public Node build(Set<Node> open, Set<Node> close){
 Node nodeA=new Node("A");
 Node nodeB=new Node("B");
 Node nodeC=new Node("C");
 Node nodeD=new Node("D");
 Node nodeE=new Node("E");
 Node nodeF=new Node("F");
 Node nodeG=new Node("G");
 Node nodeH=new Node("H");
 nodeA.getChild().put(nodeB, 1);
 nodeA.getChild().put(nodeC, 1);
 nodeA.getChild().put(nodeD, 4);
 nodeA.getChild().put(nodeG, 5);
 nodeA.getChild().put(nodeF, 2);
 nodeB.getChild().put(nodeA, 1);
 nodeB.getChild().put(nodeF, 2);
 nodeB.getChild().put(nodeH, 4);
 nodeC.getChild().put(nodeA, 1);
 nodeC.getChild().put(nodeG, 3);
 nodeD.getChild().put(nodeA, 4);
 nodeD.getChild().put(nodeE, 1);
 nodeE.getChild().put(nodeD, 1);
 nodeE.getChild().put(nodeF, 1);
 nodeF.getChild().put(nodeE, 1);
 nodeF.getChild().put(nodeB, 2);
 nodeF.getChild().put(nodeA, 2);
 nodeG.getChild().put(nodeC, 3);
 nodeG.getChild().put(nodeA, 5);
 nodeG.getChild().put(nodeH, 1);
 nodeH.getChild().put(nodeB, 4);
 nodeH.getChild().put(nodeG, 1);
 open.add(nodeB);
 open.add(nodeC);
 open.add(nodeD);
 open.add(nodeE);
 open.add(nodeF);
 open.add(nodeG);
 open.add(nodeH);
 close.add(nodeA);
 return nodeA;
 }
}

图的结构如下图所示:

Dijkstra对象用于计算起始节点到所有其他节点的最短路径

public class Dijkstra {
 Set<Node> open=new HashSet<Node>();
 Set<Node> close=new HashSet<Node>();
 Map<String,Integer> path=new HashMap<String,Integer>();//封装路径距离
 Map<String,String> pathInfo=new HashMap<String,String>();//封装路径信息
 public Node init(){
 //初始路径,因没有A->E这条路径,所以path(E)设置为Integer.MAX_VALUE
 path.put("B", 1);
 pathInfo.put("B", "A->B");
 path.put("C", 1);
 pathInfo.put("C", "A->C");
 path.put("D", 4);
 pathInfo.put("D", "A->D");
 path.put("E", Integer.MAX_VALUE);
 pathInfo.put("E", "A");
 path.put("F", 2);
 pathInfo.put("F", "A->F");
 path.put("G", 5);
 pathInfo.put("G", "A->G");
 path.put("H", Integer.MAX_VALUE);
 pathInfo.put("H", "A");
 //将初始节点放入close,其他节点放入open
 Node start=new MapBuilder().build(open,close);
 return start;
 }
 public void computePath(Node start){
 Node nearest=getShortestPath(start);//取距离start节点最近的子节点,放入close
 if(nearest==null){
  return;
 }
 close.add(nearest);
 open.remove(nearest);
 Map<Node,Integer> childs=nearest.getChild();
 for(Node child:childs.keySet()){
  if(open.contains(child)){//如果子节点在open中
  Integer newCompute=path.get(nearest.getName())+childs.get(child);
  if(path.get(child.getName())>newCompute){//之前设置的距离大于新计算出来的距离
   path.put(child.getName(), newCompute);
   pathInfo.put(child.getName(), pathInfo.get(nearest.getName())+"->"+child.getName());
  }
  }
 }
 computePath(start);//重复执行自己,确保所有子节点被遍历
 computePath(nearest);//向外一层层递归,直至所有顶点被遍历
 }
 public void printPathInfo(){
 Set<Map.Entry<String, String>> pathInfos=pathInfo.entrySet();
 for(Map.Entry<String, String> pathInfo:pathInfos){
  System.out.println(pathInfo.getKey()+":"+pathInfo.getValue());
 }
 }
 /**
 * 获取与node最近的子节点
 */
 private Node getShortestPath(Node node){
 Node res=null;
 int minDis=Integer.MAX_VALUE;
 Map<Node,Integer> childs=node.getChild();
 for(Node child:childs.keySet()){
  if(open.contains(child)){
  int distance=childs.get(child);
  if(distance<minDis){
   minDis=distance;
   res=child;
  }
  }
 }
 return res;
 }
}

Main用于测试Dijkstra对象

public class Main {
 public static void main(String[] args) {
 Dijkstra test=new Dijkstra();
 Node start=test.init();
 test.computePath(start);
 test.printPathInfo();
 }
}

打印输出如下:

D:A->D
E:A->F->E
F:A->F
G:A->C->G
B:A->B
C:A->C
H:A->B->H

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • java实现dijkstra最短路径寻路算法

    [引用]迪杰斯特拉(Dijkstra)算法是典型最短路径算法,用于计算一个节点到其他节点的最短路径. 它的主要特点是以起始点为中心向外层层扩展(广度优先搜索思想),直到扩展到终点为止. 基本思想 通过Dijkstra计算图G中的最短路径时,需要指定起点s(即从顶点s开始计算). 此外,引进两个集合S和U.S的作用是记录已求出最短路径的顶点(以及相应的最短路径长度),而U则是记录还未求出最短路径的顶点(以及该顶点到起点s的距离). 初始时,S中只有起点s:U中是除s之外的顶点,并且U中顶点的路径是

  • Java实现Floyd算法求最短路径

    本文实例为大家分享了Java实现Floyd算法求最短路径的具体代码,供大家参考,具体内容如下 import java.io.FileInputStream; import java.io.FileNotFoundException; import java.util.Scanner; public class TestMainIO { /** * @param args * @throws FileNotFoundException */ public static void main(Stri

  • java实现最短路径算法之Dijkstra算法

    前言 Dijkstra算法是最短路径算法中为人熟知的一种,是单起点全路径算法.该算法被称为是"贪心算法"的成功典范.本文接下来将尝试以最通俗的语言来介绍这个伟大的算法,并赋予java实现代码. 一.知识准备: 1.表示图的数据结构 用于存储图的数据结构有多种,本算法中笔者使用的是邻接矩阵. 图的邻接矩阵存储方式是用两个数组来表示图.一个一维数组存储图中顶点信息,一个二维数组(邻接矩阵)存储图中的边或弧的信息. 设图G有n个顶点,则邻接矩阵是一个n*n的方阵,定义为: 从上面可以看出,无

  • java使用Dijkstra算法实现单源最短路径

    单源最短路径问题,即在图中求出给定顶点到其它任一顶点的最短路径.在弄清楚如何求算单源最短路径问题之前,必须弄清楚最短路径的最优子结构性质. 一.最短路径的最优子结构性质 该性质描述为:如果P(i,j)={Vi....Vk..Vs...Vj}是从顶点i到j的最短路径,k和s是这条路径上的中间顶点,那么P(k,s)必定是从k到s的最短路径.下面证明该性质的正确性. 假设P(i,j)={Vi....Vk..Vs...Vj}是从顶点i到j的最短路径,则有P(i,j)=P(i,k)+P(k,s)+P(s,

  • Java实现Dijkstra输出最短路径的实例

    Java实现Dijkstra输出指定起点到终点的最短路径 前言: 最近在公司参加了一个比赛,其中涉及的一个问题,可以简化成如是描述:一个二维矩阵,每个点都有权重,需要找出从指定起点到终点的最短路径. 马上就想到了Dijkstra算法,所以又重新温故了一遍,这里给出Java的实现. 而输出最短路径的时候,在网上也进行了查阅,没发现什么标准的方法,于是在下面的实现中,我给出了一种能够想到的比较精简的方式:利用prev[]数组进行递归输出. package graph.dijsktra; import

  • Java实现利用广度优先遍历(BFS)计算最短路径的方法

    本文实例讲述了Java实现利用广度优先遍历(BFS)计算最短路径的方法.分享给大家供大家参考.具体分析如下: 我们用字符串代表图的顶点(vertax),来模拟学校中Classroom, Square, Toilet, Canteen, South Gate, North Gate几个地点,然后计算任意两点之间的最短路径. 如下图所示: 如,我想从North Gate去Canteen, 程序的输出结果应为: BFS: From [North Gate] to [Canteen]: North Ga

  • java实现单源最短路径

    本文采用java实现单源最短路径,并带有略微详细的注解,供大家参考,具体内容如下 package com.qf.greaph; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.Map; import java.util.Map.Entry; /** * @author jiayoo * 7 / 30 * Dijkstra最短路径算法是一种单源最短路径 *

  • java实现Dijkstra最短路径算法

    任务描述:在一个无向图中,获取起始节点到所有其他节点的最短路径描述 Dijkstra(迪杰斯特拉)算法是典型的最短路径路由算法,用于计算一个节点到其他所有节点的最短路径.主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止. Dijkstra一般的表述通常有两种方式,一种用永久和临时标号方式,一种是用OPEN, CLOSE表方式 用OPEN,CLOSE表的方式,其采用的是贪心法的算法策略,大概过程如下: 1.声明两个集合,open和close,open用于存储未遍历的节点,close用来存储

  • PHP实现的迪科斯彻(Dijkstra)最短路径算法实例

    本文实例讲述了PHP实现的迪科斯彻(Dijkstra)最短路径算法.分享给大家供大家参考,具体如下: 一.待解决问题 单源最短路径问题,在给定有向图中求一个顶点(单源顶点)到其他所有顶点的最短路径问题.在下图中,每条边上有一个权值,希望求解A到所有其他顶点(B/C/D/E/F/G)的最短路径. 二.问题分析(最短路径的子结构同样最优性) 如果P(A,G)是从顶点A到G的最短路径,假设D和F是这条路径上的中间点,那么P(D,F)一定时从D到F的最短路径.如果P(D,F)不是D到F的最短路径,那必然

  • Dijkstra最短路径算法实现代码

    Dijkstra的最短路径算法是基于前驱顶点的最短路径计算的,整体上来讲还是比较简单的,下面是代码: 复制代码 代码如下: #include <iostream>#include <vector>#include <limits> void shortestpath( const std::vector <std::vector< short> >& paths, int from, std::vector< short>&a

  • Java利用Dijkstra算法求解拓扑关系最短路径

    目录 算法简介 代码实现思路 算法思想 代码示例 算法简介 迪杰斯特拉算法(Dijkstra)是由荷兰计算机科学迪家迪杰斯特拉于1959年提出的,因此又叫狄克斯特拉算法.是从一个顶点到其余各顶点最短路劲算法,解决的是有权图中最短路径问题.迪杰斯特拉算法主要特点是从起始点开始,采用贪心算法的策略,每次遍历到始点距离最近且未访问过的顶点的邻接节点,直到扩展到终点为止. 代码实现思路 1.先初始化源节点(起始点)到其他各个拓扑节点的最短距离,可以用map存放,key为节点,value为节点到源节点的距

  • Java利用Dijkstra和Floyd分别求取图的最短路径

    目录 1 最短路径的概述 2 杰斯特拉(Dijkstra)算法 2.1 原理 2.2 案例分析 3 弗洛伊德(Floyd)算法 3.1 原理 3.2 案例分析 4 邻接矩阵加权图实现 5 邻接表加权图实现 本文详细介绍了图的最短路径的概念,然后介绍了求最短路径的两种算法:Dijkstra算法和Floyd算法的原理,最后提供了基于邻接矩阵和邻接表的图对两种算法的Java实现. 阅读本文需要一定的图的基础,如果对于图不是太明白的可以看看这篇文章:Java数据结构之图的原理与实现. 1 最短路径的概述

  • 详解Java中Dijkstra(迪杰斯特拉)算法的图解与实现

    目录 简介 工作过程 总体思路 实现 小根堆 Dijsktra 测试 简介 Dijkstra(迪杰斯特拉)算法是典型的单源最短路径算法,用于计算一个节点到其他所有节点的最短路径.主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止.Dijkstra算法是很有代表性的最短路径算法,在很多专业课程中都作为基本内容有详细的介绍,如数据结构,图论,运筹学等等.注意该算法要求图中不存在负权边.对应问题:在无向图G=(V,E)中,假设每条边E(i)的长度W(i),求由顶点V0到各节点的最短路径. 工作过

  • Java实现Dijkstra算法的示例代码

    目录 一 问题描述 二 实现 三 测试 一 问题描述 小明为位置1,求他到其他各顶点的距离. 二 实现 package graph.dijkstra; import java.util.Scanner; import java.util.Stack; public class Dijkstra { static final int MaxVnum = 100; // 顶点数最大值 static final int INF = 0x3f3f3f3f; //无穷大 static final int

随机推荐