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 / dfs.m @ 8:b5b38998ef3b

History | View | Annotate | Download (2.32 KB)

1
function [d, pre, post, cycle, f, pred] = dfs(adj_mat, start, directed)
2
% DFS Perform a depth-first search of the graph starting from 'start'.
3
% [d, pre, post, cycle, f, pred] = dfs(adj_mat, start, directed)
4
%
5
% Input:
6
% adj_mat(i,j)=1 iff i is connected to j.
7
% start is the root vertex of the dfs tree; if [], all nodes are searched
8
% directed = 1 if the graph is directed
9
%
10
% Output:
11
% d(i) is the time at which node i is first discovered.
12
% pre is a list of the nodes in the order in which they are first encountered (opened).
13
% post is a list of the nodes in the order in which they are last encountered (closed).
14
% 'cycle' is true iff a (directed) cycle is found.
15
% f(i) is the time at which node i is finished.
16
% pred(i) is the predecessor of i in the dfs tree.
17
%
18
% If the graph is a tree, preorder is parents before children,
19
% and postorder is children before parents.
20
% For a DAG, topological order = reverse(postorder).
21
%
22
% See Cormen, Leiserson and Rivest, "An intro. to algorithms" 1994, p478.
23

    
24
n = length(adj_mat);
25

    
26
global white gray black color
27
white = 0; gray = 1; black = 2;
28
color = white*ones(1,n);
29

    
30
global time_stamp
31
time_stamp = 0;
32

    
33
global d f
34
d = zeros(1,n);
35
f = zeros(1,n);
36

    
37
global pred
38
pred = zeros(1,n);
39

    
40
global cycle
41
cycle = 0;
42

    
43
global pre post
44
pre = [];
45
post = [];
46

    
47
if ~isempty(start)
48
  dfs_visit(start, adj_mat, directed);
49
end
50
for u=1:n
51
  if color(u)==white
52
    dfs_visit(u, adj_mat, directed);
53
  end
54
end
55

    
56

    
57
%%%%%%%%%%
58

    
59
function dfs_visit(u, adj_mat, directed)
60

    
61
global white gray black color time_stamp d f pred cycle  pre post
62

    
63
pre = [pre u];
64
color(u) = gray;
65
time_stamp = time_stamp + 1;
66
d(u) = time_stamp;
67
if directed
68
  ns = children(adj_mat, u);
69
else
70
  ns = neighbors(adj_mat, u);
71
  ns = setdiff(ns, pred(u)); % don't go back to visit the guy who called you!
72
end
73
for v=ns(:)'
74
  %fprintf('u=%d, v=%d, color(v)=%d\n', u, v, color(v))
75
  switch color(v)
76
    case white, % not visited v before (tree edge)
77
     pred(v)=u;
78
     dfs_visit(v, adj_mat, directed);
79
   case gray, % back edge - v has been visited, but is still open
80
    cycle = 1;
81
    %fprintf('cycle: back edge from v=%d to u=%d\n', v, u);
82
   case black, % v has been visited, but is closed
83
    % no-op
84
  end
85
end
86
color(u) = black;
87
post = [post u];
88
time_stamp = time_stamp + 1;
89
f(u) = time_stamp;
90

    
91