separators.scm 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. ; Part of Scheme 48 1.9. See file COPYING for notices and license.
  2. ; Authors: Richard Kelsey
  3. ; Code to determine the separation vertices of a graph
  4. ; NODES is a list of nodes
  5. ; (TO node) returns a list of the nodes which are connected to this one
  6. ; (SLOT-NODE node) and (SET-SLOT! node value) are used by the algorithm to
  7. ; associate data with nodes (in the absence of a tables).
  8. (define (separation-vertices nodes to slot set-slot!)
  9. (cond ((null? nodes)
  10. (values '() '()))
  11. ((null? (cdr nodes))
  12. (values nodes (list nodes)))
  13. (else
  14. (receive (separators components)
  15. (real-separation-vertices (make-vertices nodes to slot set-slot!))
  16. (for-each (lambda (n) (set-slot! n #f)) nodes)
  17. (values separators components)))))
  18. (define-record-type vertex :vertex
  19. (really-make-vertex data edges dfs-index)
  20. vertex?
  21. (data vertex-data) ; user's data
  22. (edges vertex-edges ; list of edges from this vertex
  23. set-vertex-edges!)
  24. (dfs-index vertex-dfs-index ; ordering from depth-first-search
  25. set-vertex-dfs-index!)
  26. (level vertex-level ; value used in algorithm...
  27. set-vertex-level!)
  28. (parent vertex-parent ; parent of this node in DFS tree
  29. set-vertex-parent!))
  30. (define (make-vertex data)
  31. (really-make-vertex data '() 0))
  32. (define-record-type edge :edge
  33. (make-edge from to unused?)
  34. (from edge-from) ; two (unordered) vertices
  35. (to edge-to)
  36. (unused? edge-unused ; used to mark edges that have been traversed
  37. set-edge-unused!))
  38. (define (make-edge from to)
  39. (really-make-edge from to #t))
  40. (define (other-vertex edge v)
  41. (if (eq? v (edge-from edge))
  42. (edge-to edge)
  43. (edge-from edge)))
  44. (define (maybe-add-edge from to)
  45. (if (and (not (eq? from to))
  46. (not (any? (lambda (e)
  47. (or (eq? to (edge-from e))
  48. (eq? to (edge-to e))))
  49. (vertex-edges from))))
  50. (let ((e (make-edge from to)))
  51. (set-vertex-edges! from (cons e (vertex-edges from)))
  52. (set-vertex-edges! to (cons e (vertex-edges to))))))
  53. (define (make-vertices nodes to slot set-slot!)
  54. (let ((vertices (map (lambda (n)
  55. (let ((v (make-vertex n)))
  56. (set-slot! n v)
  57. v))
  58. nodes)))
  59. (for-each (lambda (n)
  60. (for-each (lambda (n0)
  61. (maybe-add-edge (slot n) (slot n0)))
  62. (to n)))
  63. nodes)
  64. vertices))
  65. ; The numbers are the algorithm step numbers from page 62 of Graph Algorithms,
  66. ; Shimon Even, Computer Science Press, 1979.
  67. ; Them Us
  68. ; L(v) (vertex-level v)
  69. ; k(v) (vertex-dfs-index v)
  70. ; f(v) (vertex-parent v)
  71. ; S stack
  72. ; s start
  73. (define (real-separation-vertices vertices)
  74. (do-vertex (car vertices) 0 '() (car vertices) '() '()))
  75. ; 2
  76. (define (do-vertex v i stack start v-res c-res)
  77. (let ((i (+ i 1)))
  78. (set-vertex-level! v i)
  79. (set-vertex-dfs-index! v i)
  80. (find-unused-edge v i (cons v stack) start v-res c-res)))
  81. ; 3
  82. (define (find-unused-edge v i stack start v-res c-res)
  83. (let ((e (first edge-unused? (vertex-edges v))))
  84. (if e
  85. (do-edge e v i stack start v-res c-res)
  86. (no-unused-edge v i stack start v-res c-res))))
  87. ; 4
  88. (define (do-edge e v i stack start v-res c-res)
  89. (let ((u (other-vertex e v)))
  90. (set-edge-unused?! e #f)
  91. (cond ((= 0 (vertex-dfs-index u))
  92. (set-vertex-parent! u v)
  93. (do-vertex u i stack start v-res c-res))
  94. (else
  95. (if (> (vertex-level v)
  96. (vertex-dfs-index u))
  97. (set-vertex-level! v (vertex-dfs-index u)))
  98. (find-unused-edge v i stack start v-res c-res)))))
  99. ; 5
  100. (define (no-unused-edge v i stack start v-res c-res)
  101. (let* ((parent (vertex-parent v))
  102. (p-dfs-index (vertex-dfs-index parent)))
  103. (cond ((= 1 p-dfs-index)
  104. (gather-nonseparable-with-start v i stack start v-res c-res))
  105. ((< (vertex-level v) p-dfs-index)
  106. (if (< (vertex-level v)
  107. (vertex-level parent))
  108. (set-vertex-level! parent (vertex-level v)))
  109. (find-unused-edge parent i stack start v-res c-res))
  110. (else
  111. (gather-nonseparable v i stack start v-res c-res)))))
  112. ; 7
  113. (define (gather-nonseparable v i stack start v-res c-res)
  114. (let* ((parent (vertex-parent v))
  115. (data (vertex-data parent)))
  116. (receive (vertices stack)
  117. (pop-down-to stack v)
  118. (find-unused-edge parent
  119. i
  120. stack
  121. start
  122. (if (not (memq? data v-res))
  123. (cons data v-res)
  124. v-res)
  125. (cons (cons data (map vertex-data vertices)) c-res)))))
  126. ; 9
  127. (define (gather-nonseparable-with-start v i stack start v-res c-res)
  128. (receive (vertices stack)
  129. (pop-down-to stack v)
  130. (let* ((data (vertex-data start))
  131. (c-res (cons (cons data (map vertex-data vertices)) c-res)))
  132. (if (not (any? edge-unused? (vertex-edges start)))
  133. (values v-res c-res)
  134. (find-unused-edge start
  135. i
  136. stack
  137. start
  138. (if (not (memq? data v-res))
  139. (cons data v-res)
  140. v-res)
  141. c-res)))))
  142. (define (pop-down-to stack v)
  143. (do ((stack stack (cdr stack))
  144. (res '() (cons (car stack) res)))
  145. ((eq? v (car stack))
  146. (values (cons v res) (cdr stack)))))
  147. (define (test-separation-vertices graph)
  148. (let ((nodes (map (lambda (n)
  149. (vector (car n) #f #f))
  150. graph)))
  151. (for-each (lambda (data node)
  152. (vector-set! node 1 (map (lambda (s)
  153. (first (lambda (v)
  154. (eq? s (vector-ref v 0)))
  155. nodes))
  156. (cdr data))))
  157. graph
  158. nodes)
  159. (receive (separation-vertices components)
  160. (separation-vertices nodes
  161. (lambda (v) (vector-ref v 1))
  162. (lambda (v) (vector-ref v 2))
  163. (lambda (v val) (vector-set! v 2 val)))
  164. (values (map (lambda (v) (vector-ref v 0)) separation-vertices)
  165. (map (lambda (l)
  166. (map (lambda (v) (vector-ref v 0))
  167. l))
  168. components)))))