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 / trees.txt @ 8:b5b38998ef3b

History | View | Annotate | Download (3.78 KB)

1

    
2
% make undirected adjacency matrix of graph/tree
3
% e.g.,
4
%  1 
5
% / \
6
% 2  3
7
T = zeros(3,3);
8
T(1,2) = 1; T(2,1)=1;
9
T(1,3)=1; T(3,1) = 1;
10

    
11
root = 1;
12
[T, preorder, postorder] =  mk_rooted_tree(T, root);
13

    
14
% bottom up message passing leaves to root
15
for n=postorder(:)'
16
  for p	= parents(T, n)
17
     % p is parent of n
18
   end
19
end
20

    
21
% top down, root to leaves
22
for n=preorder(:)'
23
  for c= children(T,n)
24
    % c is child of n
25
  end
26
end
27

    
28

    
29
%%%%%%%%%%%%%
30

    
31
function ps = parents(adj_mat, i)
32
% PARENTS Return the list of parents of node i
33
% ps = parents(adj_mat, i)
34

    
35
ps = find(adj_mat(:,i))';
36

    
37

    
38
%%%%%%%%%%%%
39

    
40
function cs = children(adj_mat, i, t)
41
% CHILDREN Return the indices of a node's children in sorted order
42
% c = children(adj_mat, i, t)
43
%
44
% t is an optional argument: if present, dag is assumed to be a 2-slice DBN
45

    
46
if nargin < 3 
47
  cs = find(adj_mat(i,:));
48
else
49
  if t==1
50
    cs = find(adj_mat(i,:));
51
  else
52
    ss = length(adj_mat)/2;
53
    j = i+ss;
54
    cs = find(adj_mat(j,:)) + (t-2)*ss;
55
  end
56
end
57

    
58
%%%%%%%%%%%
59

    
60
function [T, pre, post, cycle] = mk_rooted_tree(G, root)
61
% MK_ROOTED_TREE Make a directed, rooted tree out of an undirected tree.
62
% [T, pre, post, cycle] = mk_rooted_tree(G, root)
63

    
64
n = length(G);
65
T = sparse(n,n); % not the same as T = sparse(n) !
66
directed = 0;
67
[d, pre, post, cycle, f, pred] = dfs(G, root, directed);
68
for i=1:length(pred)
69
  if pred(i)>0
70
    T(pred(i),i)=1;
71
  end
72
end
73

    
74

    
75
%%%%%%%%%%%
76

    
77
function [d, pre, post, cycle, f, pred] = dfs(adj_mat, start, directed)
78
% DFS Perform a depth-first search of the graph starting from 'start'.
79
% [d, pre, post, cycle, f, pred] = dfs(adj_mat, start, directed)
80
%
81
% Input:
82
% adj_mat(i,j)=1 iff i is connected to j.
83
% start is the root vertex of the dfs tree; if [], all nodes are searched
84
% directed = 1 if the graph is directed
85
%
86
% Output:
87
% d(i) is the time at which node i is first discovered.
88
% pre is a list of the nodes in the order in which they are first encountered (opened).
89
% post is a list of the nodes in the order in which they are last encountered (closed).
90
% 'cycle' is true iff a (directed) cycle is found.
91
% f(i) is the time at which node i is finished.
92
% pred(i) is the predecessor of i in the dfs tree.
93
%
94
% If the graph is a tree, preorder is parents before children,
95
% and postorder is children before parents.
96
% For a DAG, topological order = reverse(postorder).
97
%
98
% See Cormen, Leiserson and Rivest, "An intro. to algorithms" 1994, p478.
99

    
100
n = length(adj_mat);
101

    
102
global white gray black color
103
white = 0; gray = 1; black = 2;
104
color = white*ones(1,n);
105

    
106
global time_stamp
107
time_stamp = 0;
108

    
109
global d f
110
d = zeros(1,n);
111
f = zeros(1,n);
112

    
113
global pred
114
pred = zeros(1,n);
115

    
116
global cycle
117
cycle = 0;
118

    
119
global pre post
120
pre = [];
121
post = [];
122

    
123
if ~isempty(start)
124
  dfs_visit(start, adj_mat, directed);
125
else
126
  for u=1:n
127
    if color(u)==white
128
      dfs_visit(u, adj_mat, directed);
129
    end
130
  end
131
end
132

    
133

    
134
%%%%%%%%%%
135

    
136
function dfs_visit(u, adj_mat, directed)
137

    
138
global white gray black color time_stamp d f pred cycle  pre post
139

    
140
pre = [pre u];
141
color(u) = gray;
142
time_stamp = time_stamp + 1;
143
d(u) = time_stamp;
144
if directed
145
  ns = children(adj_mat, u);
146
else
147
  ns = neighbors(adj_mat, u);
148
  ns = mysetdiff(ns, pred(u)); % don't go back to visit the guy who called you!
149
end
150
for v=ns(:)'
151
  %fprintf('u=%d, v=%d, color(v)=%d\n', u, v, color(v))
152
  switch color(v)
153
    case white, % not visited v before (tree edge)
154
     pred(v)=u;
155
     dfs_visit(v, adj_mat, directed);
156
   case gray, % back edge - v has been visited, but is still open
157
    cycle = 1;
158
    %fprintf('cycle: back edge from v=%d to u=%d\n', v, u);
159
   case black, % v has been visited, but is closed
160
    % no-op
161
  end
162
end
163
color(u) = black;
164
post = [post u];
165
time_stamp = time_stamp + 1;
166
f(u) = time_stamp;
167

    
168