引子:

Dijkstra算法:某个顶点到其他顶点的最短路径。

以下面这个图为例:其中源点是A。关键点:维护一个二维数组,具体见下面:

1、首先,派一名调查员驻扎在A处,在A处,a调查员能够知道与A相连的B和D的路径长度,在笔记本上记着下面图片1的信息。接下来选择没有驻扎调查员、和A直接相连以及到A路径最短的点。只有B(50)和D(80)直接和A相连,所以选择B。

注意:如果在笔记本上标注了#号的地方,表示已经在此地驻扎了调查员,同时意味着这个就是此地到源点A的最短路径,不会再在笔记本上修改此项。

2、根据上一位调查员的结果,另外派一名调查员驻扎在B处,这样b调查员就知道了与B相连的地点的路径。也就是C和D,致电告诉a调查员,则a调查员在笔记本上记上下面图片2的信息。现在只有A和B才驻扎了调查员,则下面我们应该选择一个与A或B直接相连的、并且到源点A的路径最短的以及没有驻扎调查员的地点。因为A-B-C是110,A到D是80,A-B-D是140,所以另外派一名调查员直接从A到D。

3、d调查员到D地点之后,开始调查,发现了D到E、D到C的路径,致电给a调查员,a调查员做下面如图所示的笔记。

4、这时,只有A、B、D三个地方驻扎了调查员,而与A、B、D直接相连的并且没有驻扎调查员的地点有C、E,所以,接下来就在C、E里面选择他们俩谁离源点A最近,通过比较知道,AC(100)的路径比AE(150)近,所以,接下来另外派一名调查员驻扎到C处、、、、、、

package graph;public class DijkstraGraphTest3 {public static void main(String[] args) {MyDijkstraGraph g = new MyDijkstraGraph(40);//增加顶点g.addVertex("A");g.addVertex("B");g.addVertex("C");g.addVertex("D");g.addVertex("E");g.addVertex("F");g.addVertex("G");//增加边和边的权重g.addEdge(0, 1, 50);g.addEdge(0, 3, 80);g.addEdge(1, 2, 60);g.addEdge(1, 3, 90);g.addEdge(2, 4, 40);g.addEdge(3, 2, 20);g.addEdge(3, 4, 70);g.addEdge(4, 1, 50);g.addEdge(2, 5, 60);g.addEdge(4, 5, 10);g.addEdge(5, 6, 40);//执行dijkstra算法g.doDijkstra();}
}class MyDijkstraGraph{//最大的权值private static final int INFINITE = 10000;//顶点队列private Vertex[] vertexList;//邻接矩阵private int[][] matrix;//顶点的个数private int size;//辅助数组,记录某点的父顶点以及这个点到源点的距离private DistanceParent[] distanceParents;public MyDijkstraGraph(int maxSize){this.vertexList = new Vertex[maxSize];this.matrix = new int[maxSize][maxSize];this.size = 0;this.distanceParents = new DistanceParent[maxSize];}//增加顶点public void addVertex(String label){vertexList[size++] = new Vertex(label);}//增加边和权重public void addEdge(int start, int end, int weigth){this.matrix[start][end] = weigth;}//执行算法public void doDijkstra(){//当前顶点int currentVertex = 0;//加入树中的顶点数int treeNum = 1;//初始化:把所有的边的权重都为最大for(int i = 0; i < size; i++){for(int k = 0; k < size; k++){int weigth = matrix[i][k];if(weigth == 0){matrix[i][k] = INFINITE;}}}//初始化:第一个顶点到其余顶点的权重,父顶点下标都为0for(int i = 0; i < size; i++){int weigth = matrix[currentVertex][i];distanceParents[i] = new DistanceParent(weigth, 0);}//每一次循环,都可以确认某一个顶点到源点的最小距离while(treeNum < size){currentVertex = getMin();//如果成立,说明剩余的顶点没有和当前顶点相连,可以退出了if(distanceParents[currentVertex].distance == INFINITE){System.err.println("full ......");break;}vertexList[currentVertex].setInTree(true);treeNum++;//打印print(currentVertex);//调整辅助数组adjust(currentVertex);}}/*** 获取距离最小的非父顶点的下标* @return*/public int getMin(){int temp = INFINITE;int tempIndex = -1;for(int i = 0; i < size; i++){int temp2 = distanceParents[i].distance;if(temp2 < temp && !vertexList[i].isInTree){temp = temp2;tempIndex = i;}}return tempIndex;}//调整辅助数组public void adjust(int currentVertex){for(int i = 1; i < size; i++){if(currentVertex == i)continue;//当前顶点到边缘顶点的路径长度(权重)int currentToFringe = matrix[currentVertex][i];//这个边缘顶点到源点的路径长度(权重)int startToFringe = distanceParents[currentVertex].distance+currentToFringe;if(vertexList[i].isInTree == false && distanceParents[i].distance > startToFringe){distanceParents[i].distance = startToFringe;distanceParents[i].parentVertex = currentVertex;}}}public void print(int currentVertex){Vertex parentVertex = vertexList[distanceParents[currentVertex].parentVertex];System.out.println(parentVertex.label+" --> "+vertexList[currentVertex].label+": "+distanceParents[currentVertex].distance+"; ");}/***  顶点类* @author admin**/class Vertex{//标签String label;//是否已经加入树中(即是否已经确认这个顶点到源点的最短路径)boolean isInTree;public Vertex(String label){this.label = label;this.isInTree = false;}public void setInTree(boolean isInTree) {this.isInTree = isInTree;}}/*** 记录某点的父顶点以及这个点到源点的距离* @author LiangYH**/class DistanceParent{//从源点到现在所在点的距离int distance;//现在所在点的父顶点int parentVertex;public DistanceParent(){}public DistanceParent(int distance, int parentVertex){this.distance = distance;this.parentVertex = parentVertex;}}
}

二、

下面的代码使用连接矩阵来表示顶点与顶点的边的关系的。具体一点讲就是,有几个顶点就有几行,每一行是一个链表,链表中的元素在实际图中表示为都与同一个元素相连。比如第一行有两个元素B和C,则表示B和C都和A相连。而上面的代码是用邻接矩阵表示的。在内存空间使用方面,本人觉得下面这种方式比较好。

package graph;import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;public class DijkstraGTest {public static void main(String[] args) {MyDijkstraG g = new MyDijkstraG(40);//增加顶点g.addVertex("A");g.addVertex("B");g.addVertex("C");g.addVertex("D");g.addVertex("E");g.addVertex("F");g.addVertex("G");//增加边和边的权重g.addEdge(0, 1, 50);g.addEdge(0, 3, 80);g.addEdge(1, 2, 60);g.addEdge(1, 3, 90);g.addEdge(2, 4, 40);g.addEdge(3, 2, 20);g.addEdge(3, 4, 70);g.addEdge(4, 1, 50);g.addEdge(2, 5, 60);g.addEdge(4, 5, 10);g.addEdge(5, 6, 40);//执行dijkstra算法g.doDijkstra();}
}class MyDijkstraG{//最大的权值private static final int INFINITE = 10000;//二维数组,连接矩阵List<LinkedList<VertexWeigth>> matrix = null;//顶点队列private Vertex[] vertexList;//顶点的个数private int size;//辅助数组,记录某点的父顶点以及这个点到源点的距离private DistanceParent[] distanceParents;public MyDijkstraG(int maxSize){this.vertexList = new Vertex[maxSize];this.matrix = new ArrayList<LinkedList<VertexWeigth>>();this.size = 0;this.distanceParents = new DistanceParent[maxSize];for(int i = 0; i < maxSize; i++){LinkedList<VertexWeigth> list = new LinkedList<>();matrix.add(list);}}//增加顶点public void addVertex(String label){vertexList[size++] = new Vertex(label);}//增加边和权重public void addEdge(int start, int end, int weigth){VertexWeigth vw = new VertexWeigth(end, weigth);matrix.get(start).add(vw);}//执行算法public void doDijkstra(){//当前顶点int currentVertex = 0;//加入树中的顶点数int treeNum = 1;//初始化:第一个顶点到其余顶点的权重,父顶点下标都为0Iterator<VertexWeigth> iter = matrix.get(0).iterator();while(iter.hasNext()){VertexWeigth vw = iter.next();distanceParents[vw.vertexIndex] = new DistanceParent(vw.weigth, 0);}//初始化:把源点不可达的边的权重都为最大,同时防止空异常for(int i = 0; i < size; i++){if(distanceParents[i] == null){distanceParents[i] = new DistanceParent(INFINITE, 0);}}//每一次循环,都可以确认某一个顶点到源点的最小距离while(treeNum < size){currentVertex = getMin();//如果成立,说明剩余的顶点没有和当前顶点相连,可以退出了if(distanceParents[currentVertex].distance == INFINITE){System.err.println("full ......");break;}vertexList[currentVertex].setInTree(true);treeNum++;//打印print(currentVertex);//调整辅助数组adjust(currentVertex);}}/*** 获取距离最小的非父顶点的下标* @return*/public int getMin(){int temp = INFINITE;int tempIndex = -1;for(int i = 0; i < size; i++){int temp2 = distanceParents[i].distance;if(temp2 < temp && !vertexList[i].isInTree){temp = temp2;tempIndex = i;}}return tempIndex;}//调整辅助数组public void adjust(int currentVertex){Iterator<VertexWeigth> iter = matrix.get(currentVertex).iterator();while(iter.hasNext()){VertexWeigth vw = iter.next();int currentToFringe = vw.weigth;int startToFringe = distanceParents[currentVertex].distance+currentToFringe;if(vertexList[vw.vertexIndex].isInTree == false && distanceParents[vw.vertexIndex].distance > startToFringe){distanceParents[vw.vertexIndex].distance = startToFringe;distanceParents[vw.vertexIndex].parentVertex = currentVertex;}}}public void print(int currentVertex){Vertex parentVertex = vertexList[distanceParents[currentVertex].parentVertex];System.out.println(parentVertex.label+" --> "+vertexList[currentVertex].label+": "+distanceParents[currentVertex].distance+"; ");}/*** 用于保存尾顶点的下标以及边的权重* @author LiangYH**/class VertexWeigth{int vertexIndex;int weigth;public VertexWeigth(){}public VertexWeigth(int vertexIndex, int weigth){this.vertexIndex = vertexIndex;this.weigth = weigth;}}/***  顶点类* @author admin**/class Vertex{//标签String label;//是否已经加入树中(即是否已经确认这个顶点到源点的最短路径)boolean isInTree;public Vertex(String label){this.label = label;this.isInTree = false;}public void setInTree(boolean isInTree) {this.isInTree = isInTree;}}/*** 记录某点的父顶点以及这个点到源点的距离* @author LiangYH**/class DistanceParent{//从源点到现在所在点的距离int distance;//现在所在点的父顶点int parentVertex;public DistanceParent(){}public DistanceParent(int distance, int parentVertex){this.distance = distance;this.parentVertex = parentVertex;}}
}

结果:

Dijkstra算法--有向图的源点到其他顶点的最短路径(连接矩阵、邻接矩阵两种方式)相关推荐

  1. ML之catboost:基于自定义数据集利用catboost 算法实现回归预测(训练采用CPU和GPU两种方式)

    ML之catboost:基于自定义数据集利用catboost 算法实现回归预测(训练采用CPU和GPU两种方式) 目录 基于自定义数据集利用catboost 算法实现回归预测(训练采用CPU和GPU两 ...

  2. 最短路径(Dijkstra算法),一文必看懂最短路径的方法

    最短路径问题(Dijkstra算法) 从图中的某一个顶点出发到达另一个顶点的所经过的边的权重和最小的一条路径,称为最短路径. Dijkstra算法适用于求一个节点到其他节点的最短路径,主要特点是通过广 ...

  3. PCA(2):PCA算法实现的两种方式

    因为样本个数和特征维度的是不相等de,所以组成的矩阵不是方阵. 第一种方式:特征分解思路(特征值分解要求分解的矩阵是方阵) 基于样本特征维度,先求协方差矩阵---->再特征分解(因为协方差矩阵是 ...

  4. 算法导论Java实现-随机化数组的两种方式(5.3章节)

    package lhz.algorithm.chapter.five; /** * 随机数组两种实现,<算法导论>第五章第三节 * 本文地址:http://mushiqianmeng.bl ...

  5. 最短汉密尔顿回路算法c语言,【算法】浅谈最短哈密尔顿回路类问题的两种近似算法...

    // 标题是糊弄人的 1. 问题引入 给出一张图,求其最短哈密尔顿回路,也就是 "旅行商问题"(Traveling Saleman Problem,TSP) 假设有一个旅行商人要拜 ...

  6. Dijkstra算法——计算一个点到其他所有点的最短路径的算法

    迪杰斯特拉算法百度百科定义:传送门 gh大佬博客:传送门 迪杰斯特拉算法用来计算一个点到其他所有点的最短路径,是一种时间复杂度相对比较优秀的算法 O(n2)(相对于Floyd算法来说) 是一种单源最短 ...

  7. 两种方式判断有向图是否有环-python实现

    1. DFS判断有向图是否有环 假设图以邻接矩阵表示,一条深度遍历路线中如果有结点被第二次访问到,那么有环.我们用一个变量来标记某结点的访问状态(未访问,访问过,其后结点都被访问过),然后判断每一个结 ...

  8. 十五、插入排序算法(两种方式)

    一.插入排序法思想 插入排序(Insertion Sorting)的基本思想是:把 n 个待排序的元素看成为一个有序表和一个无序表,开始时有 序表中只包含一个元素,无序表中包含有 n-1 个元素,排序 ...

  9. 【C语言】两种方式实现冒泡排序算法

    题目要求 编写一个C语言程序,实现基本的冒泡排序算法. 算法 冒泡排序,用一句话来总结: 一组数中,相邻的两个数进行比较.交换,将最大(小)数交换至尾(首)部,即完成了一次冒泡排序 要想对N个数字进行 ...

最新文章

  1. MySQL 关于毫秒和微秒的处理,MySQL获取毫秒!
  2. c语言怎么编程极差,我是一个编程能力很差的计算机专业的孩子。。==
  3. ASP.NET使用母版页后动态加载JS/CSS
  4. Swagger:后端文档生成工具
  5. python基础知识学习笔记(1)
  6. eas库存状态调整单不能反审核_仓储管理笔记:库存差错、毁损赔偿、自用管理、组织架构.........
  7. 计算机网络技术之网络系统设计与组建工程
  8. 【JSOI2015】bzoj4487 染色问题
  9. Python中字典(dict)和集合(set)区别与联系
  10. 利用call与ret实现段内子函数
  11. 纯css3彩色3d雪糕
  12. Docker_使用DockerFile监本构建镜像
  13. qt.network.monitor: Could not get the INetworkConnection instance for the adapter GUID.QT关闭时程序异常结束
  14. 《信息物理融合系统(CPS)设计、建模与仿真——基于 Ptolemy II 平台》——1.10 小结...
  15. React构造函数中为什么要写 super(props)
  16. Validators
  17. 搭建Discuz论坛网站-最新版Discuz3.4
  18. Fiddler抓取HTTPS最强攻略
  19. 【题解】codeforces765F Souvenirs
  20. pdf怎么转换成word文档呢?

热门文章

  1. 指针的本质是:内存(地址)+ 类型 装包解包
  2. CentOs7安装tomcat
  3. Java中异常处理之try和catch代码块的使用
  4. Eclipse中jsp、js文件编辑时,卡死现象解决汇总
  5. 【翻译转载】【官方教程】Asp.Net MVC4入门指南(2):添加一个控制器
  6. Loadrunner日志设置与查看
  7. sed当中使用变量替换以及执行外部命令
  8. python 多线程 类_Python中如何自定义一个多线程类呢?
  9. python访问数据库如何解决高并发_怎样解决数据库高并发的问题
  10. 服务器系统日志4625,win2008 r2 成千上万的“审核失败”日志 事件ID 4625