comparison scripts/sparse/treelayout.m @ 8507:cadc73247d65

style fixes
author John W. Eaton <jwe@octave.org>
date Tue, 13 Jan 2009 14:08:36 -0500
parents bc982528de11
children eb63fbe60fab
comparison
equal deleted inserted replaced
8506:bc982528de11 8507:cadc73247d65
16 ## along with Octave; see the file COPYING. If not, see 16 ## along with Octave; see the file COPYING. If not, see
17 ## <http://www.gnu.org/licenses/>. 17 ## <http://www.gnu.org/licenses/>.
18 18
19 ## -*- texinfo -*- 19 ## -*- texinfo -*-
20 ## @deftypefn {Function File} {} treelayout (@var{Tree}) 20 ## @deftypefn {Function File} {} treelayout (@var{Tree})
21 ## @deftypefnx {Function File} {} treelayout (@var{Tree}, @var{Permutation}) 21 ## @deftypefnx {Function File} {} treelayout (@var{Tree}, @var{permutation})
22 ## treelayout lays out a tree or a forest. The first argument @var{Tree} is a vector of 22 ## treelayout lays out a tree or a forest. The first argument @var{Tree} is a vector of
23 ## predecessors, optional parameter @var{Permutation} is an optional postorder permutation. 23 ## predecessors, optional parameter @var{permutation} is an optional postorder permutation.
24 ## The complexity of the algorithm is O(n) in 24 ## The complexity of the algorithm is O(n) in
25 ## terms of time and memory requirements. 25 ## terms of time and memory requirements.
26 ## @seealso{etreeplot, gplot,treeplot} 26 ## @seealso{etreeplot, gplot,treeplot}
27 ## @end deftypefn 27 ## @end deftypefn
28 28
29 function [XCoordinate, YCoordinate, Height, s] = treelayout (Tree, Permutation) 29 function [x_coordinate, y_coordinate, height, s] = treelayout (tree, permutation)
30 if (nargin < 1 || nargin > 2 || nargout > 4) 30 if (nargin < 1 || nargin > 2 || nargout > 4)
31 print_usage (); 31 print_usage ();
32 elseif (! isvector (Tree) || rows (Tree) != 1 || ! isnumeric (Tree) 32 elseif (! isvector (tree) || rows (tree) != 1 || ! isnumeric (tree)
33 || any (Tree > length (Tree)) || any (Tree < 0) ) 33 || any (tree > length (tree)) || any (tree < 0))
34 error ("treelayout: the first input argument must be a vector of predecessors"); 34 error ("treelayout: the first input argument must be a vector of predecessors");
35 else 35 else
36 ## Make it a row vector. 36 ## Make it a row vector.
37 Tree = Tree(:)'; 37 tree = tree(:)';
38 38
39 ## The count of nodes of the graph. 39 ## The count of nodes of the graph.
40 NodNumber = length (Tree); 40 num_nodes = length (tree);
41 ## The number of children. 41 ## The number of children.
42 ChildNumber = zeros (1, NodNumber + 1); 42 num_children = zeros (1, num_nodes + 1);
43 43
44 ## Checking vector of predecessors. 44 ## Checking vector of predecessors.
45 for i = 1 : NodNumber 45 for i = 1 : num_nodes
46 if (Tree (i) < i) 46 if (tree(i) < i)
47 ## This part of graph was checked before. 47 ## This part of graph was checked before.
48 continue; 48 continue;
49 endif 49 endif
50 50
51 ## Try to find cicle in this part of graph using modified Floyd's 51 ## Try to find cicle in this part of graph using modified Floyd's
52 ## cycle-finding algorithm. 52 ## cycle-finding algorithm.
53 tortoise = Tree (i); 53 tortoise = tree(i);
54 hare = Tree (tortoise); 54 hare = tree(tortoise);
55 55
56 while (tortoise != hare) 56 while (tortoise != hare)
57 ## End after finding a cicle or reaching a checked part of graph. 57 ## End after finding a cicle or reaching a checked part of graph.
58 58
59 if (hare < i) 59 if (hare < i)
60 ## This part of graph was checked before. 60 ## This part of graph was checked before.
61 break 61 break
62 endif 62 endif
63 63
64 tortoise = Tree (tortoise); 64 tortoise = tree(tortoise);
65 ## Hare will move faster than tortoise so in cicle hare must 65 ## Hare will move faster than tortoise so in cicle hare must
66 ## reach tortoise. 66 ## reach tortoise.
67 hare = Tree (Tree (hare)); 67 hare = tree(tree(hare));
68 68
69 endwhile 69 endwhile
70 70
71 if (tortoise == hare) 71 if (tortoise == hare)
72 ## If hare reach tortoise we found circle. 72 ## If hare reach tortoise we found circle.
74 endif 74 endif
75 75
76 endfor 76 endfor
77 ## Vector of predecessors has right format. 77 ## Vector of predecessors has right format.
78 78
79 for i = 1:NodNumber 79 for i = 1:num_nodes
80 ## VecOfChild is helping vector which is used to speed up the 80 ## vec_of_child is helping vector which is used to speed up the
81 ## choice of descendant nodes. 81 ## choice of descendant nodes.
82 82
83 ChildNumber (Tree (i) + 1) = ChildNumber (Tree (i) + 1) + 1; 83 num_children(tree(i)+1) = num_children(tree(i)+1) + 1;
84 endfor 84 endfor
85 85
86 Pos = 1; 86 pos = 1;
87 for i = 1 : NodNumber + 1 87 start = zeros (1, num_nodes+1);
88 Start (i) = Pos; 88 xhelp = zeros (1, num_nodes+1);
89 Help (i) = Pos; 89 stop = zeros (1, num_nodes+1);
90 Pos += ChildNumber (i); 90 for i = 1 : num_nodes + 1
91 Stop (i) = Pos; 91 start(i) = pos;
92 xhelp(i) = pos;
93 pos += num_children(i);
94 stop(i) = pos;
92 endfor 95 endfor
93 96
94 if (nargin == 1) 97 if (nargin == 1)
95 for i = 1 : NodNumber 98 for i = 1:num_nodes
96 VecOfChild (Help (Tree (i) + 1)) = i; 99 vec_of_child(xhelp(tree(i)+1)) = i;
97 Help (Tree (i) + 1) = Help (Tree (i) + 1) + 1; 100 xhelp(tree(i)+1) = xhelp(tree(i)+1) + 1;
98 endfor 101 endfor
99 else 102 else
100 VecOfChild = Permutation; 103 vec_of_child = permutation;
101 endif 104 endif
102 105
103 ## The number of "parent" (actual) node (it's descendants will be 106 ## The number of "parent" (actual) node (it's descendants will be
104 ## browse in the next iteration). 107 ## browse in the next iteration).
105 ParNumber = 0; 108 par_number = 0;
106 109
107 ## The x-coordinate of the left most descendant of "parent node" 110 ## The x-coordinate of the left most descendant of "parent node"
108 ## this value is increased in each leaf. 111 ## this value is increased in each leaf.
109 LeftMost = 0; 112 left_most = 0;
110 113
111 ## The level of "parent" node (root level is NodNumber). 114 ## The level of "parent" node (root level is num_nodes).
112 Level = NodNumber; 115 level = num_nodes;
113 116
114 ## NodNumber - Max is the height of this graph. 117 ## num_nodes - max_ht is the height of this graph.
115 Max = NodNumber; 118 max_ht = num_nodes;
116 119
117 ## Main stack - each item consists of two numbers - the number of 120 ## Main stack - each item consists of two numbers - the number of
118 ## node and the number it's of parent node on the top of stack 121 ## node and the number it's of parent node on the top of stack
119 ## there is "parent node". 122 ## there is "parent node".
120 St = [-1, 0]; 123 stk = [-1, 0];
121 124
122 ## Number of vertices s in the top-level separator. 125 ## Number of vertices s in the top-level separator.
123 s = 0; 126 s = 0;
124 ## Flag which says if we are in top level separator. 127 ## Flag which says if we are in top level separator.
125 topLevel = 1; 128 top_level = 1;
126 ## The top of the stack. 129 ## The top of the stack.
127 while (ParNumber != -1) 130 while (par_number != -1)
128 if (Start(ParNumber + 1) < Stop(ParNumber + 1)) 131 if (start(par_number+1) < stop(par_number+1))
129 idx = VecOfChild (Start (ParNumber + 1) : Stop (ParNumber + 1) - 1); 132 idx = vec_of_child(start(par_number+1) : stop(par_number+1) - 1);
130 else 133 else
131 idx = zeros (1, 0); 134 idx = zeros (1, 0);
132 endif 135 endif
133 136
134 ## Add to idx the vector of parent descendants. 137 ## Add to idx the vector of parent descendants.
135 St = [St ; [idx', ones(fliplr(size(idx))) * ParNumber]]; 138 stk = [stk; [idx', ones(fliplr(size(idx))) * par_number]];
136 139
137 ## We are in top level separator when we have one child and the 140 ## We are in top level separator when we have one child and the
138 ## flag is 1 141 ## flag is 1
139 if (columns(idx) == 1 && topLevel ==1 ) 142 if (columns(idx) == 1 && top_level == 1)
140 s += 1; 143 s++;
141 else 144 else
142 # We aren't in top level separator now. 145 # We aren't in top level separator now.
143 topLevel = 0; 146 top_level = 0;
144 endif 147 endif
145 ## If there is not any descendant of "parent node": 148 ## If there is not any descendant of "parent node":
146 if (St(end,2) != ParNumber) 149 if (stk(end,2) != par_number)
147 LeftMost = LeftMost + 1; 150 left_most++;
148 XCoordinateR(ParNumber) = LeftMost; 151 x_coordinate_r(par_number) = left_most;
149 Max = min (Max, Level); 152 max_ht = min (max_ht, level);
150 if ((length(St) > 1) && (find((shift(St,1)-St) == 0) >1) 153 if (length(stk) > 1 && find ((shift(stk,1)-stk) == 0) > 1
151 && St(end,2) != St(end-1,2)) 154 && stk(end,2) != stk(end-1,2))
152 ## Return to the nearest branching the position to return 155 ## Return to the nearest branching the position to return
153 ## position is the position on the stack, where should be 156 ## position is the position on the stack, where should be
154 ## started further search (there are two nodes which has the 157 ## started further search (there are two nodes which has the
155 ## same parent node). 158 ## same parent node).
156 159
157 Position = (find ((shift (St(:, 2), 1) - St(:, 2)) == 0))(end)+1; 160 position = (find ((shift (stk(:,2), 1) - stk(:,2)) == 0))(end) + 1;
158 ParNumberVec = St(Position : end, 2); 161 par_number_vec = stk(position:end,2);
159 162
160 ## The vector of removed nodes (the content of stack form 163 ## The vector of removed nodes (the content of stack form
161 ## position to end). 164 ## position to end).
162 165
163 Level = Level + length(ParNumberVec); 166 level += length (par_number_vec);
164 167
165 ## The level have to be decreased. 168 ## The level have to be decreased.
166 169
167 XCoordinateR(ParNumberVec) = LeftMost; 170 x_coordinate_r(par_number_vec) = left_most;
168 St(Position:end, :) = []; 171 stk(position:end,:) = [];
169 endif 172 endif
170 173
171 ## Remove the next node from "searched branch". 174 ## Remove the next node from "searched branch".
172 175
173 St(end, :) = []; 176 stk(end,:) = [];
174 ## Choose new "parent node". 177 ## Choose new "parent node".
175 ParNumber = St(end, 1); 178 par_number = stk(end,1);
176 ## If there is another branch start to search it. 179 ## If there is another branch start to search it.
177 if (ParNumber != -1) 180 if (par_number != -1)
178 YCoordinate(ParNumber) = Level; 181 y_coordinate(par_number) = level;
179 XCoordinateL(ParNumber) = LeftMost + 1; 182 x_coordinate_l(par_number) = left_most + 1;
180 endif 183 endif
181 else 184 else
182 185
183 ## There were descendants of "parent nod" choose the last of 186 ## There were descendants of "parent nod" choose the last of
184 ## them and go on through it. 187 ## them and go on through it.
185 Level--; 188 level--;
186 ParNumber = St(end, 1); 189 par_number = stk(end,1);
187 YCoordinate(ParNumber) = Level; 190 y_coordinate(par_number) = level;
188 XCoordinateL(ParNumber) = LeftMost+1; 191 x_coordinate_l(par_number) = left_most + 1;
189 endif 192 endif
190 endwhile 193 endwhile
191 194
192 ## Calculate the x coordinates (the known values are the position 195 ## Calculate the x coordinates (the known values are the position
193 ## of most left and most right descendants). 196 ## of most left and most right descendants).
194 XCoordinate = (XCoordinateL + XCoordinateR) / 2; 197 x_coordinate = (x_coordinate_l + x_coordinate_r) / 2;
195 198
196 Height = NodNumber - Max - 1; 199 height = num_nodes - max_ht - 1;
197 endif 200 endif
198 endfunction 201 endfunction
199 202
200 %!demo 203 %!demo
201 %! % Compute a simple tree layout 204 %! % Compute a simple tree layout