I've just implemented Dijkstra's algorithm, and as far as I can tell, it works.
However, I'm a little concerned at the efficiency. Specifically, I am using sorted sets, and I can't break apart the set into first/next and keep it as a set. I have to get next as a sequence and then apply sorted-set-by to that sequence. This seems like a lot of wasted time. Is there a better way, or is it not a problem? Thanks. ;;; The dijkstra's algorithm values look like this! ;;; [end-node [path path-weight]] ;;; [:A [[] 0]] ;;; [:B [[:A :B] 3]] ;;; [:C [[:A :B :C] 5]] (defn d-comp "The comparator for Dijkstra's algorithm!" [[_ [_ a]] [_ [_ b]]] (<= a b)) (defn dijkstra "Computes a shortest-path tree starting at the specified node." [graph start-node] (loop [acc {} q (sorted-set-by d-comp [start-node [[start-node] 0]])] ;; Loop until the queue is empty, then return the accumulator (if (empty? q) acc (let [;; Destructure the first element of the queue [cur-node [cur-path cur-sum]] (first q) ;; Add the first element to the accumulator map new-acc (conj acc (first q)) ;; Pop the first element of the queue new-q (apply sorted-set-by d-comp (next q)) ;See? Can't just dequeue the first of the set! ;; Get outgoint links from the current node ;; Only those that either aren't in the accumulator, ;; or which have a shorter path than the accumulator's ;; entry. links (for [[n w] (graph cur-node) :when (or (not (acc n)) (< (+ cur-sum w) (second (acc n))))] [n [(conj cur-path n) (+ cur-sum w)]]) ;; Get the set of nodes from the links l-nodes (set (map first links)) ;; Filter out the obsolete queue entries. Now, ;; we have better paths. new-q (apply sorted-set-by d-comp (filter #(not (l-nodes (first %))) new-q)) ;; Combine the queue and the links new-q (reduce conj new-q links)] ;; Recur on the new values! (recur new-acc new-q))))) -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en