Skip to content

Instantly share code, notes, and snippets.

@loganlinn
Last active March 21, 2022 15:01
Show Gist options
  • Save loganlinn/5437067 to your computer and use it in GitHub Desktop.
Save loganlinn/5437067 to your computer and use it in GitHub Desktop.
Dijkstra's Algorithm in Clojure
(defn neighbors
"Returns n's neighbors, optionally filtered if unvisited"
([g n] (get g n {}))
([g n uv] (select-keys (neighbors g n) uv)))
(defn update-costs
"Returns "
[g costs curr unvisited]
(reduce
(fn [c [nbr nbr-cost]] (update-in c [nbr] (partial min (+ (c curr) nbr-cost))))
costs
(neighbors g curr unvisited)))
(defn dijkstra
"Returns a mapping of nodes to minimum cost from src using Dijkstra algorithm.
Graph is a mapping of nodes to map of neighboring nodes and associated cost.
Optionally, specify :target node to return only the min price for target"
[g src & {:keys [target]}]
(loop [costs (assoc (zipmap (keys g) (repeat inf)) src 0)
curr src
unvisited (disj (apply hash-set (keys g)) src)]
(if (or (empty? unvisited) (= inf (costs curr)))
costs
(let [costs' (update-costs g costs curr unvisited)
curr' (first (sort-by costs' unvisited))]
(if (= target curr)
(costs' target)
(recur costs'
curr'
(disj unvisited curr')))))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment