separators.scm 5.6 KB

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