Floyd算法

176 阅读1分钟

是一种利用动态规划的思想,寻找有向加权图中,任意两点之间的最短路径

时间复杂度O(N^3) 空间复杂度O(N^2)

golang实现

const MaxDistance = math.MaxInt32

func floyd(n int, weight []int, edges [][]int) ([][]int, [][]int) {
   distance := make([][]int, n)
   paths := make([][]int, n)
   for i := 0; i < n; i++ {
      distance[i] = make([]int, n)
      paths[i] = make([]int, n)
      for j := 0; j < n; j++ {
         if i == j {
            distance[i][j] = 0
         } else {
            distance[i][j] = MaxDistance
         }
         paths[i][j] = -1
      }
   }

   for i, edge := range edges {
      u := edge[0]
      v := edge[1]
      distance[u][v] = weight[i]
   }

   for k := 0; k < n; k++ {
      for i := 0; i < n; i++ {
         for j := 0; j < n; j++ {
            if distance[i][k]+distance[k][j] < distance[i][j] {
               distance[i][j] = distance[i][k] + distance[k][j]
               paths[i][j] = k
            }
         }
      }
   }
   return distance, paths
}

func main() {
   edges := [][]int{[]int{0, 1}, []int{0, 3}, []int{1, 2}, []int{1, 3}, []int{2, 0}, []int{2, 1}, []int{2, 3}, []int{3, 2}}
   weight := []int{5, 7, 4, 2, 3, 3, 2, 1}
   n := 4
   distance, paths := floyd(n, weight, edges)

   fmt.Println(distance)
   fmt.Println(paths)

   for i := 0; i < n; i++ {
      for j := 0; j < n; j++ {
         path := strconv.Itoa(i)
         tmp := paths[i][j]
         for tmp != -1 {
            path += "-->" + strconv.Itoa(tmp)
            tmp = paths[tmp][j]
         }
         path += "-->" + strconv.Itoa(j)

         fmt.Println("从" + strconv.Itoa(i) + "--->" + strconv.Itoa(j) + "的距离为" + strconv.Itoa(distance[i][j]) + ",路径为" + path)
      }
   }
}

参考文章: juejin.cn/post/684490…