floyd_warshall_algorithm.sf 942 B

12345678910111213141516171819202122232425262728293031323334353637383940
  1. #!/usr/bin/ruby
  2. #
  3. ## https://rosettacode.org/wiki/Floyd-Warshall_algorithm
  4. #
  5. func floyd_warshall(n, edge) {
  6. var dist = n.of {|i| n.of { |j| i == j ? 0 : Inf }}
  7. var nxt = n.of { n.of(nil) }
  8. for u,v,w in edge {
  9. dist[u-1][v-1] = w
  10. nxt[u-1][v-1] = v-1
  11. }
  12. [^n] * 3 -> cartesian { |k, i, j|
  13. if (dist[i][j] > dist[i][k]+dist[k][j]) {
  14. dist[i][j] = dist[i][k]+dist[k][j]
  15. nxt[i][j] = nxt[i][k]
  16. }
  17. }
  18.  
  19. var summary = "pair dist path\n"
  20. for i,j (^n ~X ^n) {
  21. i==j && next
  22. var u = i
  23. var path = [u]
  24. while (u != j) {
  25. path << (u = nxt[u][j])
  26. }
  27. path.map!{|u| u+1 }.join!(" -> ")
  28. summary += ("%d -> %d  %4d  %s\n" % (i+1, j+1, dist[i][j], path))
  29. }
  30. return summary
  31. }
  32.  
  33. var n = 4
  34. var edge = [[1, 3, -2], [2, 1, 4], [2, 3, 3], [3, 4, 2], [4, 2, -1]]
  35. print floyd_warshall(n, edge)