首页 > 编程语言 >python | 算法-最短路径-dijikstra改进算法

python | 算法-最短路径-dijikstra改进算法

时间:2022-10-27 15:25:32浏览次数:67  
标签:node index python self 算法 heap dijikstra nodes dis

写在前面:
我自己用python练习算法与数据结构的典型算法汇总在这里:汇总-算法与数据结构-python版,欢迎翻阅!

1️⃣ 参考链接https://github.com/algorithmzuo/algorithmbasic2020/blob/master/src/class16/Code06_Dijkstra.java

2️⃣ 所用例子

数据结构

与前章同:python | 算法-图的宽度优先遍历

dijikstra改进算法

class Dijikstra:
    # 改进的dijikstra算法: 利用堆结构
    # 从head出发,所有head能到达的节点,生成到达每个节点的最小路径记录并返回
    # 参考:https://github.com/algorithmzuo/algorithmbasic2020/blob/master/src/class16/Code06_Dijkstra.java
    def dijikstra2(self, first):
        node_heap = NodeHeap()
        node_heap.add_update_ignore(first, 0)
        result = {} # node:distance(first到node的最短距离)
        while not node_heap.is_empty():
            record = node_heap.pop()
            cur = record.node
            cur_dis = record.dis # cur diatance
            for edge in cur.edges:
                node_heap.add_update_ignore(edge.n_to, edge.weight + cur_dis)
            result[cur] = cur_dis

        return result

class NodeHeap:
    def __init__(self):
        self.size = 0
        self.nodes_heap = []
        self.dis_map = {} # distance map
        self.heap_index = {} # heap index map

    def is_empty(self):
        return self.size == 0

    def add_update_ignore(self, node, distance):
        # 如果node已经入堆,更新源点到node的最短距离
        if self.in_heap(node):
            self.dis_map[node] = min(self.dis_map[node], distance)
            # 调整堆 insert heapify
            self.insert_heapify(self.heap_index[node])
        if not self.entered(node):
            self.nodes_heap.append(node)
            self.heap_index[node] = self.size
            self.dis_map[node] = distance
            self.insert_heapify(self.size)
            self.size += 1

    def in_heap(self, node):
        return self.entered(node) and self.heap_index[node] != -1

    def entered(self, node):
        return node in self.heap_index.keys()

    def insert_heapify(self, index):
        while self.dis_map[self.nodes_heap[index]] < self.dis_map[self.nodes_heap[int((index - 1) / 2)]]:
            self.swap(index, int((index-1)/2))
            index = int((index -1) / 2)

    def swap(self, index1, index2):
        self.heap_index[self.nodes_heap[index1]] = index2
        self.heap_index[self.nodes_heap[index2]] = index1
        tmp = self.nodes_heap[index1]
        self.nodes_heap[index1] = self.nodes_heap[index2]
        self.nodes_heap[index2] = tmp

    def pop(self):
        node_record = NodeRecord(node=self.nodes_heap[0], distance=self.dis_map[self.nodes_heap[0]])
        self.swap(0, self.size - 1)
        self.heap_index[self.nodes_heap[self.size-1]] = -1
        self.dis_map.pop(self.nodes_heap[self.size-1])
        self.nodes_heap.pop(self.size - 1)
        self.size -= 1
        self.heapify(0, self.size)
        return node_record

    def heapify(self, index, size):
        left = index * 2 + 1
        while left < size:
            smallest = left + 1 if left + 1 < size and \
            self.dis_map[self.nodes_heap[left+1]] < self.dis_map[self.nodes_heap[left]] \
                else left
            smallest = smallest if self.dis_map[self.nodes_heap[smallest]] < self.dis_map[self.nodes_heap[index]] \
                else index
            if smallest == index: break
            self.swap(smallest, index)
            index = smallest
            left = index * 2 + 1

class NodeRecord:
    def __init__(self, node, distance):
        self.node = node
        self.dis = distance

# test
# 自定义一个无向连通图
m = [[7, 'A', 'B'], [5, 'A', 'D'], [9, 'B', 'D'],
     [8, 'B', 'C'], [7, 'B', 'E'], [5, 'C', 'E'],
     [15, 'D', 'E'], [6, 'D', 'F'], [8, 'E', 'F'],
     [9, 'E', 'G'], [11, 'F', 'G'],
     [7, 'B', 'A'], [5, 'D', 'A'], [9, 'D', 'B'],
     [8, 'C', 'B'], [7, 'E', 'B'], [5, 'E', 'C'],
     [15, 'E', 'D'], [6, 'F', 'D'], [8, 'F', 'E'],
     [9, 'G', 'E'], [11, 'G', 'F']]
generator = GraphGenerator()
graph = generator.createGraph(m)
# 指定出发点
first = graph.nodes['C']
D = Dijikstra()
result = D.dijikstra2(first)
for node in result.keys():
    print(str(first.value)+str(node.value)+':'+str(result[node]))

# 输出
# CC:0
# CE:5
# CB:8
# CF:13
# CG:14
# CD:17
# CA:15

标签:node,index,python,self,算法,heap,dijikstra,nodes,dis
From: https://www.cnblogs.com/ljdsbfj/p/16832328.html

相关文章

  • Python之JSON用法解析
    前景Python编写HDFS服务安装的过程中,需要将构建好的JSON对象输出到文件,采用那种方式更便捷方案1open函数defwriteExecCmdCheckActionsFile(self,out_res,che......
  • Python在接口测试中的应用
    1.介绍接口测试的方式有很多,可以使用的工具有jmeter,postman,soapUI等,也可以自己写代码进行接口测试(Python,java,go等等),工具的使用相对来说都比较简单,开箱即用。但如果接口中定......
  • 一文带你了解 Python 中的继承知识点
    1类继承Python是面向对象的编程语言,因此支持面向对象的三大特性之一:继承。继承是代码重用的一种途径,Python中的继承就像现实生活中的继承一样,子类可以顺利继承父类的属性......
  • Python7-实战
    实战01(修改手机默认语言)1classPhone:2'''手机类'''3def__init__(self,language='英文'):4iflanguage=='英文':5print("智能手......
  • conda管理python环境
    Anaconda使用教程Anaconda详细安装使用教程condacreate-nlearnpython=3//创建一个名为learn的环境并指定python版本为3(最新版本)condaactivatelearn//激活l......
  • python遇到IndexError: only integers, slices (`:`), ellipsis (`...`)……
    完整错误信息如下:IndexError:onlyintegers,slices(​​:​​​),ellipsis(​​...​​​),numpy.newaxis(​​None​​)andintegerorbooleanarraysarevalid......
  • python获取文件夹、文件大小&hiberfil.sys
    跑了个很简单的程序,c盘突然爆炸增加,顿时SSD120G的盘只剩下几个G,所以有需求看看那些文件占用了大量空间。(事先通过360大文件扫描、日期排序分析未发现异常)importosimportsy......
  • python的开源微信接口
    开源微信接口文档地址:​​https://itchat.readthedocs.io/zh/latest/​​​github地址:​​​https://github.com/littlecodersh/itchat​​如下举例:importitchatitchat.......
  • OpenCV-Python learning-13.人脸检测
    如下,调用opencv使用摄像头或视频进行人脸检测,也可以在函数​​recognize(img)​​​传入​​img=cv2.imread('face.jpg')​​​。其中,人脸级联分类器xml文件我引用的是anaco......
  • python 格式化xml字符串
    【前言】本文主要介绍python中的字符串格式化,通过基本概念,使用方法及例子学习python字符串格式化的两种主要形式:字符串格式化表达以及字符串格式化方法调用。字符串......