狄克斯特拉算法之Python实现(个人独创)易于理解和扩展。

狄克斯特拉算法的基础关系模型如下:

它解决的是从起点到终点的最佳路线问题。

如果把上图的数字代表耗时,那就是要找到耗时最短的路径。

由于本人较懒,先将源代码给出来,之后有时间再解释代码的意思。

下面代码针对的关系模型如下:

# 数据关系模型用字典嵌套字典的形式来表达。
graph = {
    'start': {'a': 3, 'b': 6, 'c': 4},
    'a': {"d": 8},
    "b": {'d': 10, "e": 5},
    'c': {"e": 6},
    "d": {"f": 2, 'g': 7, "e": -2},
    'e': {'g': 3, 'h': 6},
    'f': {'fina': 9},
    'g': {'fina': 8},
    "h": {'fina': 7},
    'fina': {}
}
# 定义耗时的字典。
costs = {}
costs["start"] = 0

# 存储父节点的字典。
parents = {}


def find_lowest_cost_node(node, node_cost):
    """找到start下一级节点,并更新costs里的值,和parents里面的值"""
    # 获取当前节点的所有下一级节点和其权重值。
    for next_node in graph[node].keys():
        # 判断next_node是否在costs里存在。
        if next_node in costs.keys():
            if graph[node][next_node] + node_cost < costs[next_node]:
                costs[next_node] = graph[node][next_node] + node_cost
                parents[next_node] = node
            else:
                continue
        else:
            costs[next_node] = graph[node][next_node] + node_cost
            parents[next_node] = node


def find_path(node):
    """利用递归算法,获取parents里面的父节点"""
    super_node = parents[node]
    print(super_node)
    if super_node is not 'start':
        super_node= find_path(super_node)
        return super_node
    else:
        return 'start'


def main():
    """主函数部分"""
    # 给出起点的节点
    node = "start"
    
    while node is not "fina":
        # 找到costs里面最小值的键,将其从costs里面剔除
        node = min(costs, key=costs.get)
        node_cost = costs[node]
        del costs[node]
        if graph[node]:
            find_lowest_cost_node(node, node_cost)
        else:
            # 如果没有下一级节点,就继续找下一个最小的节点
            continue
            
    # parents里面打印出来的,就可以从终点开始追溯其父节点,最终就会追溯到起点。
    print(parents)

    # 获取父节点。并打印出来。
    finally_node = 'fina'
    print(finally_node)
    find_path(finally_node)


if __name__ == '__main__':
    main()

大体的思路如下:

每次获取costs里面最小的节点,并把最小节点从costs里面删除,然后找到该节点的下一级节点。

如果下一级节点已经在costs里存在,则需要对值进行比较。

如果经由该节点达到下一级节点的值要小,就需要更新下一级节点的cost,并更新其父节点为当前节点。

如果找到了最终的节点‘fina’,并且其cost在costs里面是最小的。就结束循环。

程序运行的结果如下:

猜你喜欢

转载自blog.csdn.net/weixin_42489971/article/details/81357587