Mercurial > hg > camir-aes2014
comparison toolboxes/FullBNT-1.0.7/graph/trees.txt @ 0:e9a9cd732c1e tip
first hg version after svn
author | wolffd |
---|---|
date | Tue, 10 Feb 2015 15:05:51 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:e9a9cd732c1e |
---|---|
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 |