一、实验目的

通过本实验的学习理解Dijkstra算法,并且编码实现最短路径问题。

二、实验内容

本Dijkstra算法实验采用了java实现,所以解决方案也使用了java中的接口,有map映射还有set集合。

Dijkstra算法属于一种贪心算法,它使用了广度优先搜索来解决带有权值的有向图或者无向图的单源最短路径问题,该算法不能计算带有负权值的有向图或无向图,该算法的目的是求其他节点到源的最短路径。

Dijkstra算法采用的是一种贪心的策略,利用Map对象path存储每个节点名称和这个节点到相邻节点的距离,使用set集合保存已经找到了最短路径的节点的集合close,用set对象open存储未处理的节点的集合。初始时,原点a的路径权重被赋为 0 。同时设所有其他(a不能直接到达的)节点的路径长度MAX_VALUE。初始时,close中只有节点s。 然后,从节点a开始,遍历所有节点,选出距离a节点最短的key值,取代a节点。并把这个最短距离存到path中。然后,我们需要看看新加入的节点是否可以到达其他顶点并且看看通过该节点到达其他点的路径长度是否比a点直接到达短,如果是,那么就替换这些顶点在PATH中的值。 然后,又找下一个里节点最近的key值,重复上述动作,直到close中包含了图的所有顶点。

三、实验要求

编码实现下图中顶点A到任一顶点的最短路径:

四、实验过程

1、过程分析

首先,利用继承Map接口的HashMap类存储图中的信息,其中的key为图中的各节点的名称,value为各节点与相应节点之间连线的权值。而Map对象Path存储的是a节点到各个子节点的权值,以及该节点的名称,另一个Map对象child中存储的是各个节点到相邻节点的权值和该节点的名称,而Map对象PathInfo存储的是路径信息。

之后就是开始实现Dijkstra算法了,本代码中封装了一个Dijkstra类,包括getshortestPath,computPath,PrintPathInfo.三个方法。

顾名思义,getshortestPath方法是用来求最短路径的,他返回的是一个节点,给这个类一个实参,即节点,遍历图中依然留在open中的节点,利用之前在child中储存的权值信息,可以得到离实参这个节点最近的节点。其中的关键过程就是比较现在的distance和minDis,如果distance小,就会被赋值给minDis,随着遍历的进行,minDis不断被赋值,遍历结束后,minDis的值就是最短距离,而相对应的key值,就是离实参这个节点最近的子节点。

computPath方法是用来计算节点之间的距离的,该方法的关键过程就是首先利用上面的getshortestPath方法获取离上一个源点最近的子节点nearst,然后在该节点的基础上,求open中的节点到a点的路径newCompute,如果newCompute这个值小于Path中储存的该open中的节点到a节点的距离,那么就用这个newCompute替换Path中的值,同时更新PathInfo的值。其中newCompute的求法是拿Path中nearst节点对应的权值加上child中该open中的节点到nearst的权值。该类通过递归实现Path中的value不断被更小的值赋值,从而得到最终的最短路径。

PrintPathInfo方法是用来打印路径信息的,打印的是PathInfo中的键值。

2、实验结果

五、实验总结

关于Dijkstra算法,刚开始做的时候遇到了较大的阻力,为了更好的理解这个算法的思想,我们从网上找了四五个关于这个算法的例子,不断地模拟解决过程,最终得到了Dijkstra算法的精髓,明白了关于其中的过程。这个过程花了很长时间,之后就是用代码实现了,因为该算法涉及键值对,恰好java语言中有Map接口,所以我们就选择了java作为基础语言去实现这个Dijkstra算法,其中也是历经了千辛万苦,所幸的是,java中关于set集合,和Map接口的子类以及他们的方法让我们更加熟悉,通过这次实验我们不仅进一步的学习了java,也掌握了一门算法,总之,过程是苦的,但是结果很快乐。

感谢教授本实验的老师,让我们获取了这样一个吸收知识的机会,只是我们自身有很多只是漏洞,需要进一步的学习。

附录(源代码)

package cn.sal.lisan;

import java.util.HashMap;

import java.util.HashSet;

import java.util.Map;

import java.util.Set;

import cn.sal.Lisan2.MapBuilder;

import cn.sal.Lisan2.Node;

class Node {

private String name;

private Map child=new HashMap<>();

public Node(String name){

this.name=name;

}

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

public Map getChild() {

return child;

}

public void setChild(Map child) {

this.child = child;

}

}

class MapBuilder {

public Node build(Set open, Set 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类里的getchild()方法,再利用散列映射的put方法,将其他节点和权值关联后添加进去

nodeA.getChild().put(nodeB, 6);

nodeA.getChild().put(nodeC, 3);

nodeB.getChild().put(nodeA, 6);

nodeB.getChild().put(nodeC, 2);

nodeB.getChild().put(nodeD, 5);

nodeC.getChild().put(nodeA, 3);

nodeC.getChild().put(nodeB, 2);

nodeC.getChild().put(nodeD, 3);

nodeC.getChild().put(nodeE, 4);

nodeD.getChild().put(nodeB, 5);

nodeD.getChild().put(nodeC, 3);

nodeD.getChild().put(nodeF, 3);

nodeD.getChild().put(nodeE, 2);

nodeE.getChild().put(nodeC, 4);

nodeE.getChild().put(nodeD, 2);

nodeE.getChild().put(nodeF, 5);

nodeF.getChild().put(nodeD, 3);

nodeF.getChild().put(nodeE, 5);

open.add(nodeB);

open.add(nodeC);

open.add(nodeD);

open.add(nodeE);

open.add(nodeF);

close.add(nodeA);

return nodeA;

}

}

class Dijkstra {

Set open = new HashSet();

Set close = new HashSet();

Map path = new HashMap();//封装路径距离

Map pathInfo = new HashMap();//封装路径信息

public Node init() {

//初始路径,因没有A->E这条路径,所以path(E)设置为Integer.MAX_VALUE

path.put("B", 6);

pathInfo.put("B", "A->B");

path.put("C", 3);

pathInfo.put("C", "A->C");

path.put("D", Integer.MAX_VALUE);

pathInfo.put("D", "A->D");

path.put("E", Integer.MAX_VALUE);

pathInfo.put("E", "A");

path.put("F", Integer.MAX_VALUE);

pathInfo.put("F", "A->F");

//将初始节点放入close,其他节点放入open

Node start = new MapBuilder().build(open, close);

return start;

}

/**

* 获取与node最近的子节点

*/

private Node getShortestPath(Node node) {

Node res = null;

int minDis = Integer.MAX_VALUE;

Map childs = node.getChild();

// 遍历与Node相连接的所有节点,选取其中距离最短的节点

for (Node child : childs.keySet()) {//keyset()方法用来返回键即节点

if (open.contains(child)) {

int distance = childs.get(child);

if (distance < minDis) {

minDis = distance;

res = child;

}

}

}

return res;

}

/*

* 计算路径

*

*

*

*/

public void computePath(Node start) {

//取距离start节点最近的子节点,放入close

Node nearest = getShortestPath(start);

if (nearest == null) {

return;

}

close.add(nearest);     //已遍历的

open.remove(nearest);   //未遍历的

Map childs = nearest.getChild();//getChild()返回child 对象,

//child中存储了各节点到相邻节点的距离·

for (Node child : childs.keySet()) {//遍历最近的节点

if (open.contains(child)) {//如果子节点在open中

Integer newCompute = path.get(nearest.getName()) + childs.get(child);

//Map接口的get()方法用来返回key所对应的value,

//此句是用来计算neareset这个节点到每个子节点的距离

if (newCompute < path.get(child.getName())) {

//新计算出来的距离小于之前设置的距离

path.put(child.getName(), newCompute);

pathInfo.put(child.getName(), pathInfo.get(nearest.getName()) + "->" + child.getName());

}

//本if语句可以用来更新A到子节点的最短距离

}

}

computePath(start);//重复执行自己,确保所有子节点被遍历

computePath(nearest);//向外一层层递归,直至所有顶点被遍历

}

public void printPathInfo() {

//entrySet()返回此映射中包含的映射关系的set视图

Set> pathInfos = pathInfo.entrySet();

for (Map.Entry pathInfo : pathInfos) {

System.out.println(pathInfo.getKey() + ":" + pathInfo.getValue());

}

}

}

public class DijkstraTest {

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

Dijkstra test=new Dijkstra();

Node start=test.init();

test.computePath(start);

test.printPathInfo();

}

}

java实现dijkstra_Dijkstra算法java实现相关推荐

  1. JAVA分析html算法(JAVA网页蜘蛛算法)

    近来有些朋友在做蜘蛛算法,或者在网页上面做深度的数据挖掘.但是遇到复杂而繁琐的html页面大家都望而却步.因为很难获取到相应的数据. 最古老的办法的是尝试用正则表达式,估计那么繁琐的东西得不偿失,浪费 ...

  2. java实现图片切割_【Java】K-means算法Java实现以及图像切割

    1.K-means算法简述以及代码原型 总的来讲,k-means聚类须要下面几个步骤: ①.初始化数据 ②.计算初始的中心点,能够随机选择 ③.计算每一个点到每一个聚类中心的距离.而且划分到距离最短的 ...

  3. 【Java】K-means算法Java实现以及图像分割

    1.K-means算法简述以及代码原型 数据挖掘中一个重要算法是K-means,我这里就不做详细介绍.如果感兴趣的话可以移步陈皓的博客: http://www.csdn.net/article/201 ...

  4. 通过网页查看服务器算法,java分析html算法(java网页蜘蛛算法示例)

    遇到复杂而繁琐的html页面大家都望而却步.因为很难获取到相应的数据. 最古老的办法的是尝试用正则表达式,估计那么繁琐的东西得不偿失,浪费我们宝贵的时间. 第二个办法用开源组织htmlparser的包 ...

  5. java代码隐藏面消除算法,java常面的几种排序算法

    冒泡排序 1.算法步骤: 1)比较相邻的元素.如果第一个比第二个大,就交换他们两个. 2)对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对.这步做完后,最后的元素会是最大的数. 3)针对所有 ...

  6. java实现神经网络算法,java调用神经网络模型

    如何用70行Java代码实现神经网络算法 . 如何用70行Java代码实现神经网络算法import.Random;publicclassBpDeep{publicdouble[][]layer;//神 ...

  7. svm算法的java实现,svm算法java实现

    他不仅提供了 LIBSVM 的 C++语言的算法源代码,还提供了 Python. Java.R.MATLAB.Perl.Ruby.LabVIEW 以及 C#.net 等各种语言的接口, 可以方便的在 ...

  8. java 计算星座算法,java 依据生日计算星座

    当前位置:我的异常网» 编程 » java 依据生日计算星座 java 依据生日计算星座 www.myexceptions.net  网友分享于:2013-09-06  浏览:344次 java 根据 ...

  9. 【Java】——基础算法Java代码

    随学随更,方便复习 选择排序: package one;/*** @author 新时代好少年* @create 2022-07-08 8:02* 选择排序:时间复杂度O(n^2) 空间复杂度O(1) ...

最新文章

  1. asp.net request编码问题,(转载)
  2. 利用JS弹出层实现简单的动态提示“正在加载中,请稍等...”
  3. caffe linux 教程,CentOS7安装Caffe的教程详解
  4. BeetleX网关之请求聚合
  5. 向银行贷款20万, 分期三年买50万的车,个人借款40万, 贷款10年买200万的房子,再贷款120万分创业...
  6. 怎么在前台取的ViewBag中的值
  7. 关于电路的书的读后感_通知 | 2021.1.1日起,专利和集成电路布图设计收费启用电子票据...
  8. django ajax页面加载,Python Django 之 基于JQUERY的AJAX 登录页面
  9. Unity3d 调用C++写的DLL
  10. 5年没发论文,读博想放弃?中科大博导万字自述:曾连收13封拒稿信...
  11. 降低软件购置成本 实现系统集中部署 ——沟通CTBS平台上海工化院应用案例
  12. 浪潮存储实至名归,通用存储用户评测排名全球榜首
  13. 工业级交换机级联介绍
  14. k8s Container资源控制: requests和limits
  15. 获取 AWS 免费套餐
  16. android 壁纸再拿,Android获取当前桌面壁纸
  17. 微信白名单配置与检验
  18. 2021年G2电站锅炉司炉考试题库及G2电站锅炉司炉模拟考试
  19. ubu下编译安装php7
  20. C语言开发环境,请查收

热门文章

  1. c语言p832.c的答案,2017年北方民族大学计算机系统结构832C语言程序设计与数据结构之C程序设计考研仿真模拟题...
  2. 啥是编码Unicode_马鸿凯_新浪博客
  3. 圆心科技冲刺港交所上市:收入主要靠卖药,毛利率仅在10%上下
  4. (官方步骤)YOLO-V3训练VOC数据集
  5. gamma对冲 matlab,gamma与对冲损益之一
  6. 如何把word中的图片怎么导出来呢?
  7. 这个bug很简单-log4j:ERROR Attempted to append to closed appender named
  8. 交流电源的原理和应用范围
  9. 【面经】远景能源一面(Java开发)
  10. 【CV-project】看图说话(Image Captioning)