To check out this repository please hg clone the following URL, or open the URL using EasyMercurial or your preferred Mercurial client.

Statistics Download as Zip
| Branch: | Revision:

root / _FullBNT / BNT / graph / Old / dfs.m @ 8:b5b38998ef3b

History | View | Annotate | Download (2.76 KB)

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