Floyd-Warshall算法求解所有结点对的最短路径问题Java和Python实现

18 篇文章 1 订阅
8 篇文章 8 订阅
本文介绍了一种用于解决所有结点对之间最短路径问题的高效算法——Floyd-Warshall算法,并通过Java和Python代码实现了该算法。与Bellman-Ford算法和Dijkstra算法相比,该算法基于邻接矩阵,适用于密集图。
摘要由CSDN通过智能技术生成

其实求解所有结点对之间的最短路径问题完全可以用调用|V|次Bellman-Ford算法或Dijkstra算法来实现,但是那样肯定效率会比较低下。与前面两个算法基于邻接链表不同,本文所要说的Floyd-Warshall算法是基于邻接矩阵的,当然也可以用邻接链表来实现。

假设i与j是图中的两个结点,那么它们之间至多经过k个结点的最短路径代价肯定不小于至多经过k+1个结点的最短路径的代价。由此对于所有结点对最短路径问题我们有如下递归解:

《算法导论》书中给出的算法伪代码如下:

而下面是一个运用Floyd-Warshall算法求解的过程的一个例子,其中左边矩阵记录的是当前的最短路径值,右边矩阵则是当前的前驱节点。

由此用Java代码实现如下

 

package Floyed_Warshall;

import java.util.ArrayList;   
import java.util.List;   
  
  
public class Main {   
  
    private static int INF=Integer.MAX_VALUE;   
    private int[][] dist;      
    private List<Integer> result=new ArrayList<>();   
       
    public static void main(String[] args) {   
        Main graph=new Main(5);   
        int[][] matrix={   
                {0,3,8,INF,-4},   
                {INF,0,INF,1,7},   
                {INF,4,0,INF,INF},   
                {2,INF,-5,0,INF},   
                {INF,INF,INF,6,0},   
        };        
                
	      graph.floyd(matrix);
	      System.out.println("============最短路径长度============");
	      for(int i = 0;i<graph.dist.length;i++){
	    	  for(int j = 0;j<graph.dist[i].length;j++)
	    		  System.out.print(graph.dist[i][j]+"  ");
	    	  System.out.println();
	      }
	      
        
    }   
  
    public void floyd(int[][] matrix){   
        int size=matrix.length;   
           
        for(int i=0;i< size;i++){   
            for(int j=0;j< size;j++){                  
                dist[i][j]=matrix[i][j];   
            }   
        }   
        for(int k=0;k< size;k++){   
            for(int i=0;i< size;i++){   
                for(int j=0;j< size;j++){   
                    if(dist[i][k]!=INF&&   
                        dist[k][j]!=INF&&   
                        dist[i][k]+dist[k][j]< dist[i][j]){
                        dist[i][j]=dist[i][k]+dist[k][j];                            
                    }   
                }   
            }   
        }   
           
    }   
       
    public Main(int size){   
        
        this.dist=new int[size][size];   
    }   
}  

运行结果截图如下

 


下面是一个Python版本的代码

import numpy as np


"""
    使用Floyed-Warshall算法计算最短路径距离
    输入是一个初始的距离矩阵
    @author: sdu_brz
    @date: 2019/02/27
"""

def floyed(distance0):
    """
    计算所有顶点对的最短路径距离
    :param distance0: 初始的距离矩阵
    :return: 保存了最短路径长度的矩阵
    """
    data_shape = distance0.shape
    n = data_shape[0]

    distance = distance0.copy()

    for index in range(0, n):
        for i in range(0, n):
            for j in range(0, n):
                if distance[i, index] < float('inf') and distance[index, j] < float('inf') and distance[i, index]+distance[index, j]<distance[i, j]:
                    distance[i, j] = distance[i, index] + distance[index, j]

    return distance


def test():
    M = np.array([[0, 3, 8, float('inf'), -4],
                  [float('inf'), 0, float('inf'), 1, 7],
                  [float('inf'), 4, 0, float('inf'), float('inf')],
                  [2, float('inf'), -5, 0, float('inf')],
                  [float('inf'), float('inf'), float('inf'), 6, 0]])
    distance = floyed(M)
    print(distance)


if __name__ == '__main__':
    test()

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值