-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathgraph.rkt
90 lines (89 loc) · 3.1 KB
/
graph.rkt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
#lang racket
(require racket/set)
(require data/heap)
(struct graph (node adj_list weights) #:mutable)
;; DATA STRUCTURE ;;
;;;;;;;;;;;;;;;;;;;;;
(provide initialize_graph)
(define (initialize_graph)
(graph empty (make-hash) (make-hash))
)
(provide add_node)
(define (add_node grph node_)
(set-graph-node! grph (cons node_ (graph-node grph)))
)
(provide add_edge)
(define (add_edge grph u v w)
(set-add! (hash-ref! (graph-adj_list grph) u (mutable-set)) v)
(set-add! (hash-ref! (graph-adj_list grph) v (mutable-set)) u)
(hash-set! (hash-ref! (graph-weights grph) u (make-hash)) v w)
(hash-set! (hash-ref! (graph-weights grph) v (make-hash)) u w)
)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(provide displn)
(define (displn a)
(display a)
(display "\n")
)
(define (get_weight grph u v)
(hash-ref (hash-ref (graph-weights grph) u) v)
)
(define (getVal hash key)
(hash-ref hash key)
)
(define (setVal hash key val)
(hash-set! hash key val)
)
(define (<=? x y)
(<= (car x) (car y))
)
(define (heap-empty? heap)
(cond
[(= 0 (heap-count heap)) #t] ;; hoping that heap-count is constant time
[else #f]
))
;; DJIKSTRA'S ALGORITHM ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(define inf "inf") ; define inf 'inf as a large value
(define (djikstra grph u v)
(let ([isVisited (make-hash (map (lambda (x) (cons x 'notvisited)) (graph-node grph)))]
[distance (make-hash (map (lambda (x) (if (equal? x u) (cons x 0) (cons x inf))) (graph-node grph)))]
[minHeap (make-heap <=?)])
(heap-add! minHeap (cons (getVal distance u) u))
(define (check)
(cond
[(heap-empty? minHeap) (void)]
[else (let ([top (heap-min minHeap)])
(heap-remove-min! minHeap)
(cond
[(equal? 'visited (hash-ref isVisited (cdr top))) (check)]
[else
(setVal isVisited (cdr top) 'visited)
(set-for-each (hash-ref! (graph-adj_list grph) (cdr top) (mutable-set))
(lambda (x)
(cond
[(or (equal? (getVal distance x) "inf") (< (+ (getVal distance (cdr top)) (get_weight grph (cdr top) x)) (getVal distance x)))
(setVal distance x (+ (getVal distance (cdr top)) (get_weight grph (cdr top) x)))(heap-add! minHeap (cons (getVal distance x) x))]
))
) (check)]) (void))])) (check) distance
)
)
(provide shortest_path)
(define (shortest_path grph src dst)
(let ([distance (djikstra grph src dst)])
;;(display "All distances :")
;;(displn distance)
distance
)
)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(provide print_graph) ; Utility for printing the graph : First the nodes are printed, then the adjacency List and finally the weights of the edges are returned
(define (print_graph grph)
(display "\nNodes: ")
(display (graph-node grph))
(display "\n")
(display "Adjacency List: ")
(display (graph-adj_list grph))
(display "\nWeights: ")
(displn (graph-weights grph))
)