当前位置: 首页 > news >正文

八.迪杰斯特拉(Dijkstra)算法

文章目录

    • 迪杰斯特拉算法
      • 应用场景—最短路径问题
      • 迪杰斯特拉(Dijkstra)算法介绍
        • 迪杰斯特拉(Dijkstra)算法过程
        • 思路图解
      • 代码实现

迪杰斯特拉算法

应用场景—最短路径问题

看一个应用场景和问题

image-20250824150626133

1)战争期间,胜利乡有7个村庄(A,B,C,D,E,F,G),现在有六个邮差,从G点出发,需要分别把邮件分别送到A,B,C,D,E,F六个村庄

2)各个村庄的距离用边线表示(权),比如A—B距离5公里

3)问:如何计算出G村庄到其他各个村庄的最短距离?

4)如果从其他点出发到各个点的最短距离又是多少?

迪杰斯特拉(Dijkstra)算法介绍

迪杰斯特拉(Dijkstra)算法是典型最短路径算法,用于计算一个节点到其他节点的最短路径。它的主要特点是以起始点为中心向外层层扩展(广度优先搜索思想),直到扩展到终点为止

迪杰斯特拉(Dijkstra)算法过程

设置出发顶点为v,顶点集合V{v1,v2,vi…},v到V中各顶点的距离构成距离集合Dis, Dis{d1,d2,di…} , Dis集合记录着v到图中各顶点的距离(到自身可以看作0,v到vi距离对应为di)

1)从Dis中选择值最小的di并移出Dis集合,同时移出V集合中对应的顶点vi,此时的v到vi即为最短路径

2)更新Dis集合,更新规则为:比较v到V集合中顶点的距离值,与v通过vi到V集合中顶点的距离值,保留值较小的一个(同时也应该更新顶点的前驱节点为vi,表明是通过vi到达的)

3)重复执行两步骤,直到最短路径顶点为目标顶点即可结束

思路图解

image-20250824222241967

class VisitedVertex{ //已访问顶点集合

public int[] already_arr; //记录各个顶点是否访问过 1表示访问过,0未访问过,会动态更新

public int[] pre_visited; //每个下标对应的值为前一个顶点下标,会动态更新

public int[] dis; //记录出发顶点到其他所有顶点的距离,比如G为出发顶点,就会记录G到其他顶点的距离,会动态更新,求的最短距离就会存放到dis

}

代码实现

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;namespace DijkstraAlgorithm
{class Program{static void Main(string[] args){char[] vertex = new char[] { 'A', 'B', 'C','D', 'E', 'F', 'G' };  //顶点数组//邻接矩阵int[,] matrix = new int[vertex.Length, vertex.Length];  //二维数组int N = 65535;  //表示不可连接matrix = new int[,]{{N,5,7,N,N,N,2 },{5,N,N,9,N,N,3 },{7,N,N,N,8,N,N },{N,9,N,N,N,4,N },{N,N,8,N,N,5,4 },{N,N,N,4,5,N,6 },{2,3,N,N,4,6,N },};//创建一个图对象Graph graph = new Graph(vertex, matrix);//测试,看看图的邻接矩阵是否okgraph.showGraph();//测试迪杰斯特拉算法graph.dsj(6);graph.showDijkstra();}}class Graph  //图{private char[] vertex;   //顶点数组private int[,] matrix;   //邻接矩阵private VisitedVertex vv;   //已经访问的顶点的集合//构造器public Graph(char[] vertex,int[,] matrix){this.vertex = vertex;this.matrix = matrix;}//显示最后结果public void showDijkstra(){vv.show();}//显示图的方法public void showGraph(){for (int i = 0; i < vertex.Length; i++){for (int j = 0; j < vertex.Length; j++){Console.Write( "{0,7}",matrix[i,j]);}Console.WriteLine();}}//迪杰斯特拉算法/// <summary>/// /// </summary>/// <param name="index">表示出发顶点的下标</param>public void dsj(int index){vv = new VisitedVertex(vertex.Length, index);update(index);  //更新index顶点到周围顶点的距离和前驱顶点//把第一个顶点走完,然后把剩余的顶点一个一个走一遍,每走一次选一个新的顶点for (int j = 1; j < vertex.Length; j++){index = vv.updateArr();  //选择并返回新的访问顶点update(index);  //更新index顶点到周围顶点的距离和前驱顶点}}//更新index顶点到周围顶点的距离和周围顶点的前驱顶点private void update(int index){int len = 0;//遍历我们的邻接矩阵matrix[index]行,因为正在考虑index跟其他顶点的关系for (int j = 0; j < matrix.GetLength(0); j++)  //GetLength(0)是行的长度,GetLength(1)是列的长度{//len含义:出发顶点到index顶点的距离+从index顶点到j顶点的距离len = vv.getDis(index)+matrix[index,j];  //如果j这个顶点没有被访问过,并且len小于出发顶点到j顶点的距离,就需要更新if(!vv.In(j) && len < vv.getDis(j))  //j没有被访问过,把j考虑进去,距离还变小了{vv.updatePre(j, index);   //更新j顶点的前驱为index顶点vv.updateDis(j, len);   //更新出发顶点到j顶点的距离}}}}//已访问顶点集合class VisitedVertex{public int[] already_arr;   //记录各个顶点是否访问过 1表示访问过,0未访问过,会动态更新public int[] pre_visited;   //每个下标对应的值为前一个顶点下标,会动态更新public int[] dis;  //记录出发顶点到其他所有顶点的距离,比如G为出发顶点,就会记录G到其他顶点的距离,会动态更新,求的最短距离就会存放到dis//构造器/// <summary>/// /// </summary>/// <param name="length">表示顶点的个数</param>/// <param name="index">出发顶点对应的下标,比如G顶点,下标就是6</param>public VisitedVertex(int length, int index){this.already_arr = new int[length];this.pre_visited = new int[length];this.dis = new int[length];//初始化dis数组dis = new int[] { 65535, 65535, 65535, 65535, 65535, 65535, 0 };this.already_arr[index] = 1;  //设置出发顶点被访问过}/// <summary>/// 功能:判断index顶点是否被访问过/// </summary>/// <param name="index"></param>/// <returns>如果访问过返回true,否则返回false</returns>public Boolean In(int index){return already_arr[index] == 1;  }/// <summary>/// 功能:更新出发顶点到index这个顶点的距离/// </summary>/// <param name="index">更新哪一个</param>/// <param name="len">更新为多少</param>public void updateDis(int index,int len)  {dis[index] = len;  }/// <summary>/// 功能:更新pre顶点的前驱顶点为index顶点/// </summary>/// <param name="pre"></param>/// <param name="index"></param>public void updatePre(int pre,int index){pre_visited[pre] = index;}/// <summary>/// 返回出发顶点到index顶点的距离/// </summary>public int getDis(int index){return dis[index];}//继续选择并返回新的访问顶点,比如这里的G完后,就是A点作为新的访问顶点(注意不是出发顶点)public int updateArr(){int min = 65535, index = 0;for (int i = 0; i < already_arr.Length; i++){if (already_arr[i]==0 && dis[i] < min){min = dis[i];index = i;  //下一个访问顶点就变成i了}}//更新index顶点被访问过already_arr[index] = 1;return index;}//显示最后的结果,即将三个数组的情况输出public void show(){Console.WriteLine("===================================================");//输出already_arrforeach (var item in already_arr){Console.Write(item+" ");}Console.WriteLine();//输出前驱顶点pre_visitedforeach (var item in pre_visited){Console.Write(item+" ");}Console.WriteLine();//输出disforeach (var item in dis){Console.Write(item+" ");}Console.WriteLine();//为了好看最后的最短距离,我们处理char[] vertex = { 'A', 'B', 'C', 'D', 'E', 'F', 'G' };int count = 0;foreach (var i in dis){if (i != 65535){Console.Write(vertex[count]+"("+i+")"+" ");}else{Console.WriteLine("N");}count++;}Console.WriteLine();}}
}

文章转载自:

http://NCzFwWOt.qdzqf.cn
http://Zi0bEtI3.qdzqf.cn
http://MzZ7c5pw.qdzqf.cn
http://UBJa1rBd.qdzqf.cn
http://kgs8Fk2e.qdzqf.cn
http://BelsE4Pf.qdzqf.cn
http://sCJL7S1u.qdzqf.cn
http://uLdbqQRq.qdzqf.cn
http://OPoSOAos.qdzqf.cn
http://xiv7sZvc.qdzqf.cn
http://TziuAzQu.qdzqf.cn
http://sAW7lY8y.qdzqf.cn
http://nxFh3vJ7.qdzqf.cn
http://JGBHVQK4.qdzqf.cn
http://K1K2ww47.qdzqf.cn
http://aql92ckW.qdzqf.cn
http://Wxxtw2EX.qdzqf.cn
http://hsXk3pur.qdzqf.cn
http://s3NLNcvh.qdzqf.cn
http://O0mx8G3r.qdzqf.cn
http://nwOsXumE.qdzqf.cn
http://COXQIogm.qdzqf.cn
http://7VKYZDoe.qdzqf.cn
http://iz5XGBT8.qdzqf.cn
http://3yrgxHN8.qdzqf.cn
http://rEiL1iD6.qdzqf.cn
http://dqPTgSQa.qdzqf.cn
http://I6Jg52SV.qdzqf.cn
http://9THHIKPZ.qdzqf.cn
http://BQpYoWwk.qdzqf.cn
http://www.dtcms.com/a/372122.html

相关文章:

  • 大模型术语
  • Python入门教程之关系运算符
  • 9. Mono项目与Unity的关系
  • 【C#】 资源共享和实例管理:静态类,Lazy<T>单例模式,IOC容器Singleton我们该如何选
  • 【C语言】函数指针的使用分析:回调、代码逻辑优化、代码架构分层
  • SQLAlchemy ORM-表与表之间的关系
  • 系统架构性能优化与容灾设计深度解析
  • K8s ConfigMap配置管理全解析
  • 【Beetle RP2350】人体运动感应警报系统
  • tomcat下载
  • 数据结构精讲:栈与队列实战指南
  • 风电设备预测性维护方案:AIoT驱动的风电运维智能化转型​
  • Shell脚本监控系统资源详解
  • Vue基础知识-脚手架开发-Vue Router路由及params、query传参
  • 鱼眼相机模型
  • 类的加载和对象的创建
  • trl GRPO源码分析:如何处理多个reward function?
  • 临床研究三千问——临床研究体系的3个维度(8)
  • TypeORM入门教程:@JoinColumn和@OneToOne的关系
  • html列表标签之无序列表
  • [1]-01-创建空工程
  • 【模型训练篇】VeRL核心思想 - 论文HybridFlow
  • pycharm设置编辑区字体大小
  • 鸿蒙NEXT跨设备数据同步实战:分布式应用开发指南
  • C++ 中栈 (Stack) 详解和常见面试示例汇总实现
  • [光学原理与应用-461]:波动光学 - 波片实现偏振态的转换或调整
  • 苍穹外卖Day12 | Apache POI、导出Excel报表、HttpServletResponse、工作台
  • 《Go小技巧易错点100例》第三十八篇
  • Conda 包管理器与环境管理使用指南
  • 笔记本、平板如何成为电脑拓展屏?向日葵16成为副屏功能一键实现