返回

黑客不可自:最短路径算法和Python实现

IOS

从入门到精通:最短路径算法
无论在现实生活中还是计算机领域,最短路径算法的应用均极其广泛。最为著名的应用在于著名的网络公司谷歌地图服务中,谷歌地图通过最短路径算法为其使用者规划最优的路径。而除了在导航软件中的应用,最短路径算法还被广泛运于项目规划、物流配送、乃至机器人路径规划。

广度优先遍历:入门级最短路径算法

在无权图中,我们能够运先广度优先遍历,即在计算机算法术语中,我们可以采用广度优先遍历这一种极其入门级的算法进行最短路径的求解。

广度优先遍历是一种非常直观且容易理解的算法,我们可以想象我们在图中开始进行广度优先遍历,我们从起点开始进行访问,访问每一个可能的方向,而在访问每一个可能的方向的同时,我们将广度优先遍历的边界尽可能扩大的广度,直到我们到达图的边界,或者到达终止点。

广度优先遍历算法的伪代码实现:

 def shortest_path(graph, source):
    # 初始化一个队列,包含我们准备访问的点
    queue = [source]
    # 初始化一个列表,包含我们已经访问过的点
    visited = [source]
    # 初始化一个列表,包含我们到目前为止已访问过的最短路径
    shortest_path = 0
    # 循环直到队列为空
    while queue:
        # 从队列中取出一个点
        current_node = queue.pop()
        # 遍历当前点的邻接点
        for neighbor in current_node.neighbors:
            # 如果邻接点没有被访问过
            if neighbor not in visited:
                # 将邻接点添加到队列中
                queue.append(neighbor)
                # 更新最短路径
                shortest_path += graph[current_node][neighbor]
                # 如果邻接点是终止点
                if neighbor == graph.destination:
                    return shortest_path
        # 标记当前点为已访问过
        visited.append(current_node)
    # 如果队列为空,则没有最短路径
    return None

Dijkstra算法:适用于带权图的最短路径算法

广度优先遍历算法的优劣立非常明显,它适用于图中所有边权都相同的无权图,而对于那些边权不相同、图中包含权重的图,我们则需要适用Djiikstra算法。

Djiikstra算法,利用了数据的稀疏性,并构建一个小根堆数据结果,通过迭代的方式进行访问。在Djiikstra算法中,我们将使用一个队列,即小根堆,来存储我们需要访问的点。我们将起点放入队列中,并将其权重设置为0.

Djiikstra算法的伪代码实现:

def dijkstra(graph, source):
    # 初始化一个小根堆,包含我们准备访问的点
    queue = PriorityQueue()
    queue.push(source, 0)
    # 初始化一个列表,包含我们已经访问过的点
    visited = [source]
    # 初始化一个列表,包含我们到目前为止已访问过的最短路径
    shortest_path = 0
    # 循环直到队列为空
    while queue:
        # 从队列中取出一个点
        current_node = queue.pop()
        # 遍历当前点的邻接点
        for neighbor in current_node.neighbors:
            # 如果邻接点没有被访问过
            if neighbor not in visited:
                # 计算当前点到邻接点的权重
                weight = graph[current_node][neighbor]
                # 将邻接点放入队列中
                queue.push(neighbor, weight)
                # 更新最短路径
                shortest_path += weight
                # 如果邻接点是终止点
                if neighbor == graph.destination:
                    return shortest_path
        # 标记当前点为已访问过
        visited.append(current_node)
    # 如果队列为空,则没有最短路径
    return None

最后进行一个简单的回顾,我们主要学习了广度优先遍历和Djiikstra算法,以及它们的Python实现。广度优先遍历适用于无权图,而Djiikstra适用于带权图。这两种最短路径算法都是非常实