Skip to content

Commit

Permalink
Merge branch 'floydWarshall' into directory-action
Browse files Browse the repository at this point in the history
  • Loading branch information
dlesnoff committed Jun 23, 2023
2 parents 9083271 + 6cb4b87 commit 11056ed
Showing 1 changed file with 65 additions and 0 deletions.
65 changes: 65 additions & 0 deletions dynamic_programming/floyd_warshall.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
# Floyd-Warshall
## From https://rosettacode.org/wiki/Floyd-Warshall_algorithm#Nim

import sequtils, strformat
{.push raises: [].}

type
Weight = tuple[src, dest, value: int]
Weights = seq[Weight]


#-------------------------------------------------------------------------------

proc printResult(dist: seq[seq[float]]; next: seq[seq[int]])
{.raises: [ValueError].} =

echo "pair dist path"
for i in 0..next.high:
for j in 0..next.high:
if i != j:
var u = i + 1
let v = j + 1
var path = fmt"{u} -> {v} {dist[i][j].toInt:2d} {u}"
while true:
u = next[u-1][v-1]
path &= fmt" -> {u}"
if u == v: break
echo path


#-------------------------------------------------------------------------------

proc floydWarshall(weights: Weights; numVertices: Positive)
{.raises: [ValueError].} =

var dist = repeat(repeat(Inf, numVertices), numVertices)
for w in weights:
dist[w.src - 1][w.dest - 1] = w.value.toFloat

var next = repeat(newSeq[int](numVertices), numVertices)
for i in 0..<numVertices:
for j in 0..<numVertices:
if i != j:
next[i][j] = j + 1

for k in 0..<numVertices:
for i in 0..<numVertices:
for j in 0..<numVertices:
if dist[i][j] > dist[i][k] + dist[k][j]:
dist[i][j] = dist[i][k] + dist[k][j]
next[i][j] = next[i][k]

printResult(dist, next)


when isMainModule:
let weights: Weights = @[
(1, 3, -2),
(2, 1, 4),
(2, 3, 3),
(3, 4, 2),
(4, 2, -1)]
let numVertices = 4

floydWarshall(weights, numVertices)

0 comments on commit 11056ed

Please sign in to comment.