介绍

Dijistra算法作为一种最短路径算法,可以用来计算一个节点到图上其他节点的最短距离。

主要是通过启发式的思想,由中心节点层层向外拓展,直到找到中点。

适用于无向图和有向图。

算法思想

  1. 假设我们要计算节点A到其它节点的最短距离
  2. 引入两个集合(SU),其中集合S表示已经求出最短路径的点(以及最短距离),集合U表示还未求出最短路径的点。集合中的元素用类似A(0)形式表示,其中A目标点为A(0)表示目前已知最短路径为0(未直接连通的距离用表示)。
  3. 初始时,S集合中只有起始点,距离为0,U集合中除了直接与A点连通的点外,距离都为
  4. 第一次向外拓展,找出U集合中距离最短的点(假设为B)加入集合S。并以B点向外拓展,更新U集合中的距离值。更新规则为,如果经过B到某点的距离小于U集合中记录的结果,那么则更新中集合U中该点的距离值。
  5. 每执行一次步骤四,我们可以得出A点距某个点的最短距离。
  6. 重复步骤四,直到U的集合为空或是目标点不在U集合中,也就计算出了需要的最短距离。

用图表示解题过程:

证明

同样以上图为例,我们如何保证第一次选择得到结果A-> B (6)是正确的最优解。

证明:

  • 上述图为无向图,且不存在负权边。
  • 由A出发去其他点,穷举第一条边所有选择,只能为A -> B(6)A -> C(12)A -> D(8)三种。一旦第一条边选择了后两种情况,经过C或是D点再绕回B,由于不存在负权边,那么经过C的路线一定大于A->C(12),经过D的路线A->D(8),因此都会大于A ->B(6)
  • 那么为什么第二次选择只能确定D而非刚更新了最小值的E点。首先基于上一步我们确定了由A出发去D点最短路径第一条边只可能是A->BA->D两种情况,而经过B点再选择第二条边也在上轮计算过了,其与第一条边之和均大于A->D(8),所以能够确定到D的最短路径。而由于D->E的最短路径在第二轮尚不知道,因此无法确定到E的最短路径。
  • 同理,可以确定每一轮的解都是最短路径。

算法实现

public class Dijkstra {

    public static int[] getShortestPath(int[][] graph, int source){
if(graph == null || graph.length <= source)
throw new IllegalArgumentException(); if(graph.length != graph[0].length)
throw new IllegalArgumentException(); int n = graph[source].length;
// String[] route = new String[n]; //保存结果集
int[] ret = new int[graph[source].length];
//保存已确定最短路径的点
int[] visited = new int[graph[source].length]; //初始化数据
Arrays.fill(visited, 0);
Arrays.fill(ret, Integer.MAX_VALUE);
ret[source] = 0; //进行n次筛选
for(int i=0; i<n; i++){
//找出结果集中未visited结果中数据最小的点,为该轮确定的最短路径
int minValueIndex = findMinValue(ret, visited);
visited[minValueIndex] = 1; //更新通过该点是否有新的最短路径生成
int[] line = graph[minValueIndex];
for(int j=0; j<line.length; j++){
if(visited[j] == 0 &&
line[j] != Integer.MAX_VALUE &&
line[j] + ret[minValueIndex] <= ret[j]){
ret[j] = line[j] + ret[minValueIndex];
} } } return ret;
} private static int findMinValue(int[] source, int[] visited){
int ret = 0;
int minVal = Integer.MAX_VALUE;
for(int i=0; i<source.length; i++){
if(visited[i] == 0 && source[i] < minVal){
ret = i;
minVal = source[i];
} }
return ret;
} }

上述代码见Github

日日算法:Dijkstra算法的更多相关文章

  1. 最短路径算法-Dijkstra算法的应用之单词转换(词梯问题)(转)

    一,问题描述 在英文单词表中,有一些单词非常相似,它们可以通过只变换一个字符而得到另一个单词.比如:hive-->five:wine-->line:line-->nine:nine- ...

  2. HDU1535——Invitation Cards(最短路径:SPAF算法+dijkstra算法)

    Invitation Cards DescriptionIn the age of television, not many people attend theater performances. A ...

  3. 《算法导论》读书笔记之图论算法—Dijkstra 算法求最短路径

    自从打ACM以来也算是用Dijkstra算法来求最短路径了好久,现在就写一篇博客来介绍一下这个算法吧 :) Dijkstra(迪杰斯特拉)算法是典型的最短路径路由算法,用于计算一个节点到其他所有节点的 ...

  4. 最短路径算法——Dijkstra算法

    在路由选择算法中都要用到求最短路径算法.最出名的求最短路径算法有两个,即Bellman-Ford算法和Dijkstra算法.这两种算法的思路不同,但得出的结果是相同的. 下面只介绍Dijkstra算法 ...

  5. 单源最短路径算法——Dijkstra算法(迪杰斯特拉算法)

    一 综述 Dijkstra算法(迪杰斯特拉算法)主要是用于求解有向图中单源最短路径问题.其本质是基于贪心策略的(具体见下文).其基本原理如下: (1)初始化:集合vertex_set初始为{sourc ...

  6. 最短路径算法——Dijkstra算法与Floyd算法

    转自:https://www.cnblogs.com/smile233/p/8303673.html 最短路径 ①在非网图中,最短路径是指两顶点之间经历的边数最少的路径. AE:1    ADE:2  ...

  7. 最小生成树(prime算法 & kruskal算法)和 最短路径算法(floyd算法 & dijkstra算法)

    一.主要内容: 介绍图论中两大经典问题:最小生成树问题以及最短路径问题,以及给出解决每个问题的两种不同算法. 其中最小生成树问题可参考以下题目: 题目1012:畅通工程 http://ac.jobdu ...

  8. 最短路-Prim算法 dijkstra算法

    HDU-1233 #include <iostream> #define INF 1000000 using namespace std; ][]; ]; ]; ]; ]; int mai ...

  9. (转)最短路算法--Dijkstra算法

    转自:http://blog.51cto.com/ahalei/1387799         上周我们介绍了神奇的只有五行的Floyd最短路算法,它可以方便的求得任意两点的最短路径,这称为“多源最短 ...

  10. 有向有权图的最短路径算法--Dijkstra算法

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

随机推荐

  1. Golang入门(4):并发

    摘要 并发程序指同时进行多个任务的程序,随着硬件的发展,并发程序变得越来越重要.Web服务器会一次处理成千上万的请求,这也是并发的必要性之一.Golang的并发控制比起Java来说,简单了不少.在Go ...

  2. Java8 新特性 Lambda & Stream API

    目录 Lambda & Stream API 1 Lambda表达式 1.1 为什么要使用lambda表达式 1.2 Lambda表达式语法 1.3 函数式接口 1.3.1 什么是函数式接口? ...

  3. Google GMS介绍

    Google GMS介绍GMS全称为GoogleMobile Service.GMS目前提供有Search.Search by Voice.Gmail.Contact Sync.Calendar Sy ...

  4. 33.1 File 获取目录下的所有文件及子目录

    重要获取功能 String[] list() 返回当前路径下所有的文件和文件夹名称 //注意:只有指向文件夹的File对象才可以调用该方法(指向文件的file对象使用list会报错npe) File[ ...

  5. 28.3 api--date 日期 (日期获取、格式化)

    /* * Date: 表示特定的瞬间,精确到毫秒,他可以通过方法来设定自己所表示的时间,可以表示任意的时间 * System.currentTimeMillis():返回的是当前系统时间,1970-1 ...

  6. Spire.Cloud 私有化部署教程(一) - CentOS 7 系统

    Spire.Cloud支持的Linux服务器系统包括CentOS和Ubuntu(推荐使用CentOS 7和Ubuntu 18版本),本教程主要介绍如何在CentOS 7系统上实现Spire.Cloud ...

  7. django 利用ORM对单表进行增删改查

    牛小妹上周末,一直在尝试如何把数据库的数据弄到界面上.毕竟是新手,搞不出来,文档也看不懂.不过没关系,才刚上大学.今晚我们就来解释下,要把数据搞到界面的第一步.先把数据放到库里,然后再把数据从库里拿出 ...

  8. tf.nn.softmax 分类

    tf.nn.softmax(logits,axis=None,name=None,dim=None) 参数: logits:一个非空的Tensor.必须是下列类型之一:half, float32,fl ...

  9. 从CentOS 7.0升级到7.7版本

    我平时都在VirtualBox上装虚拟机,方法是导入ova镜像文件,比如导入从网上下载的CentOS7-base.ova,该ova为CentOS 7.0版本,而现在最新版本为7.7,为此进入系统后第一 ...

  10. c++ 启发式搜索解决八数码问题

    本文对八数码问题 启发式搜索 (C++)做了一点点修改 //fn=gn+hn #include<iostream> #include<queue> #include<st ...