(define make-graph (make-encapsulation (n) ((v (generate-vector (lambda (i) (make-vector 3 '())) n))) ((node-ref (lambda (node i) (vector-ref (vector-ref v node) i))) (node-set! (lambda (node i value) (vector-set! (vector-ref v node) i value)))) ((number-of-nodes (lambda () n)) (for-each-node (lambda (function) (for-each-integer function n))) (self-print (lambda () (vector-for-each print v))) (self (lambda () v)) (label (lambda (node) (node-ref node 0))) (set-label! (lambda (node value) (node-set! node 0 value))) (predecessor (lambda (node) (node-ref node 1))) (set-predecessor! (lambda (node value) (node-set! node 1 value))) (adjacency-list (lambda (node) (node-ref node 2))) (first-node (lambda (link) (vector-ref link 0))) (second-node (lambda (link) (vector-ref link 1))) (link-length (lambda (link) (vector-ref link 2))) (reverse-link (lambda (link) (vector (vector-ref link 1) (vector-ref link 0) (vector-ref link 2)))) (add-directed-link (lambda (link) (let ((node1 (first-node link))) (vector-set! (vector-ref v node1) 2 (cons link (adjacency-list node1)))))) (add-undirected-link (lambda (link) (let ((node1 (first-node link)) (node2 (second-node link))) (vector-set! (vector-ref v node1) 2 (cons link (adjacency-list node1))) (vector-set! (vector-ref v node2) 2 (cons (reverse-link link) (adjacency-list node2)))))) (for-each-link-of-node (lambda (function node) (for-each function (adjacency-list node))))))) ;@ ;;;========================================== ;;; ;;; Random Graph Generators ;;; ;;;========================================== (define (random-edge n length) (let loop ((i (random n)) (j (random n))) (if (= i j) (loop (random n) (random n)) (vector i j (random length))))) (define (d-graph n m . r) (let* ((r (if (null? r) 100 (car r))) (graph (make-graph n)) (add (graph 'add-directed-link)) (add-random-link (lambda (x) (add (random-edge n r))))) (for-each-integer add-random-link m) graph)) (define (u-graph n m . r) (let* ((r (if (null? r) 100 (car r))) (graph (make-graph n)) (add (graph 'add-undirected-link)) (add-random-link (lambda (x) (add (random-edge n r))))) (for-each-integer add-random-link m) graph))