annotate toolboxes/FullBNT-1.0.7/graph/dfs.m @ 0:e9a9cd732c1e tip

first hg version after svn
author wolffd
date Tue, 10 Feb 2015 15:05:51 +0000
parents
children
rev   line source
wolffd@0 1 function [d, pre, post, cycle, f, pred] = dfs(adj_mat, start, directed)
wolffd@0 2 % DFS Perform a depth-first search of the graph starting from 'start'.
wolffd@0 3 % [d, pre, post, cycle, f, pred] = dfs(adj_mat, start, directed)
wolffd@0 4 %
wolffd@0 5 % Input:
wolffd@0 6 % adj_mat(i,j)=1 iff i is connected to j.
wolffd@0 7 % start is the root vertex of the dfs tree; if [], all nodes are searched
wolffd@0 8 % directed = 1 if the graph is directed
wolffd@0 9 %
wolffd@0 10 % Output:
wolffd@0 11 % d(i) is the time at which node i is first discovered.
wolffd@0 12 % pre is a list of the nodes in the order in which they are first encountered (opened).
wolffd@0 13 % post is a list of the nodes in the order in which they are last encountered (closed).
wolffd@0 14 % 'cycle' is true iff a (directed) cycle is found.
wolffd@0 15 % f(i) is the time at which node i is finished.
wolffd@0 16 % pred(i) is the predecessor of i in the dfs tree.
wolffd@0 17 %
wolffd@0 18 % If the graph is a tree, preorder is parents before children,
wolffd@0 19 % and postorder is children before parents.
wolffd@0 20 % For a DAG, topological order = reverse(postorder).
wolffd@0 21 %
wolffd@0 22 % See Cormen, Leiserson and Rivest, "An intro. to algorithms" 1994, p478.
wolffd@0 23
wolffd@0 24 n = length(adj_mat);
wolffd@0 25
wolffd@0 26 global white gray black color
wolffd@0 27 white = 0; gray = 1; black = 2;
wolffd@0 28 color = white*ones(1,n);
wolffd@0 29
wolffd@0 30 global time_stamp
wolffd@0 31 time_stamp = 0;
wolffd@0 32
wolffd@0 33 global d f
wolffd@0 34 d = zeros(1,n);
wolffd@0 35 f = zeros(1,n);
wolffd@0 36
wolffd@0 37 global pred
wolffd@0 38 pred = zeros(1,n);
wolffd@0 39
wolffd@0 40 global cycle
wolffd@0 41 cycle = 0;
wolffd@0 42
wolffd@0 43 global pre post
wolffd@0 44 pre = [];
wolffd@0 45 post = [];
wolffd@0 46
wolffd@0 47 if ~isempty(start)
wolffd@0 48 dfs_visit(start, adj_mat, directed);
wolffd@0 49 end
wolffd@0 50 for u=1:n
wolffd@0 51 if color(u)==white
wolffd@0 52 dfs_visit(u, adj_mat, directed);
wolffd@0 53 end
wolffd@0 54 end
wolffd@0 55
wolffd@0 56
wolffd@0 57 %%%%%%%%%%
wolffd@0 58
wolffd@0 59 function dfs_visit(u, adj_mat, directed)
wolffd@0 60
wolffd@0 61 global white gray black color time_stamp d f pred cycle pre post
wolffd@0 62
wolffd@0 63 pre = [pre u];
wolffd@0 64 color(u) = gray;
wolffd@0 65 time_stamp = time_stamp + 1;
wolffd@0 66 d(u) = time_stamp;
wolffd@0 67 if directed
wolffd@0 68 ns = children(adj_mat, u);
wolffd@0 69 else
wolffd@0 70 ns = neighbors(adj_mat, u);
wolffd@0 71 ns = setdiff(ns, pred(u)); % don't go back to visit the guy who called you!
wolffd@0 72 end
wolffd@0 73 for v=ns(:)'
wolffd@0 74 %fprintf('u=%d, v=%d, color(v)=%d\n', u, v, color(v))
wolffd@0 75 switch color(v)
wolffd@0 76 case white, % not visited v before (tree edge)
wolffd@0 77 pred(v)=u;
wolffd@0 78 dfs_visit(v, adj_mat, directed);
wolffd@0 79 case gray, % back edge - v has been visited, but is still open
wolffd@0 80 cycle = 1;
wolffd@0 81 %fprintf('cycle: back edge from v=%d to u=%d\n', v, u);
wolffd@0 82 case black, % v has been visited, but is closed
wolffd@0 83 % no-op
wolffd@0 84 end
wolffd@0 85 end
wolffd@0 86 color(u) = black;
wolffd@0 87 post = [post u];
wolffd@0 88 time_stamp = time_stamp + 1;
wolffd@0 89 f(u) = time_stamp;
wolffd@0 90
wolffd@0 91