Pythonアルゴリズム-Dijkstraアルゴリズム

今回は、グラフィックとテキストを組み合わせたDijkstraのアルゴリズムについて学びます。

Dijkstraのアルゴリズムは4つのステップで構成されています

(1)最も安いノード、最短時間で到達できるノードを見つける
(2)ノードの隣接ノードについて、それらへのより短いパスがあるかどうかを確認し、ある場合はそのコストを更新します
(3)これを繰り返しますグラフ内のノードごとにこれを実行するまでのプロセス
(4)最終パスを計算します

用語:

Dijkstraアルゴリズムは、各エッジに番号が関連付けられているグラフに使用されます。これらの番号は重みと呼ばれます。重みのあるグラフは重み付きグラフと呼ばれ、重みのないグラフは重みなしグラフと呼ばれます。 (重み付けされていないグラフ)

重み付けされていないグラフの最短距離を計算するには、幅優先検索またはDijkstraのアルゴリズムのいずれかを使用できますが、「ループ」が存在する場合があります。

Dijkstraのアルゴリズムでは、円の周りのパスを最短パスにすることはできません

Dijkstraのアルゴリズムは、有向非周期グラフにのみ適用されます

最短パスは必ずしも物理的な距離を指すわけではなく、特定のメトリックを最小化することもあります

マイナス面:

負の重みを持つグラフにDijkstraのアルゴリズムを使用すると、間違ったパスが作成されるため、負の重みのエッジがある場合、Dijkstraのアルゴリズムを使用することはできません。

負の重みエッジを持つグラフでは、最短パスを見つけるために、別のアルゴリズムを使用できます-ベルマン-フォードアルゴリズム(ベルマン-フォードアルゴリズム)

場合

最初から最後まで最小のコストを見つける
ここに写真の説明を挿入

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']}")        # 找出接下来要处理的节点并循环

おすすめ

転載: blog.csdn.net/Layfolk_XK/article/details/108452395