图遍历算法 dijkstra、floyd的python实现及注意事项

网上关于Dijkstra算法与Floyd算法的python实现各种各样,没有一个简单的介绍,下面用精简的python代码实现了这两种方法:

Dijkstra(迪杰斯特拉)可以求一个结点到其他结点的最短路径,且所有边不能有负值

Floyd(弗洛伊德)直接求出所有节点到其他结点的最短路径,边可以为负值,但不能有负权回路

Dijkstra算法核心步骤:

  1. 初始化两个集合,S集合初始时 只有当前要计算的节点,A->A,Q集合初始时为 除A以外所有结点
  2. 通过S中已经确定的点比较Q中点的直达距离与中转距离,并将所有更短路径保存在dist中
  3. 将最短路径结点加入S集合,并从Q中移除
def dijkstra(graph,s):
    if graph is None:
        return None
    # 记录已访问结点
    S = [s]
    # 记录未访问结点
    Q = [i for i in range(len(graph))]
    Q.remove(s)
    dist = [i for i in graph[s]]
    # 得到下个路径最近结点
    next = -1
    while Q:
        mid_distance = float("inf")
        # 用已知结点中转
        for i in S:
            # 得到未确定的最短路径结点
            for j in Q:
                if dist[i] + graph[i][j] < mid_distance:
                    mid_distance = dist[i] + graph[i][j]
                    dist[j] = mid_distance
                    next = j
        if next in Q:
            Q.remove(next)
            S.append(next)
        else:
            # 存在不可达顶点
            return dist

    return dist

Floyd算法核心步骤:

用每一个点当做中转点,发现最短路径

def floyd(graph):                                          
    dist = []                                              
    for i in range(len(graph)):                            
        sub_dist = []                                      
        for j in range(len(graph)):                        
            sub_dist.append(graph[i][j])                   
        dist.append(sub_dist[:])                           
    for i in range(len(graph)):                            
        for j in range(len(graph)):                        
            for k in range(len(graph)):                    
                if dist[j][i] + dist[i][k] < dist[j][k]:   
                    dist[j][k] = dist[j][i] + dist[i][k]   
    return dist                                            

代码输入为邻接矩阵,结点从0~n-1

测试用例

M = float("inf")         
graph = [[0, 4, M, 2, M],
         [4, 0, 4, 1, M],         
         [M, 4, 0, 1, M],         
         [2, 1, 1, 0, M],         
         [M, M, M, M, M]]
dist0 = dijkstra(graph,0)
dist = floyd(graph)         

 

你可能感兴趣的:(算法)