Created
November 2, 2017 14:59
-
-
Save tmountain/0a5d39559e67d4f4dde58bb8ffa7370b to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(defn A* | |
"Finds a path between start and goal inside the graph described by edges | |
(a map of edge to distance); estimate is an heuristic for the actual | |
distance. Accepts a named option: :monotonic (default to true). | |
Returns the path if found or nil." | |
[edges estimate start goal & {mono :monotonic :or {mono true}}] | |
(let [f (memoize #(estimate % goal)) ; unsure the memoization is worthy | |
neighbours (reduce (fn [m [a b]] (assoc m a (conj (m a #{}) b))) | |
{} (keys edges))] | |
(loop [q (priority-map start (f start)) | |
preds {} | |
shortest {start 0} | |
done #{}] | |
(when-let [[x hx] (peek q)] | |
(if (= goal x) | |
(reverse (take-while identity (iterate preds goal))) | |
(let [dx (- hx (f x)) | |
bn (for [n (remove done (neighbours x)) | |
:let [hn (+ dx (edges [x n]) (f n)) | |
sn (shortest n Double/POSITIVE_INFINITY)] | |
:when (< hn sn)] | |
[n hn])] | |
(recur (into (pop q) bn) | |
(into preds (for [[n] bn] [n x])) | |
(into shortest bn) | |
(if mono (conj done x) done)))))))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment