无向图-最短路径Dijkstra(迪杰斯特拉算法)算法

一、算法思路

1、采用广度优先搜索算法;

2、二维数组初始化无向图;

3、创建一个一维数组,初始化起点到其它所有节点的距离为无穷大,起点自己到自己的距离为0;

4、从起点开始找与起点相邻的其它节点的距离,将距离赋值到前面创建的一维数组,将此节点标记为已访问;

5、在一维数组中找一个没有访问过的节点,并且数值是最小的节点,将此节点作为起点重复第4步;

6、直至所有节点全部标记为已访问,程序执行结束;

二、代码

import sys
class Graph:
    #所有节点信息
    nodeAll = []
    #记录节点是否已访问 0否 1是
    visited = []
    #指定起始点到所有其他点的距离
    minDis = []
    #所有的边
    edge = []
    #节点数量
    nodeNum = 0
    #路径记录
    paths = []

    #构造方法,初始化整个无向图
    def __init__(self, nodeAll):
        self.nodeAll = nodeAll
        self.nodeNum = len(nodeAll)
        #初始化所有节点都未访问
        self.visited = [0] * self.nodeNum

        #创建一个二维数据,是浅拷贝,每一维的数组都是指向同一个内容地址,会有问题
        #test = [[0] * nodeNum] * nodeNum
        #test[0][1] = 1

        #创建一个二维数组,每次都会创建一个新的数组
        self.edge = [([0] * self.nodeNum) for i in range(self.nodeNum)]
        self.visited = [0] * self.nodeNum
        # 初始化指定起点到其它所有节点的距离无穷大
        self.minDis = [sys.maxsize] * self.nodeNum
        self.paths = [''] * self.nodeNum

    #添加边和权重
    def addEdge(self, v1, v2, value):
        self.edge[v1][v2] = value
        self.edge[v2][v1] = value

    #找没有访问过的节点的最小值的下标
    def getMinIndex(self):
        # 找到列表中没有访问过的最小值节点和下标
        minV, index = sys.maxsize, -1
        for i in range(self.nodeNum):
            if self.visited[i] == 0 and self.minDis[i] < minV:
                minV = self.minDis[i]
                index = i
        return index

    #迪杰斯特拉
    def dijkstra(self, start, end):
        #标记节点被访问过
        self.visited[start] = 1
        for i in range(self.nodeNum):
            # 如果当前节点没有被访问过,并且节点start到节点i的距离大于0
            if (self.visited[i] == 0 and self.edge[start][i]>0):
                #起始点到当前点的值+边的值
                newDis = self.minDis[start]+self.edge[start][i]
                if newDis < self.minDis[i]:
                    self.minDis[i] = newDis
                    self.paths[i] = self.paths[start] + '->' + self.nodeAll[i]
        #print(start, self.minDis)

        #找minDis中未被访问过的最小值节点的的下标
        index = self.getMinIndex()
        if index == -1:
            return
        self.dijkstra(index, end)



def test1():
    nodes = ['A', 'B', 'C', 'D', 'E', 'F']
    graph = Graph(nodes)
    graph.addEdge(0, 1, 7)
    graph.addEdge(0, 2, 9)
    graph.addEdge(0, 3, 11)
    graph.addEdge(1, 2, 8)
    graph.addEdge(1, 5, 20)
    graph.addEdge(2, 4, 6)
    graph.addEdge(3, 4, 3)
    graph.addEdge(4, 5, 1)
    # 初始化无向图
    print('=====初始化无向图=====')
    print(graph.edge)

    start, end = 0, 5
    graph.minDis[start] = 0
    graph.paths[start] = graph.nodeAll[start]
    graph.dijkstra(start, end)
    #print(graph.paths)
    print('节点%s到节点%s的最短路径是:%s,距离是%s' % (graph.nodeAll[start], graph.nodeAll[end], graph.paths[end], graph.minDis[end]))

def test2():
    nodes = ['V0', 'V1', 'V2', 'V3', 'V4', 'V5']
    graph = Graph(nodes)
    graph.addEdge(0, 1, 1)
    graph.addEdge(0, 2, 4)
    graph.addEdge(1, 2, 2)
    graph.addEdge(1, 3, 7)
    graph.addEdge(1, 4, 5)
    graph.addEdge(2, 4, 1)
    graph.addEdge(3, 4, 3)
    graph.addEdge(3, 5, 2)
    graph.addEdge(4, 5, 6)
    # 初始化无向图
    print('=====初始化无向图=====')
    print(graph.edge)
    start, end = 0, 5
    graph.minDis[start] = 0
    graph.paths[start] = graph.nodeAll[start]
    graph.dijkstra(start, end)
    print('节点%s到节点%s的最短路径是:%s,距离是%s' % (graph.nodeAll[start], graph.nodeAll[end], graph.paths[end],graph.minDis[end]))

#测试
if(__name__ == '__main__'):
    test2()



参考资料:

无向图的最短路径求解算法之——Dijkstra算法

Dijkstra 最短路径算法详解 无向图

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值