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

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