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天前
|
算法 程序员 开发工具
GitHub上新!14个Python项目详细教程(附完整代码)
Python作为程序员的宠儿,越来越得到人们的关注,使用Python进行应用程序开发的也越来越多。 今天给小伙伴们分享的这份项目教程完整代码已上传至GitHub,你可以选择跟着这份教程一段一段的手敲出来这几个项目,也可以直接从GitHub上copy下来。
|
3天前
|
机器学习/深度学习 人工智能 算法
中草药识别系统Python+深度学习人工智能+TensorFlow+卷积神经网络算法模型
中草药识别系统Python+深度学习人工智能+TensorFlow+卷积神经网络算法模型
17 0
|
3天前
|
机器学习/深度学习 算法 数据安全/隐私保护
基于DCT变换和位平面分解的数字水印嵌入提取算法matlab仿真
这是一个关于数字水印算法的摘要:使用MATLAB2022a实现,结合DCT和位平面分解技术。算法先通过DCT变换将图像转至频域,随后利用位平面分解嵌入水印,确保在图像处理后仍能提取。核心程序包括水印嵌入和提取,以及性能分析部分,通过PSNR和NC指标评估水印在不同噪声条件下的鲁棒性。
|
3天前
|
C语言 Python
专为编程小白设计的Python零基础入门教程,GitHub星标破W
市面上大多数技术类的书籍都着重于一步步的构建系统的知识体系,并不是说这样就是不对的,但这样按部就班的学习注定了需要花费大量的时间用来掌握“基础知识”,或死记硬背,或慢慢理解。 然而世界不会迁就你,而是在步步紧逼的告诉你要赶紧学完,赶紧找工作,赶紧挣钱,这才是你生活的基础。 今天给小伙伴们带来了一份《编程小白的第一步Python书》,这本书是专为零基础小白设计的,不会告诉“先学C语言,会更好理解Python”这种狗屁道理。而是先带你掌握搭建项目所用到的最少得知识,再真实的项目搭建中实践自己的所学,逐渐的完善知识体系。
|
3天前
|
机器学习/深度学习 算法 数据挖掘
4小时学完!15年技术大牛用247个实战案例剖析的Python教程
今天给小伙伴们分享一份15年技术大牛用247个实战案例剖析的Python教程,这份教程全程彩图讲解,告别枯燥!60秒学会?个?例?,带你系统学习Python,从?门到?师。 涵盖了Python基础、Python字符串和正则、Python?件和?期、Python三?利器、Python绘图、Python之坑、Python第三?包、机器学习和深度学必知算法、Python实战、Pandas数据分析案例实战十大篇幅的精品案例教程
|
3天前
|
机器学习/深度学习 Web App开发 算法
Python 机器学习算法交易实用指南(一)(5)
Python 机器学习算法交易实用指南(一)
11 2
|
3天前
|
传感器 机器学习/深度学习 存储
Python 机器学习算法交易实用指南(一)(4)
Python 机器学习算法交易实用指南(一)
13 4
|
3天前
|
机器学习/深度学习 算法 API
Python 机器学习算法交易实用指南(一)(3)
Python 机器学习算法交易实用指南(一)
14 4
|
3天前
|
机器学习/深度学习 存储 算法
Python 机器学习算法交易实用指南(一)(2)
Python 机器学习算法交易实用指南(一)
9 2
|
3天前
|
机器学习/深度学习 算法 数据挖掘
Python 机器学习算法交易实用指南(一)(1)
Python 机器学习算法交易实用指南(一)
12 4
http://www.vxiaotou.com