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代码示例。这些算法在不同的应用场景下各有优势,选择何种算法主要取决于图的特性、是否存在负权边以及是否需要启发式搜索。掌握这些算法,你将能够在各种需要路径规划的场景中找到高效的解决方案。


目录
相关文章
|
4天前
|
机器学习/深度学习 算法 搜索推荐
从理论到实践,Python算法复杂度分析一站式教程,助你轻松驾驭大数据挑战!
【10月更文挑战第4天】在大数据时代,算法效率至关重要。本文从理论入手,介绍时间复杂度和空间复杂度两个核心概念,并通过冒泡排序和快速排序的Python实现详细分析其复杂度。冒泡排序的时间复杂度为O(n^2),空间复杂度为O(1);快速排序平均时间复杂度为O(n log n),空间复杂度为O(log n)。文章还介绍了算法选择、分而治之及空间换时间等优化策略,帮助你在大数据挑战中游刃有余。
19 4
|
4天前
|
机器学习/深度学习 缓存 算法
Python算法设计中的时间复杂度与空间复杂度,你真的理解对了吗?
【10月更文挑战第4天】在Python编程中,算法的设计与优化至关重要,尤其在数据处理、科学计算及机器学习领域。本文探讨了评估算法性能的核心指标——时间复杂度和空间复杂度。通过详细解释两者的概念,并提供快速排序和字符串反转的示例代码,帮助读者深入理解这些概念。同时,文章还讨论了如何在实际应用中平衡时间和空间复杂度,以实现最优性能。
21 6
|
2天前
|
存储 机器学习/深度学习 算法
蓝桥杯练习题(三):Python组之算法训练提高综合五十题
蓝桥杯Python编程练习题的集合,涵盖了从基础到提高的多个算法题目及其解答。
11 3
蓝桥杯练习题(三):Python组之算法训练提高综合五十题
|
9天前
|
监控 数据可视化 搜索推荐
【Python篇】matplotlib超详细教程-由入门到精通(下篇)2
【Python篇】matplotlib超详细教程-由入门到精通(下篇)
22 8
|
7天前
|
缓存 测试技术 Apache
告别卡顿!Python性能测试实战教程,JMeter&Locust带你秒懂性能优化💡
【10月更文挑战第1天】告别卡顿!Python性能测试实战教程,JMeter&Locust带你秒懂性能优化💡
30 4
|
7天前
|
算法 安全 Go
RSA加密算法详解与Python和Go实现
RSA加密算法详解与Python和Go实现
11 1
|
7天前
|
存储 算法 安全
Python 加密算法详解与应用
Python 加密算法详解与应用
9 1
|
9天前
|
编解码 数据可视化 IDE
【Python篇】matplotlib超详细教程-由入门到精通(下篇)1
【Python篇】matplotlib超详细教程-由入门到精通(下篇)
24 3
|
1天前
|
算法 前端开发 数据处理
小白学python-深入解析一位字符判定算法
小白学python-深入解析一位字符判定算法
10 0
|
5天前
|
搜索推荐 算法 Shell
Python 金典的“八大排序算法”
Python 金典的“八大排序算法”
8 0