Tree Compression with Top Trees Revisited
randomTree.cpp
Go to the documentation of this file.
1 #include <iostream>
2 
3 // Data Structures
4 #include "Edges.h"
5 #include "Labels.h"
6 #include "Nodes.h"
7 #include "OrderedTree.h"
8 #include "TopDag.h"
9 #include "TopTree.h"
10 
11 // Algorithms
12 #include "TopDagUnpacker.h"
13 #include "DotGraphExporter.h"
14 #include "RandomTree.h"
15 #include "TopDagConstructor.h"
16 
17 // Utils
18 #include "ArgParser.h"
19 #include "Timer.h"
20 #include "XML.h"
21 
22 using std::cout;
23 using std::endl;
24 
25 void usage(char* name) {
26  cout << "Usage: " << name << " <options>" << endl
27  << " -n <int> tree size (edges) (default: 10)" << endl
28  << " -l <int> number of distinct labels" << endl
29  << " -o <str> output XML filename (default: do not write)" << endl
30  << " -s <int> seed (default: 12345678)" << endl
31  << " -d dump DOT graph if tree is small enough" << endl
32  << " -c construct Top DAG" << endl
33  << " -v verbose output" << endl;
34 }
35 
36 int main(int argc, char **argv) {
37  ArgParser argParser(argc, argv);
38 
39  if (argParser.isSet("h") || argParser.isSet("-help")) {
40  usage(argv[0]);
41  return 0;
42  }
43 
44  const int size = argParser.get<int>("n", 10);
45  const int seed = argParser.get<int>("s", 12345678);
46  const int numLabels = argParser.get<int>("l", 2);
47  const std::string outfn = argParser.get<std::string>("o", "");
48  const bool dump = argParser.isSet("d");
49  const bool construct = argParser.isSet("c");
50  const bool verbose = argParser.isSet("v");
51 
52  // Initiliase
53  getRandomGenerator().seed(seed);
56 
57  // Generate the tree and the labels
58  Timer timer;
59  rand.generateTree(tree, size, (verbose && size < 1000));
60  RandomLabels<RandomGeneratorType> labels(size+1, numLabels, getRandomGenerator());
61 
62  if (verbose) cout << "Generated " << tree.summary() << " in " << timer.get() << "ms" << endl;
63  timer.reset();
64 
65  if (outfn != "") {
66  // Write output XML
67  XmlWriter<OrderedTree<TreeNode, TreeEdge>>::template write<int>(tree, labels, outfn);
68  }
69 
70  if (dump) {
71  // Dump some various stuff if the tree is small
72  if (size <= 30) cout << tree << endl;
73 
74  if (size <= 10000) {
75  OrderedTreeDotGraphExporter<TreeNode, TreeEdge, int>().write(tree, labels, "/tmp/tree.dot");
76  cout << "Wrote DOT file in " << timer.getAndReset() << "ms" << endl;
77  }
78 
79  if (size <= 1000) {
80  DotGraphExporter<OrderedTree<TreeNode, TreeEdge>>::drawSvg("/tmp/tree.dot", "/tmp/tree.svg");
81  cout << "Graphed DOT file in " << timer.getAndReset() << "ms" << endl;
82  }
83  }
84 
85  // Abort here if we don't want the top tree / DAG
86  if (!construct) {
87  return 0;
88  }
89 
90  const int treeEdges = tree._numEdges;
91  TopDag<int> dag(tree._numNodes, labels);
92  TopDagConstructor<OrderedTree<TreeNode, TreeEdge>, int> topDagConstructor(tree, dag);
93 
94  timer.reset();
95  topDagConstructor.construct();
96  if (verbose) cout << "Top DAG construction took " << timer.get() << "ms" << endl;
97  timer.reset();
98 
99  const int edges = dag.countEdges();
100  const double percentage = (edges * 100.0) / treeEdges;
101  const double ratio = ((int)(1000 / percentage)) / 10.0;
102  if (verbose)
103  cout << "Top dag has " << dag.nodes.size() - 1 << " nodes, " << edges << " edges (" << percentage
104  << "% of original tree, " << ratio << ":1)" << endl;
105 
106  if (dump) {
107  if (size <= 10000) {
108  TopDagDotGraphExporter<int>().write(dag, "/tmp/topdag.dot");
109  if (verbose) cout << "Wrote DOT file in " << timer.get() << "ms" << endl;
110  timer.reset();
111  }
112 
113  if (size <= 1000) {
114  TopDagDotGraphExporter<int>::drawSvg("/tmp/topdag.dot", "/tmp/topdag.svg");
115  if (verbose) cout << "Graphed DOT file in " << timer.get() << "ms" << endl;
116  timer.reset();
117  }
118  }
119 }
Export a tree as a DOT graph.
vector< DagNode< DataType > > nodes
Definition: TopDag.h:177
int main(int argc, char **argv)
Definition: randomTree.cpp:36
Ordered tree data structure.
Definition: OrderedTree.h:37
bool isSet(const string &arg) const
check whether an argument was set
Definition: ArgParser.h:58
ReturnType get() const
Definition: Timer.h:23
Export a Top DAG as a DOT graph.
void reset()
Definition: Timer.h:19
Uniformly random labels.
Definition: Labels.h:76
Parse command-line arguments.
Definition: ArgParser.h:21
std::mt19937 & getRandomGenerator()
shared random generator
Definition: Common.h:40
void construct(DebugInfo *debugInfo=NULL)
T get(const string &key, const T defaultValue=T())
Definition: ArgParser.h:44
Generates ordered unlabelled trees uniformly at random.
Definition: RandomTree.h:15
Transform a tree into its top tree.
void usage(char *name)
Definition: randomTree.cpp:25
string summary() const
A one-line summary of the tree.
Definition: OrderedTree.h:348
Base class for exporting various graphs (or trees) as DOT files.
A flexible timer.
Definition: Timer.h:14
XML tree writer (empty template for overloading)
Definition: XML.h:68
int countEdges() const
Count the number of edges in the DAG.
Definition: TopDag.h:87
ReturnType getAndReset()
Definition: Timer.h:29
static void drawSvg(const string &dotfile, const string &outfilename)
A binary DAG that is specialised to be a top tree's minimal DAG.
Definition: TopDag.h:46
void generateTree(TreeType &tree, const int numEdges, const bool verbose=false)
Definition: RandomTree.h:54