Orbiter 2022
Combinatorial Objects
tree.cpp
Go to the documentation of this file.
1// tree.cpp
2//
3// Anton Betten
4// February 7, 2003
5
6#include "foundations.h"
7
8using namespace std;
9
10
11namespace orbiter {
12namespace layer1_foundations {
13namespace graphics {
14
15
17{
18 root = NULL;
19
20 nb_nodes = 0;
21 max_depth = 0;
22 f_node_select = NULL;
23
24 path = NULL;
26 leaf_count = 0;
27}
28
30{
31 if (f_node_select) {
33 }
34}
35
36#define TREEPATHLEN 10000
37#define BUFSIZE_TREE 100000
38
40 int xmax, int ymax, int verbose_level)
41{
42 int f_v = (verbose_level >= 1);
43
44 if (f_v) {
45 cout << "tree::init reading tree from file " << Tree_draw_options->file_name << endl;
46 }
47 int f_vv = (verbose_level >= 1);
48 char *buf;
49 char *p_buf;
50 int l, a, i, nb_nodes;
51 char *c_data;
52 int path[TREEPATHLEN];
53 int color;
54 string dummy;
55 string label;
57
58 nb_nodes = 0;
60 {
61 ifstream f(Tree_draw_options->file_name);
62 //f.getline(buf, BUFSIZE_TREE);
63 while (TRUE) {
64 if (f.eof()) {
65 cout << "tree::init premature end of file" << endl;
66 exit(1);
67 }
68 f.getline(buf, BUFSIZE_TREE);
69
70 if (f_vv) {
71 cout << "tree::init read line '" << buf << "'" << endl;
72 }
73
74 p_buf = buf;
75 if (buf[0] == '#') {
76 continue;
77 }
78 ST.s_scan_int(&p_buf, &a);
79 if (a == -1) {
80 break;
81 }
82
83 if (Tree_draw_options->f_restrict) {
84 if (a == Tree_draw_options->restrict_excluded_color) {
85 continue;
86 }
87 }
88 nb_nodes++;
89 }
90 //s_scan_int(&p_buf, &nb_nodes);
91 }
92 if (f_v) {
93 cout << "tree::init found " << nb_nodes
94 << " nodes in file " << Tree_draw_options->file_name << endl;
95 }
96
97 if (f_v) {
98 cout << "tree::init calling root->init" << endl;
99 }
101 root->init(0 /* depth */,
102 NULL, FALSE, 0, FALSE, 0, dummy,
103 verbose_level - 1);
104
105 if (f_v) {
106 cout << "tree::init reading the file again" << endl;
107 }
108 {
109 ifstream f(Tree_draw_options->file_name);
110 //f.getline(buf, BUFSIZE_TREE);
111 while (TRUE) {
112 if (f.eof()) {
113 cout << "premature end of file" << endl;
114 exit(1);
115 }
116 f.getline(buf, BUFSIZE_TREE);
117 p_buf = buf;
118 if (buf[0] == '#') {
119 continue;
120 }
121 ST.s_scan_int(&p_buf, &l);
122 if (l == -1) {
123 break;
124 }
125 if (l >= TREEPATHLEN) {
126 cout << "tree::init overflow, please increase "
127 "the value of TREEPATHLEN" << endl;
128 cout << "l=" << l << endl;
129 exit(1);
130 }
131 if (f_vv) {
132 cout << "reading entry at depth " << l << endl;
133 }
134 for (i = 0; i < l; i++) {
135 ST.s_scan_int(&p_buf, &path[i]);
136 }
137
138 // read one more entry, the color of the node:
139 ST.s_scan_int(&p_buf, &color);
140
141 // skip over whitespace:
142 while (*p_buf == ' ') {
143 p_buf++;
144 }
145
146 // read the label:
147 c_data = p_buf;
148 for (i = 0; c_data[i]; i++) {
149 if (c_data[i] == '#') {
150 c_data[i] = 0;
151 break;
152 }
153 }
154 label.assign(c_data);
155
156 if (Tree_draw_options->f_restrict) {
157 if (color == Tree_draw_options->restrict_excluded_color) {
158 continue;
159 }
160 }
161
162
163 if (f_vv) {
164 cout << "tree::init trying to add node: " << buf << endl;
165 }
166 root->add_node(l, 0, path, color, label, 0/*verbose_level - 1*/);
167 if (f_vv) {
168 cout << "node added: " << buf << endl;
169 }
172 }
173 }
174 if (f_v) {
175 cout << "tree::init finished adding nodes, max_depth = " << max_depth << endl;
176 cout << "tree::init nb_nodes=" << tree::nb_nodes << endl;
177 }
178
179 if (f_vv) {
181 }
183
184 int my_nb_nodes;
185
186 if (f_v) {
187 cout << "tree::init before compute_DFS_ranks" << endl;
188 }
189 compute_DFS_ranks(my_nb_nodes, verbose_level);
190 if (f_v) {
191 cout << "tree::init after compute_DFS_ranks" << endl;
192 }
193
194 if (f_v) {
195 cout << "tree::init before root->calc_weight" << endl;
196 }
197 root->calc_weight();
198 if (f_v) {
199 cout << "tree::init after root->calc_weight" << endl;
200 }
201 if (f_v) {
202 cout << "tree::init before root->place_xy" << endl;
203 }
204 root->place_xy(0, xmax, ymax, max_depth);
205 if (f_v) {
206 cout << "tree::init after root->place_xy" << endl;
207 }
208 if (f_v) {
209 cout << "tree::init before print_depth_first" << endl;
211 cout << "tree::init after print_depth_first" << endl;
212 }
213 FREE_char(buf);
214
215
216
217
218 if (f_v) {
219 cout << "tree::init done" << endl;
220 }
221
222}
223
224void tree::draw(std::string &fname,
225 graphics::tree_draw_options *Tree_draw_options,
227 int verbose_level)
228{
229 int f_v = (verbose_level >= 1);
230
231 if (f_v) {
232 cout << "tree::draw" << endl;
233 }
234 string fname_full;
235
236 fname_full.assign(fname);
237 fname_full.append(".mp");
238
239#if 0
240 if (f_edge_labels) {
241 strcat(fname_full, "e");
242 }
243#endif
244
245 if (f_v) {
246 cout << "tree::draw before draw_preprocess" << endl;
247 }
248 draw_preprocess(fname,
249 Tree_draw_options,
250 Opt,
251 verbose_level);
252 if (f_v) {
253 cout << "tree::draw after draw_preprocess" << endl;
254 }
255
256 {
257 int factor_1000 = 1000;
258
259 mp_graphics G;
260 G.init(fname_full, Opt, verbose_level);
261
262 G.header();
263 G.begin_figure(factor_1000);
264
265
266 //G.frame(0.05);
267
268#if 0
269 int x = 500000, y;
270 calc_y_coordinate(y, 0, max_depth);
271
272 if (f_circletext) {
273 G.circle_text(x, y, "$\\emptyset$");
274 }
275 else {
276 G.circle(x, y, 5);
277 }
278#endif
279
280 //root->draw_sideways(G, f_circletext, f_i,
281 //FALSE, 10000 - 0, 10000 - 0, max_depth, f_edge_labels);
282
283
284#if 0
285 int *radii = NULL;
286 int x0, y0;
287 if (f_on_circle) {
288 int l;
289
290#if 1
291 G.sl_thickness(30); // 100 is normal
292 //G.sl_thickness(200); // 100 is normal
293 circle_center_and_radii(xmax_in, ymax_in, max_depth, x0, y0, radii);
294 for (l = 1; l <= max_depth; l++) {
295 G.circle(x0, y0, radii[l]);
296 }
297#endif
298 }
299#endif
300
301
302 G.sl_thickness(30); // 100 is normal
303
304
305
306 leaf_count = 0;
307
308 //int f_circletext = TRUE;
309 //int f_i = TRUE;
310
311
312 if (f_v) {
313 cout << "tree::draw before root->draw_edges" << endl;
314 }
316 G, Tree_draw_options, Opt,
317 FALSE, 0, 0,
318 max_depth,
319 this, verbose_level);
320 if (f_v) {
321 cout << "tree::draw after root->draw_edges" << endl;
322 }
323
324 G.sl_thickness(10); // 100 is normal
325
326
327 if (f_v) {
328 cout << "tree::draw before root->draw_vertices" << endl;
329 }
330 root->draw_vertices(G, Tree_draw_options, Opt,
331 FALSE, 0, 0,
332 max_depth,
333 this, verbose_level);
334 if (f_v) {
335 cout << "tree::draw after root->draw_vertices" << endl;
336 }
337
338#if 0
339 if (f_on_circle) {
340 FREE_int(radii);
341 }
342#endif
343
344
345 G.end_figure();
346 G.footer();
347 }
349
350 cout << "written file " << fname_full << " of size "
351 << Fio.file_size(fname_full) << endl;
352 if (f_v) {
353 cout << "tree::draw done" << endl;
354 }
355
356}
357
358void tree::draw_preprocess(std::string &fname,
359 graphics::tree_draw_options *Tree_draw_options,
361 int verbose_level)
362{
363 int f_v = (verbose_level >= 1);
364
365 if (f_v) {
366 cout << "tree::draw_preprocess" << endl;
367 }
368 if (Tree_draw_options->f_select_path) {
369 int rk;
370 int *my_path;
371 int sz;
372
373 rk = 0;
374
375 if (f_v) {
376 cout << "tree::draw_preprocess before root->compute_DFS_rank" << endl;
377 }
379 nb_nodes = rk;
380
382
384 Int_vec_scan(Tree_draw_options->select_path_text, my_path, sz);
385
386 if (f_v) {
387 cout << "tree::draw_preprocess my_path = ";
388 Int_vec_print(cout, my_path, sz);
389 cout << endl;
390 }
391
392 if (FALSE) {
393 int DFS_rk;
394 root->find_node(DFS_rk, my_path, sz, verbose_level);
395 if (f_v) {
396 cout << "tree::draw_preprocess my_path = ";
397 Int_vec_print(cout, my_path, sz);
398 cout << " rk=" << DFS_rk << endl;
399 }
400 f_node_select[DFS_rk] = TRUE;
401 }
402 else {
403 int i, a;
404 std::vector<int> Rk;
405 root->find_node_and_path(Rk, my_path, sz, verbose_level);
406 for (i = 0; i < Rk.size(); i++) {
407 a = Rk[i];
408 f_node_select[a] = TRUE;
409 }
410 }
411
412
413 }
414 if (f_v) {
415 cout << "tree::draw_preprocess done" << endl;
416 }
417}
418
419
420void tree::circle_center_and_radii(int xmax, int ymax,
421 int max_depth, int &x0, int &y0, int *&rad)
422{
423 int l, dy;
424 double y;
425 tree_node N;
426
427 x0 = xmax * 0.5;
428 y0 = ymax * 0.5;
429 rad = NEW_int(max_depth + 1);
430 for (l = 0; l <= max_depth; l++) {
431 dy = (int)((double)ymax / (double)(max_depth + 1));
432 y = N.calc_y_coordinate(ymax, l, max_depth);
433 y = ymax - y;
434 y -= dy * 0.5;
435 y /= ymax;
436 rad[l] = y * xmax * 0.5;
437 }
438}
439
440void tree::compute_DFS_ranks(int &nb_nodes, int verbose_level)
441{
442 int f_v = (verbose_level >= 1);
443 int rk;
444
445 if (f_v) {
446 cout << "tree::compute_DFS_ranks" << endl;
447 }
448 rk = 0;
450 nb_nodes = rk;
451 if (f_v) {
452 cout << "tree::compute_DFS_ranks done" << endl;
453 }
454}
455
456}}}
457
458
459
460
functions related to strings and character arrays
options for drawing an object of type layered_graph
Definition: graphics.h:457
a general 2D graphical output interface (metapost, tikz, postscript)
Definition: graphics.h:545
void init(std::string &file_name, layered_graph_draw_options *Draw_options, int verbose_level)
Definition: mp_graphics.cpp:71
void circle_text(int x, int y, int rad, const char *text)
part of the data structure tree
Definition: graphics.h:1547
void draw_edges(mp_graphics &G, tree_draw_options *Tree_draw_options, layered_graph_draw_options *Opt, int f_has_parent, int parent_x, int parent_y, int max_depth, tree *T, int verbose_level)
Definition: tree_node.cpp:363
int find_node(int &DFS_rk, int *path, int sz, int verbose_level)
Definition: tree_node.cpp:123
void place_xy(int left, int right, int ymax, int max_depth)
Definition: tree_node.cpp:224
int calc_y_coordinate(int ymax, int l, int max_depth)
Definition: tree_node.cpp:701
void draw_vertices(mp_graphics &G, tree_draw_options *Tree_draw_options, layered_graph_draw_options *Opt, int f_has_parent, int parent_x, int parent_y, int max_depth, tree *T, int verbose_level)
Definition: tree_node.cpp:460
void add_node(int l, int depth, int *path, int color, std::string &label, int verbose_level)
Definition: tree_node.cpp:270
int find_node_and_path(std::vector< int > &Rk, int *path, int sz, int verbose_level)
Definition: tree_node.cpp:155
void init(int depth, tree_node *parent, int f_value, int value, int f_has_color, int color, std::string &label, int verbose_level)
Definition: tree_node.cpp:51
void circle_center_and_radii(int xmax, int ymax, int max_depth, int &x0, int &y0, int *&rad)
Definition: tree.cpp:420
void compute_DFS_ranks(int &nb_nodes, int verbose_level)
Definition: tree.cpp:440
void draw(std::string &fname, graphics::tree_draw_options *Tree_draw_options, layered_graph_draw_options *Opt, int verbose_level)
Definition: tree.cpp:224
void draw_preprocess(std::string &fname, graphics::tree_draw_options *Tree_draw_options, layered_graph_draw_options *Opt, int verbose_level)
Definition: tree.cpp:358
void init(graphics::tree_draw_options *Tree_draw_options, int xmax, int ymax, int verbose_level)
Definition: tree.cpp:39
#define Int_vec_scan(A, B, C)
Definition: foundations.h:716
#define FREE_int(p)
Definition: foundations.h:640
#define Int_vec_zero(A, B)
Definition: foundations.h:713
#define NEW_char(n)
Definition: foundations.h:632
#define NEW_OBJECT(type)
Definition: foundations.h:638
#define NEW_int(n)
Definition: foundations.h:625
#define TRUE
Definition: foundations.h:231
#define FALSE
Definition: foundations.h:234
#define FREE_char(p)
Definition: foundations.h:646
#define Int_vec_print(A, B, C)
Definition: foundations.h:685
#define MAXIMUM(x, y)
Definition: foundations.h:217
the orbiter library for the classification of combinatorial objects
#define BUFSIZE_TREE
Definition: tree.cpp:37
#define TREEPATHLEN
Definition: tree.cpp:36