python最短路径算法及优化思路

  1. Dijkstra算法
  • 算法思路: 从起点出发,每次选择距离起点最近的未访问节点加入已访问集合,然后更新与其相邻的节点的距离
  • 优化思路: 堆优化, 预处理相邻节点, 双向Dijkstra
  • 代码示例:
import heapq

def dijkstra(graph, start):
    distances = {node: float('inf') for node in graph}
    distances[start] = 0
    heap = [(0, start)]
    while heap:
        (dist, current_node) = heapq.heappop(heap)
        if dist > distances[current_node]:
            continue
        for neighbor, weight in graph[current_node].items():
            distance = dist + weight
            if distance < distances[neighbor]:
                distances[neighbor] = distance
                heapq.heappush(heap, (distance, neighbor))
    return distances

  1. Bellman-Ford算法
  • 算法思路: 从源点出发,依次进行n-1轮更新,每次更新当前节点的所有邻居的距离
  • 优化思路: 提前退出, 差分约束系统求解
  • 代码示例:
def bellman_ford(graph, start):
    distances = {node: float('inf') for node in graph}
    distances[start] = 0
    for _ in range(len(graph) - 1):
        for node in graph:
            for neighbor, weight in graph[node].items():
                if distances[node] + weight < distances[neighbor]:
                    distances[neighbor] = distances[node] + weight
    return distances

  1. Floyd-Warshall算法
  • 算法思路: 以中间节点为枚举变量,更新任意两个节点之间的距离
  • 优化思路: 利用矩阵运算加速
  • 代码示例:
def floyd_warshall(graph):
    distances = graph
    for k in graph:
        for i in graph:
            for j in graph:
                distances[i][j] = min(distances[i][j], distances[i][k] + distances[k][j])
    return distances

  1. A*算法
  • 算法思路: 综合考虑路径长度和启发函数值,每次选取最小值作为下一个搜索节点
  • 优化思路: 启发函数优化(如曼哈顿距离), 双向A*
  • 代码示例:
import heapq
from math import sqrt

def euclidean_distance(a, b):
    return sqrt((a[0] - b[0]) ** 2 + (a[1] - b[1]) ** 2)

def a_star(graph, start, end):
    open_set = set([start])
    closed_set = set()
    g = {node: float('inf') for node in graph}
    g[start] = 0
    parents = {node: None for node in graph}

    f = {node: euclidean_distance(graph[node], graph[end]) for node in graph}

    while open_set:
        current = min(open_set, key=lambda node: f[node])
        if current == end:
            path = []
            while current:
                path.append(current)
                current = parents[current]
            return list(reversed(path))

        open_set.remove(current)
        closed_set.add(current)

        for neighbor in graph[current]:
            if neighbor in closed_set:
                continue

            tentative_g_score = g[current] + euclidean_distance(graph[current], graph[neighbor])

            if neighbor not in open_set:
                open_set.add(neighbor)
            elif tentative_g_score >= g[neighbor]:
                continue

            parents[neighbor] = current
            g[neighbor] = tentative_g_score
            f[neighbor] = g[neighbor] + euclidean_distance(graph[neighbor], graph[end])

    return None

你可能感兴趣的:(算法,python,开发语言)