Skip to content

Instantly share code, notes, and snippets.

@reborg
Last active August 17, 2018 00:59
Show Gist options
  • Save reborg/c3372428c6ccd7d93289fb7a3a9ec393 to your computer and use it in GitHub Desktop.
Save reborg/c3372428c6ccd7d93289fb7a3a9ec393 to your computer and use it in GitHub Desktop.
Clojure implementation of the A* path finding algorithm
;; This is the Wikipedia entry example encoded graph.
(def graph {:orig [{:a 1.5 :d 2} 0]
:a [{:orig 1.5 :b 2} 4]
:b [{:a 2 :c 3} 2]
:c [{:b 3 :dest 4} 4]
:dest [{:c 4 :e 2} 0]
:e [{:dest 2 :d 3} 2]
:d [{:orig 2 :e 3} 4.5]})
(defn a* [graph orig dest]
(letfn [(discover [node path visited]
(let [walkable (first (graph node))
seen (map last (keys visited))]
(reduce dissoc walkable (conj seen (last path)))))
(walk [visited]
(let [[[score node :as current] [path total-distance]] (first visited)]
(if (= dest node)
(conj path dest)
(recur
(reduce-kv
(fn [m neighbour partial-distance]
(let [d (+ total-distance partial-distance)
score (+ d (last (graph neighbour)))]
(assoc m [score neighbour] [(conj path node) d])))
(dissoc visited current)
(discover node path visited))))))]
(walk (sorted-map-by compare [0 orig] [[] 0]))))
(a* graph :orig :dest)
;; [:orig :d :e :dest]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment