Mercurial > hg > camir-aes2014
comparison toolboxes/FullBNT-1.0.7/graph/Old/dfs.m @ 0:e9a9cd732c1e tip
first hg version after svn
author | wolffd |
---|---|
date | Tue, 10 Feb 2015 15:05:51 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:e9a9cd732c1e |
---|---|
1 function [d, pre, post, height, cycle, pred] = dfs(adj_mat, start, directed) | |
2 % DFS Perform a depth-first search of the graph starting from 'start'. | |
3 % [d, pre, post, height, cycle, pred] = dfs(adj_mat, start, directed) | |
4 % | |
5 % d(i) is the time at which node i is first discovered. | |
6 % pre is a listing of the nodes in the order in which they are first encountered (opened). | |
7 % post is a listing of the nodes in the order in which they are last encountered (closed). | |
8 % A node is last encountered once we have explored all of its neighbors. | |
9 % If the graph is directed, i's neighbors are its children. | |
10 % If the graph is a tree, preorder is parents before children, and | |
11 % postorder is children before parents. | |
12 % For a DAG, topological order = reverse(postorder). | |
13 % height(i) is the height (distance) of node i from the start. | |
14 % 'cycle' is true iff a (directed) cycle is found. | |
15 % pred(i) is the parent of i in the dfs tree rooted at start. | |
16 % See Cormen, Leiserson and Rivest, "An intro. to algorithms" 1994, p478. | |
17 | |
18 % We can detect undirected cycles by checking if we are about to visit a node n which we have | |
19 % already visited. To detect *directed* cycles, we need to know if n has been closed or is still open. | |
20 % For example (where arcs are directed down) | |
21 % 1 2 | |
22 % \ / | |
23 % 3 | |
24 % Assume we visit 1, 3 and then 2 in order. The fact that a child of 2 (namely, 3) has | |
25 % already been visited is okay, because 3 has been closed. | |
26 % The algorithms in Aho, Hopcroft and Ullman, and Sedgewick, do not detect directed cycles. | |
27 | |
28 n = length(adj_mat); | |
29 | |
30 global white gray black | |
31 white = 0; gray = 1; black = 2; | |
32 | |
33 color = white*ones(1,n); | |
34 d = zeros(1,n); | |
35 height = zeros(1,n); | |
36 pred = zeros(1,n); | |
37 pre = []; | |
38 post = []; | |
39 cycle = 0; | |
40 global count | |
41 count = 0; | |
42 h = 0; | |
43 [d, pre, post, height, cycle, color, pred] = ... | |
44 dfs2(adj_mat, start, directed, h, d, pre, post, height, cycle, color, pred); | |
45 | |
46 | |
47 | |
48 %%%%%%%%%% | |
49 | |
50 function [d, pre, post, height, cycle, color, pred] = ... | |
51 dfs2(adj_mat, i, directed, h, d, pre, post, height, cycle, color, pred) | |
52 | |
53 global count | |
54 global white gray black | |
55 | |
56 color(i) = gray; | |
57 count = count + 1; | |
58 d(i) = count; | |
59 pre = [pre i]; | |
60 height(i) = h; | |
61 if directed | |
62 ns = children(adj_mat, i); | |
63 else | |
64 ns = neighbors(adj_mat, i); | |
65 end | |
66 for j=1:length(ns) | |
67 n=ns(j); | |
68 if ~directed & n==pred(i) % don't go back up the edge you just came down | |
69 % continue | |
70 else | |
71 if color(n) == gray % going back to a non-closed vertex via a new edge | |
72 %fprintf(1, 'cycle from %d to %d\n', i, n); | |
73 cycle = 1; | |
74 end | |
75 if color(n) == white % not visited n before | |
76 pred(n)=i; | |
77 [d, pre, post, height, cycle, color, pred] = ... | |
78 dfs2(adj_mat, n, directed, h+1, d, pre, post, height, cycle, color, pred); | |
79 end | |
80 end | |
81 end | |
82 color(i) = black; | |
83 post = [post i]; | |
84 |