(module dijkstra-solver mzscheme (require "heap.ss" (lib "list.ss") "graph.ss") (provide (all-defined)) (define (make-node label x y weight) (vector label x y weight)) (define (node-label n) (vector-ref n 0)) (define (node-x n) (vector-ref n 1)) (define (node-y n) (vector-ref n 2)) (define (node-weight n) (vector-ref n 3)) (define (set-node-weight! n v) (vector-set! n 3 v)) (define (node< a b) (< (node-weight a) (node-weight b))) (define (sqr x) (* x x)) (define (distance-to a b) (sqrt (+ (sqr (- (node-x a) (node-x b))) (sqr (- (node-y a) (node-y b)))))) (define (hash-table-pairs hash) (hash-table-map hash (lambda (key val) (list key val)))) (define (relax backtrace heap origin dest) (let ([candidate-weight (+ (node-weight origin) (distance-to origin dest))]) (when (candidate-weight . < . (node-weight dest)) (set-node-weight! dest candidate-weight) ;;(heap-resort heap dest) (hash-table-put! backtrace dest origin)))) (define (solve graph nodes source) (let ([backtrace (make-hash-table)] [heap (make-heap node< eq?)]) (set-node-weight! source 0) (for-each (lambda (node) (heap-insert heap node)) nodes) (let loop () (unless (heap-empty? heap) (let* ([node (heap-pop heap)] [successors (graph-succs graph node)]) (for-each (lambda (succ) (relax backtrace heap node succ)) successors)) (loop))) (hash-table-pairs backtrace))))