迪杰斯特拉算法

迪杰斯特拉算法是一种贪心算法,先将所有的地点距离默认为无限,然后从起点出发,每次走距离起点最近的点并更新从该"最近的点"到附近所有点的距离,如果之前经历过的某个点从这里出发到那里会更近(比如例子里面的点8,0-1-2-8比0-7-8更近),更换为最近时的距离(将0到8的距离由15改为14),直到终点
因为每次选择最近的,所以到达终点时也是最近的
以此方法求得最短距离

迪杰斯特拉算法测试用

import numpy as np


def Dijkstra(start, end, v, edges, d, get_road=False):
    # 由get_road决定是否返回路径
    # 出于简便,v中的点从0开始,到len(v-1)结束
    # 如果问题变更,从地点1到地点2,要把地名映射成为数字
    passed = np.zeros(len(v))
    # 该数组记录已经通过的点,比如通过了点0,就把passed[0]改为1
    distance = np.full(len(v), float('inf'))
    # 默认距离全部改成无限(如果是java等语言没有办法表现为无限,就用一个足够大的final常量来表示)
    distance[start] = 0
    # 起点距离为0
    road = np.full(len(v), -1)
    # 这个数组用于记录路径,如果只是需要举例不需要路径,该数组无用
    # 若需要路径,该数组记录的是到达某个点为最短距离时,该点的上一个点
    # 举例:从起点0到点1最短距离是4,此时1的上一个点是0,则road[1]=0
    curr = start
    # 从start出发
    while curr != end:
        # 当到达终点时停止
        temp = float('inf')
        for i in range(len(distance)):
            if (temp > distance[i]) & (passed[i] == 0):
                temp = distance[i]
                curr = i
        passed[curr] = 1
        for i in range(len(edges)):
            (x, y) = edges[i]
            if x == curr:
                distance[y] = min(d[i] + distance[curr], distance[y])
                if get_road & (distance[y] == d[i] + distance[curr]):
                    road[y] = curr
            elif y == curr:
                distance[x] = min(d[i] + distance[curr], distance[x])
                if get_road & (distance[x] == d[i] + distance[curr]):
                    road[x] = curr
    print(distance)
    if get_road:
        print_road(road, start, end)


def print_road(road, start, end):
    s = []
    curr = end
    while curr != start:
        s.append(curr)
        curr = road[curr]
    s.append(curr)
    s.reverse()
    print(s)


if __name__ == "__main__":
    # 测试用例:
    V = {0, 1, 2, 3, 4, 5, 6, 7, 8}
    E = [(0, 1), (0, 7), (1, 7), (7, 8), (1, 2), (6, 7), (6, 8), (5, 6), (2, 8),
         (2, 5), (2, 3), (3, 5), (3, 4), (4, 5)]
    D = [4, 8, 11, 7, 8, 1, 6, 2, 2, 4, 7, 14, 9, 10]

    # 起点 0, 终点 4
    Dijkstra(start=0, end=4, v=V, edges=E, d=D, get_road=True)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值