求有向图中两点最短距离java_Java 迪杰斯特拉算法实现查找最短距离
迪杰斯特拉算法
迪杰斯特拉算法是由荷兰计算机科学家狄克斯特拉于1959 年提出的,因此又叫狄克斯特拉算法。是从一个顶点到其余各顶点的最短路径算法,解决的是有向图中最短路径问题。迪杰斯特拉算法主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止。具体的计算规则我们可以通过下图进行查看。
通过这幅图我们可以简单的理解迪杰斯特拉算法算法的基础思路,下面我们就通过JAVA来实现这个算法。
算法实现
在迪杰斯特拉算法中我们需要保存从起点开始到每一个节点最短步长,这也是图中需要比较得出的步长,同时我们还需要存储该步长下的前一个节点是哪个,这样我们就可以通过终点一个一个往前推到起点,这样就出来了完整的最优路径。
每一个节点的最优前一节点
public class PreNode {
private String preNodeName;//最优的前一个节点
private int nodeStep;// 起点到前一个节点的步长+前一个节点本身的步长
public PreNode(String preNodeName, int nodeStep) {
this.preNodeName = preNodeName;
this.nodeStep = nodeStep;
}
public String getPreNodeName() {
return preNodeName;
}
public void setPreNodeName(String preNodeName) {
this.preNodeName = preNodeName;
}
public int getNodeStep() {
return nodeStep;
}
public void setNodeStep(int nodeStep) {
this.nodeStep = nodeStep;
}
}
定义返回的数据结构
package dijkstra;
import java.util.List;
public class MinStep {
private boolean reachable;// 是否可达
private int minStep;// 最短步长
private List step;// 最短路径
public MinStep() {
}
public MinStep(boolean reachable, int minStep) {
this.reachable = reachable;
this.minStep = minStep;
}
public boolean isReachable() {
return reachable;
}
public void setReachable(boolean reachable) {
this.reachable = reachable;
}
public int getMinStep() {
return minStep;
}
public void setMinStep(int minStep) {
this.minStep = minStep;
}
public List getStep() {
return step;
}
public void setStep(List step) {
this.step = step;
}
}
定义接口
package dijkstra;
import java.util.HashMap;
public interface Distance {
public static final MinStep UNREACHABLE = new MinStep(false, -1);
/**
* @param start
* @param end
* @param stepLength
* @return
* @Description: 起点到终点的最短路径
*/
public MinStep getMinStep(String start, String end, final HashMap> stepLength);
}
功能实现
package dijkstra;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Map.Entry;
public class DistanceDijkstraImpl implements Distance {
// 图中相邻两个节点的距离
private HashMap> stepLength;
// 非独立节点个数
private int nodeNum;
// 移除节点
private HashSet outNode;
// 起点到各点的步长,key为目的节点,value为到目的节点的步长
private HashMap nodeStep;
// 下一次计算的节点
private LinkedList nextNode;
// 起点、终点
private String startNode;
private String endNode;
/**
* @param start
* @param end
* @param stepLength
* @return
* @Description: start 到 end 的最短距离
*/
public MinStep getMinStep(String start, String end, final HashMap> stepLength) {
this.stepLength = stepLength;
this.nodeNum = this.stepLength != null ? this.stepLength.size() : 0;
// 起点、终点不在目标节点内,返回不可达
if (this.stepLength == null || (!this.stepLength.containsKey(start)) || (!this.stepLength.containsKey(end))) {
return UNREACHABLE;
}
initProperty(start, end);
step();
if (nodeStep.containsKey(end)) {
return changeToMinStep();
}
return UNREACHABLE;
}
/**
* 返回最短距离以及路径
*/
private MinStep changeToMinStep() {
MinStep minStep = new MinStep();
minStep.setMinStep(nodeStep.get(endNode).getNodeStep());
minStep.setReachable(true);
LinkedList step = new LinkedList();
minStep.setStep(step);
// 先将终点添加到路径第一位中
String tempNode = endNode;
step.addFirst(tempNode);
// 再将所经过的节点添加到路径第一位中
while (nodeStep.containsKey(tempNode)) {
PreNode preNode = nodeStep.get(tempNode);
String preNodeName = preNode.getPreNodeName();
// System.out.println(preNodeName + " " + preNode.getNodeStep());
step.addFirst(preNodeName);
tempNode = preNodeName;
}
return minStep;
}
/**
* @param start
* @Description: 初始化属性
*/
private void initProperty(String start, String end) {
outNode = new HashSet();
nodeStep = new HashMap();
nextNode = new LinkedList();
nextNode.add(start);
startNode = start;
endNode = end;
}
/**
* @param end
* @Description:
*/
private void step() {
if (nextNode == null || nextNode.size() < 1) {
return;
}
if (outNode.size() == nodeNum) {
return;
}
// 获取下一个计算节点
String start = nextNode.removeFirst();
// 到达该节点的最小距离
int step = 0;
if (nodeStep.containsKey(start)) {
step = nodeStep.get(start).getNodeStep();
}
// 获取该节点可达节点
HashMap nextStep = stepLength.get(start);
Iterator> iter = nextStep.entrySet().iterator();
while (iter.hasNext()) {
Entry entry = iter.next();
String key = entry.getKey();
// 如果是起点到起点,不计算之间的步长
if (key.equals(startNode)) {
continue;
}
// 起点到可达节点的距离
Integer value = entry.getValue() + step;
if ((!nextNode.contains(key)) && (!outNode.contains(key))) {
nextNode.add(key);
}
if (nodeStep.containsKey(key)) {
// 比较步长
if (value < nodeStep.get(key).getNodeStep()) {
nodeStep.put(key, new PreNode(start, value));
}
} else {
nodeStep.put(key, new PreNode(start, value));
}
}
// 将该节点移除
outNode.add(start);
// 计算下一个节点
step();
}
}
step()逻辑解析
这一步也就是迪杰斯特拉算法的核心部分,在计算的过程中,我们需要进行如下步骤:
1)判断是否达到终止条件,如果达到终止条件,结束本次算法,如果没有达到,执行下一步;(终止条件:下一次需要计算的节点队列没有数据或已经计算过的节点数等于节点总数)
2)获取下一次计算的节点A;
3)从起点到各节点之间的最短距离map中获取到达A点的最小距离L;
4)获取A节点的可达节点B,计算从起点先到A再到B是否优于已有的其他方式到B,如果优于,则更新B节点,否则不更新;
5)判断B是否是已经移除的节点,如果不是移除的节点,把B添加到下一次需要计算的节点队列中,否则不做操作;
6)判断A节点是否还有除B以外的其他节点,如果有,执行第4)步,否则执行下一步;
7)将A节点从下一次需要计算的节点中移除添加到已经计算过的节点中;
8)执行第一步。
Demo运行
import java.util.HashMap;
import com.alibaba.fastjson.JSONObject;
public class DistanceTest {
public static void main(String[] args) {
// TODO Auto-generated method stub
HashMap> stepLength = new HashMap>();
HashMap step1 = new HashMap();
stepLength.put("1", step1);
step1.put("2", 2);
HashMap step2 = new HashMap();
stepLength.put("2", step2);
step2.put("1", 2);
step2.put("3", 1);
HashMap step3 = new HashMap();
stepLength.put("3", step3);
step3.put("2", 1);
step3.put("4", 1);
step3.put("9", 1);
HashMap step4 = new HashMap();
stepLength.put("4", step4);
step4.put("5", 1);
step4.put("3", 1);
HashMap step5 = new HashMap();
stepLength.put("5", step5);
step5.put("4", 1);
HashMap step6 = new HashMap();
stepLength.put("6", step6);
step6.put("9", 1);
HashMap step7 = new HashMap();
stepLength.put("7", step7);
step7.put("10", 1);
HashMap step8 = new HashMap();
stepLength.put("8", step8);
step8.put("11", 3);
HashMap step9 = new HashMap();
stepLength.put("9", step9);
step9.put("3", 1);
step9.put("6", 1);
step9.put("10", 1);
HashMap step10 = new HashMap();
stepLength.put("10", step10);
step10.put("9", 1);
step10.put("7", 1);
step10.put("11", 1);
HashMap step11 = new HashMap();
stepLength.put("11", step11);
step11.put("8", 3);
step11.put("10", 1);
System.out.println(JSONObject.toJSON(stepLength));
Distance distance = new DistanceDijkstraImpl();
MinStep step = distance.getMinStep("1", "5", stepLength);
System.out.println(JSONObject.toJSON(step));
step = distance.getMinStep("1", "8", stepLength);
System.out.println(JSONObject.toJSON(step));
step = distance.getMinStep("8", "1", stepLength);
System.out.println(JSONObject.toJSON(step));
step = distance.getMinStep("11", "7", stepLength);
System.out.println(JSONObject.toJSON(step));
step = distance.getMinStep("10", "8", stepLength);
System.out.println(JSONObject.toJSON(step));
}
}
{“11”:{“8”:1,“10”:1},“1”:{“2”:2},“2”:{“1”:2,“3”:1},“3”:{“4”:1,“9”:1,“2”:1},“4”:{“5”:1,“3”:1},“5”:{“4”:1},“6”:{“9”:1},“7”:{“10”:1},“8”:{“11”:1},“9”:{“6”:1,“3”:1,“10”:1},“10”:{“11”:1,“9”:1,“7”:1}}
{“minStep”:5,“step”:[“1”,“2”,“3”,“4”,“5”],“reachable”:true}
{“minStep”:7,“step”:[“1”,“2”,“3”,“9”,“10”,“11”,“8”],“reachable”:true}
{“minStep”:7,“step”:[“8”,“11”,“10”,“9”,“3”,“2”,“1”],“reachable”:true}
{“minStep”:2,“step”:[“11”,“10”,“7”],“reachable”:true}
{“minStep”:2,“step”:[“10”,“11”,“8”],“reachable”:true}
求有向图中两点最短距离java_Java 迪杰斯特拉算法实现查找最短距离相关推荐
- C++迪杰斯特拉算法求最短路径
一:算法历史 迪杰斯特拉算法是由荷兰计算机科学家狄克斯特拉于1959 年提出的,因此又叫狄克斯特拉算法.是从一个顶点到其余各顶点的最短路径算法,解决的是有向图中最短路径问题.迪杰斯特拉算法主要特点是以 ...
- 迪杰斯特拉算法 两点间最短路径的选择
百度首页 登录 注册 新闻网页贴吧知道音乐图片视频地图百科文库 首页 分类 艺术 科学 自然 文化 地理 生活 社会 人物 经济 体育 历史 特色百科 历史上的今天 数字博物馆 史记·2015 城市百 ...
- 最短路径问题(图表详解迪杰斯特拉算法)
首先,我们来看一下相关的图的一些基本知识点: 图:图 G=(V,E) 由顶点集 V 和边集 E 组成.每条边对应一个点对 (v,w),其中 v,w 属于 V .如果图中的点对是有序的,那么该图就是有向 ...
- 校园导游系统_C语言实现_Dijkstra(迪杰斯特拉算法)_数据结构
西京学院导游系统 摘要 要完成对整个导游图系统的功能实现,需要对每一项功能都有清楚的设想和认识,了解并明确每一项功能的实现和需要解决的问题,选择正确并且高效的算法把问题逐个解决,最终实现程序的正确 ...
- 迪杰斯特拉算法详解+模版+例题
迪杰斯特拉算法(Dijkstra)是由荷兰计算机科学家狄克斯特拉于1959 年提出的,因此又叫狄克斯特拉算法.是从一个顶点到其余各顶点的最短路径算法,解决的是有权图中最短路径问题.迪杰斯特拉算法主要特 ...
- java迪杰斯特拉算法实例,Java 图的最短路径dijstra(迪杰斯特拉)算法和拓扑排序
一.图的最短路径从某顶点出发,沿图的边到达另一顶点所经过的路径中,各边上权值之和最小的一条路径叫做最短路径 图的最短路径有许多重要的应用. 例如:上图中v0-v8有9个点,可以看做不同的地点,现在要规 ...
- 迪杰斯特拉算法的证明
求V0到V8的最短距离: 迪杰斯特拉算法的思想是依次求出距离V0第1近,第2近--.一直到第8近,也就是从距离V0最近到最远的点.而每求一个最近距离就修正V0到剩下点的最短距离. 设A为包含V0和已经 ...
- 《计算机网络自顶向下》之重头戏迪杰斯特拉算法
迪杰斯特拉算法(Dijkstra)是由荷兰计算机科学家狄克斯特拉于1959 年提出的,因此又叫狄克斯特拉算法.是从一个顶点到其余各顶点的最短路径算法,解决的是有权图中最短路径问题.迪杰斯特拉算法主要特 ...
- Dijkstra迪杰斯特拉算法 C++实现
本篇文章主要介绍了Dijkstra迪杰斯特拉算法的C++实现,文章包含两个部分,在第一部分中我会简单介绍迪杰斯特拉算法以及一些个人的理解,第二部分会对C++代码的逻辑进行解释.下面是我已经上传的代码资 ...
最新文章
- GitHub上7000+ Star的Python常用代码合集
- 堆(heap)与栈(stack)的区别(二)
- 《货币是个什么东西》笔记
- [Matlab]函数表达式运算
- Socket粘包问题终极解决方案—Netty版(2W字)!
- 含枚举类型的函数声明_02Golang基础类型
- 学计算机的,怎么知道自己喜欢软件还是硬件
- 【报告分享】2020“后浪”消费图鉴.pdf(附下载链接)
- Confluence 6 匿名访问远程 API
- 未来无人车市场中,谁最赚钱?
- freemaker if 多个条件_小函数,大用处!巧用AND函数,避开IF函数嵌套
- A/N GPU架构解析
- 年轻时欠下风流情债的十大男女明星(组图)
- canvas实现图片缩放+涂鸦
- 信噪比(SNR)计算公式的推导
- mysql数据库备份工具
- 刘慈欣新作《黄金原野》与 区块链
- VIEW PUSHED PREDICATE(谓词推入)引发的惨剧
- UGUI中随意调整Text中的字体间距
- 英语听力软件测试培训,自学英语听力
热门文章
- linux使用iscsi磁盘的几个步骤
- 关于uboot中tftp上传内存数据到tftp服务器
- C++知识点总结(三)
- 芈珺:iOS自动化测试工具总览
- 高斯求和1+2+3+······+n-1+n=?
- JQuery技巧总结【转】
- android activty动画,Activity动画效果
- bypass最新版d盾mysql_Bypass 护卫神SQL注入防御(多姿势)
- java 完全背包问题算法_算法笔记(c++)--完全背包问题
- java mvc controller_java之spring mvc之Controller配置的几种方式