迪瑞克斯拉算法 — 优化

在上一篇迪瑞克斯拉算法中将功能实现了出来,完成了图集中从源点出发获取所有可达的点的最短距离的收集。
但在代码中getMinDistanceAndUnSelectNode()方法的实现并不简洁,每次获取minNode时,都需要遍历整个Map,时间复杂度太高。这篇文章主要是针对上一篇文章代码的一个优化。
其优化的过程中主要是用到了加强堆的数据结构,如果不了解的强烈建议先看加强堆的具体实现。

回顾:

在这里插入图片描述
上一篇中,将确定不变的点放入Set中, 每个点之间的距离关系放入Map中,每次遍历Map获取最小minNode,并根据该点找到所有的边,算出最小距离后,放入set中,最终确定最小距离表。

优化
利用加强堆,来维护点和距离的关系,并利用小根堆的优势,让最小的点总是在最上面,需要注意的是,以往的的加强堆中,如果移除了这个元素会直接remove,但是在这里不能remove,因为要记录这个点是否在堆上,是否加入过堆,所以对于确定了的元素,value要改成 -1,用来标记当前元素已经确定,不用再动。

加强堆代码
NodeHeap中的distanceMap用来表示点和距离的关系,根据value的大小动态变化堆顶元素。
主方法是addOrUpdateOrIgnore()。
如果当前元素在堆中并且value != 1(inHeap),说明元素还没有确定,则判断进来的node和value是否大于当前堆中的node对应的value,取小的更新,如果更新,还需要改变元素在堆中位置,因为只可能越更新越小。所以要调用insertHeapify方法去改变堆结构。
如果元素还未加入过堆(!isEntered),则挂在堆尾,并insertHeapify检查是否上移。
pop方法中,如果弹出堆,正常要删除,但是不能删除,除了和最后一个元素交换,下移外,将distanceMap中对应的值改为 -1。否则无法判断该元素是否已经加入过堆,是否已经确定。

public static class NodeHeap {//Node类型的堆private Node[] nodes;//key对应的Node在堆中的位置是valueprivate HashMap<Node, Integer> heapIndexMap;//key对应的Node当前距离源点最近距离private HashMap<Node, Integer> distanceMap;//堆大小private int size;public NodeHeap(int size) {nodes = new Node[size];heapIndexMap = new HashMap<>();distanceMap = new HashMap<>();this.size = 0;}public boolean isEmpty() {return this.size == 0;}public boolean isEntered(Node head) {return heapIndexMap.containsKey(head);}public boolean inHeap(Node head) {return isEntered(head) && heapIndexMap.get(head) != -1;}public void swap(int index1, int index2) {heapIndexMap.put(nodes[index1], index2);heapIndexMap.put(nodes[index2], index1);Node tmp = nodes[index1];nodes[index1] = nodes[index2];nodes[index2] = tmp;}public void heapify(int index, int size) {int left = (index * 2) - 1;while (left < size) {int smallest = left + 1 < size && distanceMap.get(nodes[left + 1]) < distanceMap.get(nodes[left]) ? left + 1 : left;smallest = distanceMap.get(nodes[smallest]) < distanceMap.get(nodes[index]) ? smallest : index;if (smallest == index) {break;}swap(smallest, index);index = smallest;left = (index * 2) - 1;}}public void insertHeapify(Node node, int index) {while (distanceMap.get(nodes[index]) < distanceMap.get((index - 1) / 2)) {swap(distanceMap.get(nodes[index]), distanceMap.get((index - 1) / 2));index = (index - 1) / 2;}}public NodeRecord pop() {NodeRecord nodeRecord = new NodeRecord(nodes[0], distanceMap.get(0));swap(0, size - 1);heapIndexMap.put(nodes[size - 1], -1);distanceMap.remove(nodes[size - 1]);heapify(0, --size);return nodeRecord;}public void addOrUpdateOrIgnore(Node node, int distance) {if (inHeap(node)) {distanceMap.put(node, Math.min(distanceMap.get(node), distance));insertHeapify(node, distanceMap.get(node));}if (!isEntered(node)) {nodes[size] = node;heapIndexMap.put(node, size);distanceMap.put(node, distance);insertHeapify(node, size++);}}}

主方法逻辑
上来将给定的点添加到堆中,并且弹出,遍历所有的边放到加强堆中去搞。

  public static HashMap<Node, Integer> dijkstra2(Node head, int size) {NodeHeap nh = new NodeHeap(size);nh.addOrUpdateOrIgnore(head, 0);HashMap<Node, Integer> result = new HashMap<>();while (!nh.isEmpty()) {NodeRecord record = nh.pop();Node cur = record.node;int distance = record.distance;for (Edge edge : cur.edges) {nh.addOrUpdateOrIgnore(edge.to, distance + edge.weight);}result.put(cur, distance);}return result;}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/36643.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

HTML详解连载(5)

HTML详解连载&#xff08;5&#xff09; 专栏链接 [link](http://t.csdn.cn/xF0H3)下面进行专栏介绍 开始喽行高&#xff1a;设置多行文本的间距属性名属性值行高的测量方法 行高-垂直居中技巧 字体族属性名属性值示例扩展 font 复合属性使用场景复合属性示例注意 文本缩进属性…

UG NX二次开发(C#)-CAM自定义铣加工的出口环境

文章目录 1、前言2、自定义铣削加工操作3、出错原因4、解决方案4.1 MILL_USER的用户参数4.2 采用自定义铣削的方式生成自定义的dll4.2 配置加工的出口环境4.3 调用dll5、结论1、前言 作为一款大型的CAD/CAM软件, UG NX为我们提供了丰富的加工模板,通过加工模板能直接用于生成…

DTC服务(0x14 0x19 0x85)

DTC相关的服务有ReadDTCInformation (19) service&#xff0c;ControlDTCSetting (85) service和ReadDTCInformation (19) service ReadDTCInformation (19) service 该服务允许客户端从车辆内任意一台服务器或一组服务器中读取驻留在服务器中的诊断故障代码( DTC )信息的状态…

Web菜鸟教程 - Radis实现高性能数据库

Redis是用C语言开发的一个高性能键值对数据库&#xff0c;可用于数据缓存&#xff0c;主要用于处理大量数据的高访问负载。 也就是说&#xff0c;如果你对性能要求不高&#xff0c;不用Radis也是可以的。不过作为最自己写的程序有高要求的程序员&#xff0c;自然是要学一下的&a…

PHP Mysql查询全部全部返回字符串类型

设置pdo属性 $pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, true);

08-1_Qt 5.9 C++开发指南_QPainter绘图

文章目录 前言1. QPainter 绘图系统1.1 QPainter 与QPaintDevice1.2 paintEvent事件和绘图区1.3 QPainter 绘图的主要属性 2. QPen的主要功能3. QBrush的主要功能4. 渐变填充5. QPainter 绘制基本图形元件5.1 基本图像元件5.2 QpainterPath的使用 前言 本章所介绍内容基本在《…

chatserver服务器开发笔记

chatserver服务器开发笔记 1 chatserver2 开发环境3 编译 1 chatserver 集群聊天服务器和客户端代码&#xff0c;基于muduo、redis、mysql实现。 学习于https://fixbug.ke.qq.com/ 本人已经挂github&#xff1a;https://github.com/ZixinChen-S/chatserver/tree/main 需要该项…

kubernetes pod 资源限制 探针

资源限制 当定义 Pod 时可以选择性地为每个容器设定所需要的资源数量。 最常见的可设定资源是 CPU 和内存大小&#xff0c;以及其他类型的资源。 当为 Pod 中的容器指定了 request 资源时&#xff0c;代表容器运行所需的最小资源量&#xff0c;调度器就使用该信息来决定将 Pod …

Java课题笔记~ JSP开发模型

MVC 1.JSP演化历史 1. 早期只有servlet&#xff0c;只能使用response输出标签数据&#xff0c;非常麻烦 2. 后来有了jsp&#xff0c;简化了Servlet的开发&#xff0c;如果过度使用jsp&#xff0c;在jsp中即写大量的java代码&#xff0c;有写html表&#xff0c;造成难于维护&…

计算机网络实验4:HTTP、DNS协议分析

文章目录 1. 主要教学内容2. HTTP协议3. HTTP分析实验【实验目的】【实验原理】【实验内容】【实验思考】 4. HTTP分析实验可能遇到的问题4.1 捕捉不到http报文4.2 百度是使用HTTPS协议进行传输4.3 Wireshark获得数据太多如何筛选4.4 http报文字段含义不清楚General&#xff08…

Git和GitHub

文章目录 1.Git介绍2. 常用命令3. Git分支操作4. Git团队协作机制5. GitHub操作6. IDEA集成Git7.IDEA操作GitHub8. Gitee 1.Git介绍 Git免费的开源的分布式版本控制系统&#xff0c;可以快速高效从小到大的各种项目 Git易于学习&#xff0c;占地面积小&#xff0c;性能快。它…

【日常积累】RPM包依赖下载及私有yum仓库搭建

概述 某些时候&#xff0c;我们需要下载某个RPM包依赖的依赖。如某些内网环境&#xff0c;就需要自行准备rpm包。可以通过能上互联网的服务器进行相应的rpm包下载&#xff0c;然后在拷贝到相应的服务器安装&#xff0c;或者搭建自己的内容rpm包仓库。 查看*.rpm 包依赖&#…

Flink多流处理之Broadcast(广播变量)

写过Spark批处理的应该都知道,有一个广播变量broadcast这样的一个算子,可以优化我们计算的过程,有效的提高效率;同样在Flink中也有broadcast,简单来说和Spark中的类似,但是有所区别,首先Spark中的broadcast是静态的数据,而Flink中的broadcast是动态的,也就是源源不断的数据流.在…

什么是微服务?

2.微服务的优缺点 优点 单一职责原则每个服务足够内聚&#xff0c;足够小&#xff0c;代码容易理解&#xff0c;这样能聚焦一个指定的业务功能或业务需求&#xff1b;开发简单&#xff0c;开发效率提高&#xff0c;一个服务可能就是专一的只干一件事&#xff1b;微服务能够被小…

命令提示符之操作基础(Windows)

打开命令提示符 方法一 打开指定文件的文件夹&#xff0c;在路径栏里输入“cmd”&#xff0c;回车&#xff0c;就进入控制台了。默认路径就是指定文件夹的路径。 方法二 打开指定的文件夹&#xff0c;按住shift键&#xff0c;在空白处右击&#xff0c;在菜单栏中选择“在此处打…

社区团购商城拼团秒杀接龙分销团长小程序开源版开发

社区团购商城拼团秒杀接龙分销团长小程序开源版开发 功能介绍&#xff1a; 商品管理&#xff1a;增加商品-商品列表-商品分类-商品单/多规格-商品标签 订单管理&#xff1a;订单列表-订单挑选-订单导出-订单打印-批量发货-商品评价 会员管理&#xff1a;会员列表-会员挑选-会员…

【Git】—— 标签管理

目录 &#xff08;一&#xff09;理解标签 1、作用 &#xff08;二&#xff09;创建标签 &#xff08;三&#xff09;操作标签 1、删除标签 2、推送标签 3、删除远程标签 &#xff08;一&#xff09;理解标签 标签 tag &#xff0c;可以简单的理解为是对某次 commit 的…

python中的迭代器和生成器

一、迭代器 支持迭代的容器&#xff0c;如列表&#xff08;list&#xff09;、元组&#xff08;tuple&#xff09;、字典&#xff08;dict&#xff09;、集合&#xff08;set&#xff09;这些序列式容器。 自定义迭代器的类中必须实现以下2个方法&#xff1a; __next__(self)…

监控Kubernetes 控制面组件的关键指标

控制面组件的监控&#xff0c;包括 APIServer、Controller-manager&#xff08;简称 CM&#xff09;、Scheduler、etcd 四个组件。 1、APIServer APIServer 的核心职能是 Kubernetes 集群的 API 总入口&#xff0c;Kube-Proxy、Kubelet、Controller-Manager、Scheduler 等都需…

TCP 协议十大相关特性总结

目录 一、TCP特性 二、报文格式 TCP十大核心特性 1. 确认应答 2. 超时重传 3. 连接管理(三次握手,四次挥手) 三次握手 四次挥手 4. 滑动窗口 情况一:接收方的ACK丢失 情况二:发送方的数据包丢失 5. 流量控制 6. 拥塞控制 7. 延迟应答 8. 捎带应答 9. 字节流粘包问题 10. TCP的…