本文主要是本人对堆优化单源最短路径中堆的一些理解,如有需要还会发布对单源最短路径的解释。参考书目:Algorithms Design Techniques and Analysis【沙特】M.H.Alsuwaiyel,如有错误欢迎留言指出,谢谢。

在了解最小堆的特性之后,首先,要实现堆运算Sift_up,假定对于某个i,其键值变成了小于父节点的键值元素,这样就违反了最小堆的特性,所以要通过Sift_up,把这个不符合最小堆特性的数据项重新转移到二叉树的合适位置,以此修复最小堆的特性。具体代码如下:

def SIFT_UP(H,i,k):#H为堆,k为堆中数据项的键值done = Falseif i==1:return print(f"节点{i}为根")while i>1 or not done:if i>1:#在堆中,忽略H[0],因此在此代码中H[0]=inf,为避免H[i//2-1]取到inf,在此加入限制条件a=int(H[i]-1)b=int(H[i // 2]-1)if k[a]<k[b]:H[i],H[i//2]=H[i//2],H[i]else: done =Truei = i//2else:break

其次,在实际运算中,我们也会遇到存储在H中的数据项的键值有小于其子节点的键值的,这样也不符合最小堆的特性,因此需要用堆运算Sift_down,把这个不合适的数据项重新转移到合适的位置。具体代码如下:

def SIFT_down(H,i,k):a =  int(H[i] - 1)b = int(H[i // 2] - 1)c = int(H[i+1]-1)n = len(H)-1done = Falseif 2*i>n:print(f"节点{i}是叶子")while 2*i<=n or not done:i=2*iif i+1<=n and k[c]<k[a]:i=i+1if i<=n:#H[i]在列表内的时候,执行以下语句if k[b]>k[a]:H[i],H[i//2]=H[i//2],H[i]else:done = True

在实际运算中,我们可能需要对堆中的一些数据项进行删除处理,为了使删除数据项之后的堆依旧符合最小堆的特性,就需要对堆进行Sift_up或Sift_down运算,直到满足堆的特性。具体的删除代码如下:

"""要从大小为n的堆H中删除第i个元素,可以先用第n个元素替代第i个元素,然后将堆的大小减1"""
def delete(H,i,k):x=H[i]n=len(H)-1y=H[n]del H[n]if i==n+1:print("完成")if i==len(H):print(k)else:H[i]=yif k[y-1]>=k[x-1]:SIFT_UP(H,i,k)else:SIFT_down(H,i,k)

在实际运算中也要运用到插入堆的运算,插入堆与堆的Sift_up运算大同小异,具体代码如下:

def insert(H,x,k):H.append(x)SIFT_UP(H,H.index(x),k)

在解决单源最短路径的问题的时候,会遇到对数据项中最小键值的数据项的删除操作,具体代码如下:

def deletemin(H,k):x=H[1]delete(H,1,k)return x

以下是对最短路径的具体操作,其思想与Dijkstra的思想基本一致,只是运用堆去对路径进行了选择。具体代码如下:

def shoerestpath(lengh,H,V):V.remove(1)Y = Va=[0]*mk=[0]*mfor y in range(2,m+1):if lengh[1][y]!=inf:a[y-1]=lengh[1][y]k[y-1]=a[y-1]insert(H,y,k)else:a[y-1]=infk[y-1]=a[y-1]print(k)for j in range(1,m):# y = k.index(H[1]) + 1# delete(H, 1)y = deletemin(H,k)if y in Y:Y.remove(y)Y=Yfor w in range(1,m+1):if lengh[y][w]!=inf and w in Y:if a[y-1]+lengh[y][w]<a[w-1]:a[w-1]=a[y-1]+lengh[y][w]k[w-1]=a[w-1]print(k)if w not in H:insert(H,w,k)else:SIFT_UP(H,H.index(w),k)print(a)

完整代码如下:

from math import inf
def SIFT_UP(H,i,k):done = Falseif i==1:return print(f"节点{i}为根")while i>1 or not done:if i>1:a=int(H[i]-1)b=int(H[i // 2]-1)if k[a]<k[b]:H[i],H[i//2]=H[i//2],H[i]else: done =Truei = i//2else:break
def SIFT_down(H,i,k):a =  int(H[i] - 1)b = int(H[i // 2] - 1)c = int(H[i+1]-1)n = len(H)-1done = Falseif 2*i>n:print(f"节点{i}是叶子")while 2*i<=n or not done:i=2*iif i+1<=n and k[c]<k[a]:i=i+1if i<=n:#H[i]在列表内的时候,执行以下语句if k[b]>k[a]:H[i],H[i//2]=H[i//2],H[i]else:done = True
def delete(H,i,k):x=H[i]n=len(H)-1y=H[n]del H[n]if i==n+1:print("完成")if i==len(H):print(k)else:H[i]=yif k[y-1]>=k[x-1]:SIFT_UP(H,i,k)else:SIFT_down(H,i,k)
def insert(H,x,k):H.append(x)SIFT_UP(H,H.index(x),k)
def deletemin(H,k):x=H[1]delete(H,1,k)return x
def shoerestpath(lengh,H,V):V.remove(1)Y = Va=[0]*mk=[0]*mfor y in range(2,m+1):if lengh[1][y]!=inf:a[y-1]=lengh[1][y]k[y-1]=a[y-1]insert(H,y,k)else:a[y-1]=infk[y-1]=a[y-1]print(k)for j in range(1,m):# y = k.index(H[1]) + 1# delete(H, 1)y = deletemin(H,k)if y in Y:Y.remove(y)Y=Yfor w in range(1,m+1):if lengh[y][w]!=inf and w in Y:if a[y-1]+lengh[y][w]<a[w-1]:a[w-1]=a[y-1]+lengh[y][w]k[w-1]=a[w-1]print(k)if w not in H:insert(H,w,k)else:SIFT_UP(H,H.index(w),k)print(a)
if __name__ == '__main__':lengh = [[0,0,0,0,0,0,0],[0,0,1,12,inf,inf,inf],[0,inf,0,9,3,inf,inf],[0,inf,inf,0,inf,5,inf],[0,inf,inf,4,0,13,15],[0,inf,inf,inf,inf,0,4],[0,inf,inf,inf,inf,inf,0]]H=[inf]V={1,2,3,4,5,6}m=len(V)shoerestpath(lengh,H,V)

基于Python的堆优化单源最短路径相关推荐

  1. 洛谷_P3371 【模板】单源最短路径(弱化版)_dijkstra_堆优化

    洛谷_P3371 [模板]单源最短路径(弱化版)_dijkstra_堆优化 // dijkstra最短路算法_堆优化 #include<bits/stdc++.h> using names ...

  2. Python单源最短路径算法汇总

    给定一个带权有向图G=(V,E),其中每条边的权是一个实数.另外,还给定V中的一个顶点,称为源.要计算从源到其他所有各顶点的最短路径长度.这里的长度就是指路上各边权之和.这个问题通常称为单源最短路径问 ...

  3. matlab结束外循环,求单源最短路径的BellmanFord算法的matlab实现及其优化

    function [minD,path] = BellmanFord(w,start,terminal) %求单源最短路径的Bellman-Ford算法(图论) %调用格式:[minD,path] = ...

  4. 1131 拯救大兵瑞恩(单源最短路径扩展-拆点(dp))

    1. 问题描述: 1944 年,特种兵麦克接到国防部的命令,要求立即赶赴太平洋上的一个孤岛,营救被敌军俘虏的大兵瑞恩.瑞恩被关押在一个迷宫里,迷宫地形复杂,但幸好麦克得到了迷宫的地形图.迷宫的外形是一 ...

  5. 【算法】Dijkstra算法(单源最短路径问题) 邻接矩阵和邻接表实现

    Dijkstra算法可使用的前提:不存在负圈. 负圈:负圈又称负环,就是说一个全部由负权的边组成的环,这样的话不存在最短路,因为每在环中转一圈路径总长就会边小. 算法描述: 1.找到最短距离已确定的顶 ...

  6. 四种不同单源最短路径算法性能比较

    四种不同单源最短路径算法性能比较   一.最短路径问题描述 单源最短路径描述:给定带权有向图G=(V,E),其中每条边的权是非负实数.另外,还给定V中的一个顶点,称之为源.现在要计算从源到其他各顶点的 ...

  7. JAVA编程求单源最短路径_【算法】单源最短路径——dijkstra算法

    一,概念 单源最短路径 给定一个带权有向图G=(V,E),其中每条边的权是一个实数.另外,还给定V中的一个顶点,称为源.要计算从源到其他所有各顶点的最短路径长度.这里的长度就是指路上各边权之和.这个问 ...

  8. 四种单源最短路径算法

      一.最短路径问题描述 单源最短路径描述:给定带权有向图G=(V,E),其中每条边的权是非负实数.另外,还给定V中的一个顶点,称之为源.现在要计算从源到其他各顶点的最短路径的长度.这里的路径长度指的 ...

  9. 单源路径分支界限java_java单源最短路径算法

    . .. .. . 单源最短路径的 Dijkstra 算法: 问题描述: 给定一... 并 应用贪心法求解单源最短路径问题.环境要求对于环境没有特别要求.对于算法实现,可以自由选择 C, C++, J ...

最新文章

  1. AppDynamics赵宇辰:硅谷APM独角兽,打造DevOps领域的智能大脑
  2. Matlab cell矩阵处理
  3. Linux文本处理之printf:规定输出内容与样式 %规定内容样式 \规定排版样式
  4. JDK 12,合并的收集器和命名的挑战
  5. 第二天 Linux常见命令
  6. 对话清华NLP实验室刘知远:NLP搞事情少不了知识库与图神经网络
  7. Python数据分析与机器学习实战
  8. (转载)神级代码编辑器 Sublime Text 全程指南
  9. 【渝粤教育】电大中专中药学基础作业 题库
  10. flutter项目实战三:封装http工具类
  11. 协同感知综述:从异质单体到分层合作
  12. 【opencv】selective_search函数
  13. Java音乐播放器设计
  14. 专访腾讯高级交互设计师WingST:交互设计师的思维、眼界、手段和精神
  15. No module named ‘_lzma’
  16. 盛大:一个游戏公司的剧烈转型
  17. 阿木实验室 ubuntu 20.04 Prometheus 系统 编译问题
  18. kalman filter java_Kalman Filter算法详解
  19. 学考计算机里分号是哪个,中考电脑阅卷流程曝光!认真看完多拿分!
  20. 深度学习-参数量模型大小理论计算量

热门文章

  1. Webpack 究竟是什么?如何理解Webpack
  2. 杨绛十句话,最好背下来
  3. 如何实现电脑通过手机上网?1分钟搞定!
  4. Windows Server 远程桌面 SSL/TLS 漏洞修复
  5. RH850从0搭建Autosar开发环境【2】- Davinci Configurator配置工程导入DBC与CDD文件
  6. java之打印日历表
  7. 免费制作字体软件 - FontForge
  8. C语言与C++与JAVA的区别
  9. APP UI 真的可以实现自动化测试吗?
  10. cpu功耗排行_目前较低功耗的intel系cpu求推荐?