floyd.go 1.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. package main
  2. import (
  3. "fmt"
  4. "math"
  5. )
  6. type graph struct {
  7. to int
  8. wt float64
  9. }
  10. func floydWarshall(g [][]graph) ([][]float64, [][][]int) {
  11. path := make([][][]int, len(g))
  12. dist := make([][]float64, len(g))
  13. for i := range dist {
  14. pi := make([][]int, len(g))
  15. di := make([]float64, len(g))
  16. for j := range di {
  17. di[j] = math.Inf(1)
  18. pi[j] = []int{}
  19. }
  20. di[i] = 0
  21. dist[i] = di
  22. path[i] = pi
  23. }
  24. for u, graphs := range g {
  25. for _, v := range graphs {
  26. dist[u][v.to] = v.wt
  27. path[u][v.to] = []int{u, v.to}
  28. }
  29. }
  30. for k, dk := range dist {
  31. pk := path[k]
  32. for i, di := range dist {
  33. pi := path[i]
  34. for j, dij := range di {
  35. if d := di[k] + dk[j]; dij > d {
  36. di[j] = d
  37. pi[j] = append(pi[k], pk[j][1:]...)
  38. }
  39. }
  40. }
  41. }
  42. return dist, path
  43. }
  44. func main() {
  45. gra := [][]graph{
  46. 1: {{2, 3}, {3, 8}, {5, -4}},
  47. 2: {{4, 1}, {5, 7}},
  48. 3: {{2, 4}},
  49. 4: {{1, 2}, {3, -5}},
  50. 5: {{4, 6}},
  51. }
  52. dist, path := floydWarshall(gra)
  53. //dist[][] will be the output matrix that will finally
  54. //have the shortest distances between every pair of vertices
  55. for i, di := range dist {
  56. pi := path[i]
  57. s := ""
  58. for j, pij := range pi {
  59. if j > 0 {
  60. s += " "
  61. }
  62. s += fmt.Sprintf("%4g %-12s", di[j], fmt.Sprint(pij))
  63. }
  64. fmt.Printf("[%s]\n", s)
  65. }
  66. }