Algoritmo de Python-algoritmo de Dijkstra

Esta vez aprenderemos sobre el algoritmo de Dijkstra que combina gráficos y texto

El algoritmo de Dijkstra consta de 4 pasos

(1) Encuentre el nodo más barato, el nodo al que se puede llegar en el menor tiempo
(2) Para los vecinos del nodo, verifique si hay un camino más corto hacia ellos, si lo hay, actualice su costo
(3) Repita esto El proceso hasta que haya hecho esto para cada nodo en el gráfico
(4) Calcule la ruta final

el termino:

El algoritmo de Dijkstra se utiliza para gráficos con números asociados en cada borde. Estos números se denominan pesos. Los gráficos con pesos se denominan gráficos ponderados y los gráficos sin pesos se denominan gráficos no ponderados. (gráfico no ponderado)

Para calcular la distancia más corta de un gráfico no ponderado, se puede utilizar la búsqueda primero en amplitud o el algoritmo de Dijkstra, pero puede haber "bucles"

En el algoritmo de Dijkstra, el camino alrededor del círculo no puede ser el camino más corto

El algoritmo de Dijkstra solo se aplica a gráficos acíclicos dirigidos

El camino más corto no se refiere necesariamente a la distancia física, también puede ser para minimizar una determinada métrica

Lado negativo:

El uso del algoritmo de Dijkstra para gráficos con pesos negativos generará una ruta incorrecta, por lo que si hay bordes de peso negativos, no puede usar el algoritmo de Dijkstra

En un gráfico con bordes de peso negativos, para encontrar el camino más corto, se puede utilizar otro algoritmo: el algoritmo de Bellman-Ford

Caso

Encuentre el costo más pequeño de principio a fin
Inserte la descripción de la imagen aquí

graph = {
    
    }      # 创建一个散列表

# 嵌套散列表去包含起点到各个的节点以及权重
graph["start"] = {
    
    }
graph["start"]["a"] = 6
graph["start"]["b"] = 2

graph["a"] = {
    
    }
graph["a"]["fin"] = 1

graph["b"] = {
    
    }
graph["b"]["a"] = 3
graph["b"]["fin"] = 5

graph["fin"] = {
    
    }       # 终点没有邻居

# 节点的开销指的是从起点出发前往该节点需要多长时间
infinity = float("inf")     # 创建一个开销表
costs = {
    
    }
costs["a"] = 6
costs["b"] = 2
costs["fin"] = infinity

parents = {
    
    }        # 创建一个存储父节点的散列表
parents["a"] = "start"
parents["b"] = "start"
parents["fin"] = None

processed = []      # 创建一个数组,用于记录处理过的节点

def find_lowest_cost_node(costs):
    lowest_cost = float("inf")
    lowest_cost_node = None
    for node in costs:      # 遍历所有的节点
        cost = costs[node]
        if cost < lowest_cost and node not in processed:        # 如果当前的节点的开销更低且为处理过
            lowest_cost = cost      # 将其视为开销最低的节点
            lowest_cost_node = node
    return lowest_cost_node

node = find_lowest_cost_node(costs)     # 在未处理过的节点中找到开销最小的节点
while node is not None:
    cost = costs[node]
    neighbors = graph[node]
    for n in neighbors.keys():      # 遍历当前节点的所有邻居      
        new_cost = cost + neighbors[n]
        if costs[n] > new_cost:     # 如果当前节点前往该邻居更近     
            costs[n] = new_cost     #   更新该邻居的开销
            parents[n] = node       #  同时将该节点的父节点设置为当前的节点
    processed.append(node)      # 将当前的节点标记为处理过的
    node = find_lowest_cost_node(costs)
print(f"起点到终点的最小开销为:{costs['fin']}")        # 找出接下来要处理的节点并循环

Supongo que te gusta

Origin blog.csdn.net/Layfolk_XK/article/details/108452395
Recomendado
Clasificación