介绍

对于dijkstra算法,很多人可能感觉熟悉而又陌生,可能大部分人比较了解bfs和dfs,而对dijkstra和floyd算法可能知道大概是图论中的某个算法,但是可能不清楚其中的作用和原理,又或许,你曾经感觉它很难,那么,这个时候正适合你重新认识它。

Dijkstra能是干啥的?

Dijkstra是用来求单源最短路径的

就拿上图来说,假如直到的路径和长度已知,那么可以使用dijkstra算法计算南京到图中所有节点的最短距离。

单源什么意思?

  • 从一个顶点出发,Dijkstra算法只能求一个顶点到其他点的最短距离而不能任意两点。

bfs求的最短路径有什么区别?

  • bfs求的与其说是路径,不如说是次数。因为bfs他是按照队列一次一次进行加入相邻的点,而两点之间没有权值或者权值相等(代价相同)。处理的更多是偏向迷宫类的这种都是只能走邻居(不排除特例)。

Dijkstra在处理具体实例的应用还是很多的,因为具体的问题其实带权更多一些。

比如一个城市有多个乡镇,乡镇可能有道路,也可能没有,整个乡镇联通,如果想计算每个乡镇到a镇的最短路径,那么Dijkstra就派上了用场。

算法分析

对于一个算法,首先要理解它的运行流程

对于一个Dijkstra算法而言,前提是它的前提条件和环境:

  • 一个连通图,若干节点,节点可能有数值,但是路径一定有权值。并且路径不能为负。否则Dijkstra就不适用。

Dijkstra的核心思想是贪心算法的思想。不懂贪心?

贪心算法(又称贪婪算法)是指,在对问题求解时,总是做出在当前看来是最好的选择。也就是说,不从整体最优上加以考虑,他所做出的是在某种意义上的局部最优解。

贪心算法不是对所有问题都能得到整体最优解,关键是贪心策略的选择,选择的贪心策略必须具备无后效性,即某个状态以前的过程不会影响以后的状态,只与当前状态有关。

对于贪心算法,在很多情况都能用到。下面举几个不恰当的例子!

打个比方,吃自助餐,目标是吃回本,那么胃有限那么每次都仅最贵的吃。

上学时,麻麻说只能带5个苹果,你想带最多,那么选五个苹果你每次都选最大的那个五次下来你就选的最重的那个。

不难发现上面的策略虽然没有很强的理论数学依据,或者不太好说明。但是事实规律就是那样,并且对于贪心问题大部分都需要排序,还可能会遇到类排序。并且一个物体可能有多个属性,不同问题需要按照不同属性进行排序,操作。

那么我们的Dijkstra是如何贪心的呢?对于一个点,求图中所有点的最短路径,如果没有正确的方法胡乱想确实很难算出来,并且如果暴力匹配复杂度呈指数级上升不适合解决实际问题。

那么我们该怎么想呢?

Dijkstra算法的前提

  1. 首先,Dijkstra处理的是带正权值的有权图,那么,就需要一个二维数组(如果空间大用list数组)存储各个点到达()的权值大小。(邻接矩阵或者邻接表存储)
  2. 其次,还需要一个boolean数组判断那些点已经确定最短长度,那些点没有确定。int数组记录距离(在算法执行过程可能被多次更新)。
  3. 需要优先队列加入已经确定点的周围点。每次抛出确定最短路径的那个并且确定最短,直到所有点路径确定最短为止。

简单的概括流程为

  • 一般从选定点开始抛入优先队列。(路径一般为0),boolean数组标记0的位置(最短为0) , 然后0周围连通的点抛入优先队列中(可能是node类),并把各个点的距离记录到对应数组内(如果小于就更新,大于就不动,初始第一次是无穷肯定会更新),第一次就结束了
  • 从队列中抛出距离最近的那个点B第一次就是0周围邻居)。这个点距离一定是最近的(所有权值都是正的,点的距离只能越来越长。)标记这个点为true并且将这个点的邻居加入队列(下一次确定的最短点在前面未确定和这个点邻居中产生),并更新通过B点计算各个位置的长度,如果小于则更新!

  • 重复二的操作,直到所有点都确定。

算法实现

package 图论;

import java.util.ArrayDeque;
import java.util.Comparator;
import java.util.PriorityQueue;
import java.util.Queue;
import java.util.Scanner; public class dijkstra {
static class node
{
int x; //节点编号
int lenth;//长度
public node(int x,int lenth) {
this.x=x;
this.lenth=lenth;
}
} public static void main(String[] args) { int[][] map = new int[6][6];//记录权值,顺便记录链接情况,可以考虑附加邻接表
initmap(map);//初始化
boolean bool[]=new boolean[6];//判断是否已经确定
int len[]=new int[6];//长度
for(int i=0;i<6;i++)
{
len[i]=Integer.MAX_VALUE;
}
Queue<node>q1=new PriorityQueue<node>(com);
len[0]=0;//从0这个点开始
q1.add(new node(0, 0));
int count=0;//计算执行了几次dijkstra
while (!q1.isEmpty()) {
node t1=q1.poll();
int index=t1.x;//节点编号
int length=t1.lenth;//节点当前点距离
bool[index]=true;//抛出的点确定
count++;//其实执行了6次就可以确定就不需要继续执行了 这句可有可无,有了减少计算次数
for(int i=0;i<map[index].length;i++)
{
if(map[index][i]>0&&!bool[i])
{
node node=new node(i, length+map[index][i]);
if(len[i]>node.lenth)//需要更新节点的时候更新节点并加入队列
{
len[i]=node.lenth;
q1.add(node);
}
}
}
}
for(int i=0;i<6;i++)
{
System.out.println(len[i]);
}
}
static Comparator<node>com=new Comparator<node>() { public int compare(node o1, node o2) {
return o1.lenth-o2.lenth;
}
}; private static void initmap(int[][] map) {
map[0][1]=2;map[0][2]=3;map[0][3]=6;
map[1][0]=2;map[1][4]=4;map[1][5]=6;
map[2][0]=3;map[2][3]=2;
map[3][0]=6;map[3][2]=2;map[3][4]=1;map[3][5]=3;
map[4][1]=4;map[4][3]=1;
map[5][1]=6;map[5][3]=3;
}
}

执行结果:



当然,dijkstra算法比较灵活,实现方式也可能有点区别,但是思想是不变的:一个贪心思路。dijkstra执行一次就能够确定一个点,所以只需要执行点的总和次数即可完成整个算法。

欢迎感谢小伙伴点赞、关注,赠人玫瑰,手有余香!蟹蟹!

Dijkstra算法详细(单源最短路径算法)的更多相关文章

  1. Til the Cows Come Home(poj 2387 Dijkstra算法(单源最短路径))

    Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 32824   Accepted: 11098 Description Bes ...

  2. 单源最短路径算法:迪杰斯特拉 (Dijkstra) 算法(二)

    一.基于邻接表的Dijkstra算法 如前一篇文章所述,在 Dijkstra 的算法中,维护了两组,一组包含已经包含在最短路径树中的顶点列表,另一组包含尚未包含的顶点.使用邻接表表示,可以使用 BFS ...

  3. 单源最短路径算法:迪杰斯特拉 (Dijkstra) 算法(一)

    一.算法介绍 迪杰斯特拉算法(英语:Dijkstra's algorithm)由荷兰计算机科学家艾兹赫尔·迪杰斯特拉在1956年提出.迪杰斯特拉算法使用了广度优先搜索解决赋权有向图的单源最短路径问题. ...

  4. Dijkstra 单源最短路径算法

    Dijkstra 算法是一种用于计算带权有向图中单源最短路径(SSSP:Single-Source Shortest Path)的算法,由计算机科学家 Edsger Dijkstra 于 1956 年 ...

  5. Bellman-Ford 单源最短路径算法

    Bellman-Ford 算法是一种用于计算带权有向图中单源最短路径(SSSP:Single-Source Shortest Path)的算法.该算法由 Richard Bellman 和 Leste ...

  6. 经典贪心算法(哈夫曼算法,Dijstra单源最短路径算法,最小费用最大流)

    哈夫曼编码与哈夫曼算法 哈弗曼编码的目的是,如何用更短的bit来编码数据. 通过变长编码压缩编码长度.我们知道普通的编码都是定长的,比如常用的ASCII编码,每个字符都是8个bit.但在很多情况下,数 ...

  7. 【算法】单源最短路径和任意两点最短路径总结(补增:SPFA)

    [Bellman-Ford算法] [算法]Bellman-Ford算法(单源最短路径问题)(判断负圈) 结构: #define MAX_V 10000 #define MAX_E 50000 int ...

  8. 51nod 1445 变色DNA ( Bellman-Ford算法求单源最短路径)

    1445 变色DNA 基准时间限制:1 秒 空间限制:131072 KB 分值: 40 难度:4级算法题 有一只特别的狼,它在每个夜晚会进行变色,研究发现它可以变成N种颜色之一,将这些颜色标号为0,1 ...

  9. 单源最短路径算法---Dijkstra

    Dijkstra算法树解决有向图G=(V,E)上带权的单源最短路径问题,但是要求所有边的权值非负. 解题思路: V表示有向图的所有顶点集合,S表示那么一些顶点结合,从源点s到该集合中的顶点的最终最短路 ...

随机推荐

  1. [Spring cloud 一步步实现广告系统] 18. 查询返回广告创意

    根据三个维度继续过滤 在上一节中我们实现了根据流量信息过滤的代码,但是我们的条件有可能是多条件一起传给我们的检索服务的,本节我们继续实现根据推广单元的三个维度条件的过滤. 在SearchImpl类中添 ...

  2. 60701BMP彩色图像转化为灰度及二值图像

    1 概述 多媒体技术是一门综合了多种学科的新技术,其涉及到计算机科学与技术.通信和网络技术.人工智能技术.微电子技术.数字信号处理.图形处 理技术.声像技术等诸多学科.许多新技术的不断出现和体验,带给 ...

  3. SAP Special Fields in FAGLL03 transaction

    https://wiki.scn.sap.com/wiki/display/ERPFI/Special+Fields+in+FAGLL03+transaction https://wiki.scn.s ...

  4. 搞懂Go垃圾回收

    本文主要介绍了垃圾回收的概念,Golang GC的垃圾回收算法和工作原理,看完本文可以让你对Golang垃圾回收机制有个全面的理解.由于本人不了解其他语言的GC,并未对比其他语言的垃圾回收算法,需要的 ...

  5. Day 01--选题与设计(一)

    1.第一天我们主要确定了软件课设的项目,做一个学校内食堂订送餐的微信小程序.我们大体的设计思路是:可以实现学生身份的认证,幷使学生们能自行选择校园内的食堂,挑选各个食堂各个窗口菜谱上可以选择的菜,选择 ...

  6. python3:面向对象(多态和继承、方法重载及模块)

    1.多态 同一个方法在不同的类中最终呈现出不同的效果,即为多态. class Triangle: def __init__(self,width,height): self.width = width ...

  7. 解决mysql乱码

    总结的几个乱码问题 希望我们全体学员也能够学会总结 java web 很是希望大家能够学好.并且也希望大家能够在学习过程中不段的积累相关的知识点 1.在response中写<meta  http ...

  8. PL/SQL 监听程序当前无法识别连接描述符中请求的服务解决

    PL/SQL 用了几天后再登陆提示监听程序当前无法识别连接描述符中请求的服务,绞尽脑汁各种搜索找到以下解决方案-修改listener.ora文件 一般文件存在:app\Administrator\pr ...

  9. MySQL之Xtrabackup的使用

    一.Xtrabackup介绍 XtraBackup(PXB) 工具是 Percona 公司用 perl 语言开发的一个用于 MySQL 数据库物理热备的备份工具,支持 MySQl(Oracle).Pe ...

  10. 单选多选(CocosCreator)

    推荐阅读:  我的CSDN  我的博客园  QQ群:704621321 1.前沿       首先来说说我们的需求吧:随机出现单选题或者多选题,完全回答正确才算正确(多选题中少选错选算错),核实答案的 ...