Python实现教程:平面最短路径算法

简介: Python实现教程:平面最短路径算法

在图论中,最短路径问题是寻找图中两个顶点之间的最短路径。在平面图中,这个问题尤其有趣,因为它可以应用于现实世界中的路网、机器人路径规划、游戏编程等领域。本文将通过几个Python代码示例,介绍几种常用的平面最短路径算法。

示例1:Dijkstra算法

Dijkstra算法是一种广泛应用于单源最短路径问题的算法。下面是一个简单的Python示例来实现该算法。

import heapq

def dijkstra(graph, start):
    distances = {vertex: float('infinity') for vertex in graph}
    distances[start] = 0
    priority_queue = [(0, start)]

    while priority_queue:
        current_distance, current_vertex = heapq.heappop(priority_queue)

        if current_distance > distances[current_vertex]:
            continue

        for neighbor, weight in graph[current_vertex].items():
            distance = current_distance + weight

            if distance < distances[neighbor]:
                distances[neighbor] = distance
                heapq.heappush(priority_queue, (distance, neighbor))

    return distances

# 图表示为邻接列表
graph = {
    'A': {'B': 1, 'C': 4},
    'B': {'A': 1, 'C': 2, 'D': 5},
    'C': {'A': 4, 'B': 2, 'D': 1},
    'D': {'B': 5, 'C': 1}
}

print(dijkstra(graph, 'A'))

在这个例子中,我们使用一个优先队列(通过Python的heapq模块实现)来保持距离最小的顶点的顺序。

示例2:A*算法

A*算法是一种在图中找到最短路径的启发式算法。它用一个估计函数来评价通过该节点到达终点的估计最短路径。

import heapq

class Node:
    def __init__(self, name, h_value):
        self.name = name
        self.h_value = h_value
        self.g_value = float('infinity')
        self.f_value = float('infinity')
        self.parent = None

    def __lt__(self, other):
        return self.f_value < other.f_value

def a_star(graph, start, end):
    open_set = []
    closed_set = set()
    start_node = graph[start]
    end_node = graph[end]
    start_node.g_value = 0
    start_node.f_value = start_node.h_value

    heapq.heappush(open_set, start_node)

    while open_set:
        current_node = heapq.heappop(open_set)
        closed_set.add(current_node)

        if current_node == end_node:
            path = []
            while current_node:
                path.append(current_node.name)
                current_node = current_node.parent
            return path[::-1]

        for child in current_node.children:
            if child in closed_set:
                continue
            tentative_g_value = current_node.g_value + current_node.children[child]

            if tentative_g_value < child.g_value:
                child.parent = current_node
                child.g_value = tentative_g_value
                child.f_value = child.g_value + child.h_value

                if child not in open_set:
                    heapq.heappush(open_set, child)

    return None

# 创建图
graph = {
    'A': Node('A', 10),
    'B': Node('B', 8),
    'C': Node('C', 5),
    'D': Node('D', 7),
    'E': Node('E', 3),
    'F': Node('F', 0),
}

# 定义邻接关系和启发函数值
graph['A'].children = {graph['B']: 3, graph['C']: 1}
graph['B'].children = {graph['A']: 3, graph['D']: 4}
graph['C'].children = {graph['A']: 1, graph['D']: 1, graph['E']: 2}
graph['D'].children = {graph['B']: 4, graph['C']: 1, graph['F']: 5}
graph['E'].children = {graph['C']: 2, graph['F']: 3}
graph['F'].children = {graph['D']: 5, graph['E']: 3}

path = a_star(graph, 'A', 'F')
print("Path from A to F:", path)

A*算法通过启发函数来优化搜索过程,通常用于路径规划和图形游戏编程。

示例3:Bellman-Ford算法

Bellman-Ford算法可以计算图中的单源最短路径,它也可以处理图中的边权重为负数的情况。

def bellman_ford(graph, start):
    distance = {vertex: float('infinity') for vertex in graph}
    distance[start] = 0

    for _ in range(len(graph) - 1):
        for vertex in graph:
            for neighbor in graph[vertex]:
                if distance[vertex] + graph[vertex][neighbor] < distance[neighbor]:
                    distance[neighbor] = distance[vertex] + graph[vertex][neighbor]

    # 检测负权重循环
    for vertex in graph:
        for neighbor in graph[vertex]:
            if distance[vertex] + graph[vertex][neighbor] < distance[neighbor]:
                print("Graph contains a negative weight cycle")
                return None

    return distance

graph = {
    'A': {'B': -1, 'C': 4},
    'B': {'C': 3, 'D': 2, 'E': 2},
    'C': {},
    'D': {'B': 1, 'C': 5},
    'E': {'D': -3}
}

print(bellman_ford(graph, 'A'))

Bellman-Ford算法的一个重要特点是它可以检测负权重的循环。

总结

在本文中,我们介绍了三种平面最短路径算法:Dijkstra算法、A*算法和Bellman-Ford算法,并提供了详细的Python代码示例。这些算法在不同的应用场景下各有优势,选择何种算法主要取决于图的特性、是否存在负权边以及是否需要启发式搜索。掌握这些算法,你将能够在各种需要路径规划的场景中找到高效的解决方案。


目录
相关文章
|
1天前
|
Python
Python基础教程: math库常用函数(1),Python这些高端技术只有你还不知道
Python基础教程: math库常用函数(1),Python这些高端技术只有你还不知道
|
4天前
|
存储 数据挖掘 数据处理
使用Python将数据表中的浮点数据转换为整数:详细教程与案例分析
使用Python将数据表中的浮点数据转换为整数:详细教程与案例分析
7 2
|
4天前
|
算法 搜索推荐 C语言
Python实现数据结构与算法
【5月更文挑战第13天】学习数据结构与算法能提升编程能力,解决复杂问题,助你面试成功。从选择资源(如《算法导论》、Coursera课程、LeetCode)到实践编码,逐步学习基本概念,通过Python实现栈、队列和快速排序。不断练习、理解原理,探索高级数据结构与算法,参与开源项目和算法竞赛,持续反思与实践,以提升技术能力。
6 0
|
4天前
|
机器学习/深度学习 算法 数据可视化
Python 数据结构和算法实用指南(四)(4)
Python 数据结构和算法实用指南(四)
10 1
|
4天前
|
机器学习/深度学习 存储 算法
Python 数据结构和算法实用指南(四)(3)
Python 数据结构和算法实用指南(四)
14 1
|
4天前
|
存储 算法 搜索推荐
Python 数据结构和算法实用指南(四)(2)
Python 数据结构和算法实用指南(四)
10 0
|
4天前
|
存储 算法 Serverless
Python 数据结构和算法实用指南(四)(1)
Python 数据结构和算法实用指南(四)
14 0
|
4天前
|
存储 算法 搜索推荐
Python 数据结构和算法实用指南(三)(4)
Python 数据结构和算法实用指南(三)
10 1
|
4天前
|
存储 搜索推荐 算法
Python 数据结构和算法实用指南(三)(3)
Python 数据结构和算法实用指南(三)
10 1
|
4天前
|
存储 算法 前端开发
Python 数据结构和算法实用指南(三)(2)
Python 数据结构和算法实用指南(三)
10 1