欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

java实现Dijkstra最短路径算法

程序员文章站 2024-03-01 15:43:16
任务描述:在一个无向图中,获取起始节点到所有其他节点的最短路径描述 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;
 }
}

图的结构如下图所示:

java实现Dijkstra最短路径算法

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

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