|
31 | 31 | (rtl:? src-node 'edges)))) |
32 | 32 | rez)) |
33 | 33 |
|
34 | | -;; TODO (deftest graph () |
35 | | -;; CL-USER> (init-graph '((7 8) |
36 | | -;; (1 3) |
37 | | -;; (1 2) |
38 | | -;; (3 4) |
39 | | -;; (3 5) |
40 | | -;; (2 4) |
41 | | -;; (2 5) |
42 | | -;; (5 4) |
43 | | -;; (5 6) |
44 | | -;; (4 6))) |
| 34 | +(deftest graph () |
| 35 | + (should print-to *standard-output* |
| 36 | + " |
| 37 | + 1 2 3 4 5 6 7 8 |
| 38 | +1 x x |
| 39 | +2 x x |
| 40 | +3 x x |
| 41 | +4 x |
| 42 | +5 x x |
| 43 | +6 |
| 44 | +7 x |
| 45 | +8 |
| 46 | + " |
| 47 | + (print (init-graph '((7 8) |
| 48 | + (1 3) |
| 49 | + (1 2) |
| 50 | + (3 4) |
| 51 | + (3 5) |
| 52 | + (2 4) |
| 53 | + (2 5) |
| 54 | + (5 4) |
| 55 | + (5 6) |
| 56 | + (4 6)))))) |
45 | 57 |
|
46 | 58 | (defun topo-sort (graph) |
47 | 59 | (let ((nodes (nodes graph)) |
48 | 60 | (visited (make-hash-table)) |
49 | 61 | (rez (rtl:vec))) |
50 | 62 | (rtl:dokv (id node nodes) |
51 | | - (unless (gethash id visited) |
52 | | - (visit node nodes visited rez))) |
| 63 | + (unless (gethash id visited) |
| 64 | + (visit node nodes visited rez))) |
53 | 65 | rez)) |
54 | 66 |
|
55 | 67 | (defun visit (node nodes visited rez) |
56 | 68 | (dolist (edge (node-edges node)) |
57 | 69 | (rtl:with ((id (edge-dst edge)) |
58 | | - (child (elt nodes id))) |
59 | | - (unless (find id rez) |
60 | | - (assert (not (gethash id visited)) nil |
61 | | - "The graph isn't acyclic for vertex: ~A" id) |
62 | | - (setf (gethash id visited) t) |
63 | | - (visit child nodes visited rez)))) |
| 70 | + (child (gethash id nodes))) |
| 71 | + (unless (find id rez) |
| 72 | + (assert (not (gethash id visited)) nil |
| 73 | + "The graph isn't acyclic for vertex: ~A" id) |
| 74 | + (setf (gethash id visited) t) |
| 75 | + (visit child nodes visited rez)))) |
64 | 76 | (vector-push-extend (node-id node) rez) |
65 | 77 | rez) |
66 | 78 |
|
|
144 | 156 | (parent (hparent i)) |
145 | 157 | (parent-key (aref vec parent))) |
146 | 158 | (when (> i-key parent-key) |
147 | | - (rtl:removef i (gethash i-key *heap-indices*)) |
148 | | - (rtl:removef parent (gethash parent-key *heap-indices*)) |
| 159 | + (rtl:removef (gethash i-key *heap-indices*) i) |
| 160 | + (rtl:removef (gethash parent-key *heap-indices*) parent) |
149 | 161 | (push i (gethash parent-key *heap-indices*)) |
150 | 162 | (push parent (gethash i-key *heap-indices*)) |
151 | 163 | (rotatef (aref vec i) |
|
164 | 176 | (heap-up vec parent)) |
165 | 177 | vec) |
166 | 178 |
|
167 | | - (defun heap-decrease-key-correct (vec key decrement) |
| 179 | +(defun heap-decrease-key-correct (vec key decrement) |
168 | 180 | (let ((i (gethash key *heap-indices*))) |
169 | 181 | (unless i (error "No key ~A found in the heap: ~A" key vec)) |
170 | 182 | (remhash key *heap-indices*) |
|
179 | 191 | (rtl:with ((i-key (heap-item-key (aref vec i))) |
180 | 192 | (parent (hparent i)) |
181 | 193 | (parent-key (heap-item-key (aref vec parent)))) |
182 | | - (when (> i-key parent-kea) |
183 | | - (rtl:removef i (gethash i-key *heap-indices*)) |
184 | | - (rtl:removef parent (gethash parent-key *heap-indices*)) |
| 194 | + (when (> i-key parent-key) |
| 195 | + (rtl:removef (gethash i-key *heap-indices*) i) |
| 196 | + (rtl:removef (gethash parent-key *heap-indices*) parent) |
185 | 197 | (push i (gethash parent-key *heap-indices*)) |
186 | 198 | (push parent (gethash i-key *heap-indices*)) |
187 | 199 | (rotatef (aref vec i) |
188 | 200 | (aref vec parent)) |
189 | 201 | (heap-up vec parent))) |
190 | 202 | vec) |
191 | 203 |
|
192 | | -;; TODO (deftest heap2 () |
| 204 | +;; TODO test heap |
193 | 205 |
|
194 | 206 | (defstruct (spf-node (:include node)) |
195 | 207 | (weight most-positive-fixnum) |
196 | 208 | (path (list))) |
197 | 209 |
|
198 | 210 | (defun spf (graph src dst) |
199 | 211 | (rtl:with ((nodes (graph-nodes graph)) |
200 | | - (spf (list)) |
201 | 212 | ;; the following code should express initialize the heap |
202 | 213 | ;; with a single node of weight 0 and all other nodes |
203 | 214 | ;; of weight MOST-POSITIVE-FIXNUM |
|
222 | 233 | (spf-node-path node) (cons (rtl:? nodes id) |
223 | 234 | (rtl:? nodes id 'path)))))))))) |
224 | 235 |
|
225 | | -;; TODO (deftest spf () |
| 236 | +;; TODO test spf |
226 | 237 |
|
227 | 238 | (defstruct mf-edge |
228 | 239 | beg end capacity) |
229 | 240 |
|
230 | 241 | (defun max-flow (g) |
231 | | - (let ((rg (copy-array g)) ; residual graph |
| 242 | + (assert (= (array-dimension g 0) |
| 243 | + (array-dimension g 1))) |
| 244 | + (let ((rg (rtl:copy-array g)) ; residual graph |
232 | 245 | (rez 0)) |
233 | 246 | (loop :for path := (aug-path rg) :while path :do |
234 | 247 | (let ((flow most-positive-fixnum)) |
|
247 | 260 | (defun aug-path (g) |
248 | 261 | (rtl:with ((sink (1- (array-dimension g 0))) |
249 | 262 | (visited (make-array (1+ sink) :initial-element nil))) |
250 | | - (labels ((dfs (g i) |
251 | | - (if (zerop (aref g i sink)) |
252 | | - (dotimes (j sink) |
253 | | - (unless (or (zerop (aref g i j)) |
254 | | - (aref visited j)) |
255 | | - (rtl:when-it (dfs g j) |
256 | | - (setf (aref visited j) t) |
257 | | - (return (cons (make-mf-edge |
258 | | - :beg i :end j |
259 | | - :capacity (aref g i j)) |
260 | | - rtl:it))))) |
261 | | - (list (make-mf-edge |
262 | | - :beg i :end sink |
263 | | - :capacity (aref g i sink)))))) |
264 | | - (dfs g 0)))) |
| 263 | + (labels ((dfs (g i) |
| 264 | + (setf (aref visited i) t) |
| 265 | + (if (zerop (aref g i sink)) |
| 266 | + (dotimes (j sink) |
| 267 | + (unless (or (zerop (aref g i j)) |
| 268 | + (aref visited j)) |
| 269 | + (rtl:when-it (dfs g j) |
| 270 | + (return (cons (make-mf-edge |
| 271 | + :beg i :end j |
| 272 | + :capacity (aref g i j)) |
| 273 | + rtl:it))))) |
| 274 | + (list (make-mf-edge |
| 275 | + :beg i :end sink |
| 276 | + :capacity (aref g i sink)))))) |
| 277 | + (dfs g 0)))) |
265 | 278 |
|
266 | 279 | (deftest max-flow () |
267 | 280 | (should be = 7 (max-flow #2A((0 4 4 0 0 0) |
268 | 281 | (0 0 0 4 2 0) |
269 | 282 | (0 0 0 1 2 0) |
270 | 283 | (0 0 0 0 0 3) |
271 | | - (0 0 0 0 0 5))))) |
| 284 | + (0 0 0 0 0 5) |
| 285 | + (0 0 0 0 0 0))))) |
272 | 286 |
|
273 | 287 | ;; code prototypes |
274 | 288 |
|
275 | 289 | (defun pagerank (g &key (d 0.85) (repeat 100)) |
276 | | - (rtl:with ((n (length (nodes g))) |
277 | | - (pr (make-arrray n :initial-element (/ 1 n)))) |
| 290 | + (rtl:with ((nodes (nodes g)) |
| 291 | + (n (length nodes)) |
| 292 | + (pr (make-array n :initial-element (/ 1 n)))) |
278 | 293 | (loop :repeat repeat :do |
279 | | - (let ((pr2 (map 'vector (lambda (x) (- 1 (/ d n))) |
| 294 | + (let ((pr2 (map 'vector (lambda (x) (- 1 (/ x n))) |
280 | 295 | pr))) |
281 | 296 | (rtl:dokv (i node nodes) |
282 | 297 | (let ((p (aref pr i)) |
283 | 298 | (m (length (node-children node)))) |
284 | | - (rtl:dokv (j child (node-children node))) |
285 | | - (incf (aref pr2 j) (* d (/ p m))))) |
| 299 | + (rtl:dokv (j _ (node-children node)) |
| 300 | + (incf (aref pr2 j) (* d (/ p m)))))) |
286 | 301 | (setf pr pr2))) |
287 | 302 | pr)) |
288 | 303 |
|
289 | 304 | (defun pr1 (node n p &key (d 0.85)) |
290 | | - (let ((pr (make-arrray n :initial-element 0)) |
| 305 | + (let ((pr (make-array n :initial-element 0)) |
291 | 306 | (m (hash-table-count (node-children node)))) |
292 | 307 | (rtl:dokv (j child (node-children node)) |
293 | 308 | (setf (aref pr j) (* d (/ p m)))) |
294 | 309 | pr)) |
295 | 310 |
|
296 | 311 | (defun pagerank-mr (g &key (d 0.85) (repeat 100)) |
297 | 312 | (rtl:with ((n (length (nodes g))) |
298 | | - (pr (make-arrray n :initial-element (/ 1 n)))) |
| 313 | + (pr (make-array n :initial-element (/ 1 n)))) |
299 | 314 | (loop :repeat repeat :do |
300 | | - (setf pr (map 'vector (lambda (x) |
301 | | - (- 1 (/ d n))) |
| 315 | + (setf pr (map 'vector (lambda (x) (- 1 (/ x n))) |
302 | 316 | (reduce 'vec+ (map 'vector (lambda (node p) |
303 | 317 | (pr1 node n p :d d)) |
304 | 318 | (nodes g) |
|
0 commit comments