Open
Graph Drawing
Framework

 v. 2023.09 (Elderberry)
 

Loading...
Searching...
No Matches
pctree.cpp
Go to the documentation of this file.
1#include <ogdf/basic/Graph.h>
3#include <ogdf/basic/basic.h>
11#include <functional>
12#include <iostream>
13#include <sstream>
14#include <string>
15#include <vector>
16
17using namespace ogdf;
18using namespace pc_tree;
19
20int main() {
21 // create a tree with a given number of leaves
22 std::vector<PCNode*> leaves;
23 PCTree tree(7, &leaves);
24
25 // the tree allows any order of its leaves
26 OGDF_ASSERT(tree.isTrivial());
27 OGDF_ASSERT(tree.getLeafCount() == 7);
28 OGDF_ASSERT(tree.getPNodeCount() == 1);
29 OGDF_ASSERT(tree.getCNodeCount() == 0);
30 OGDF_ASSERT(tree.possibleOrders<int>() == factorial(6));
31 OGDF_ASSERT(tree.uniqueID(uid_utils::nodeToPosition) == "7:(6, 5, 4, 3, 2, 1, 0)");
32
33 // now we can force some leaves to be consecutive in all represented orders
34 tree.makeConsecutive({leaves.at(3), leaves.at(4), leaves.at(5)});
35 OGDF_ASSERT(tree.uniqueID(uid_utils::nodeToPosition) == "8:(7:(5, 4, 3), 6, 2, 1, 0)");
36 OGDF_ASSERT(tree.getPNodeCount() == 2);
37 OGDF_ASSERT(tree.possibleOrders<int>() == factorial(3) * factorial(4));
38
39 // further updates further change the tree
40 tree.makeConsecutive({leaves.at(4), leaves.at(5)});
41 OGDF_ASSERT(tree.uniqueID(uid_utils::nodeToPosition) == "9:(8:[7:[5, 4], 3], 6, 2, 1, 0)");
42
43 tree.makeConsecutive({leaves.at(0), leaves.at(1)});
44 OGDF_ASSERT(tree.uniqueID(uid_utils::nodeToPosition) == "10:(9:[8:[5, 4], 3], 7:[1, 0], 6, 2)");
45
46 tree.makeConsecutive({leaves.at(1), leaves.at(2)});
47 OGDF_ASSERT(tree.uniqueID(uid_utils::nodeToPosition) == "10:[9:[8:[5, 4], 3], 7:[2, 1, 0], 6]");
48
49 tree.makeConsecutive({leaves.at(2), leaves.at(3), leaves.at(4), leaves.at(5)});
50 OGDF_ASSERT(tree.uniqueID(uid_utils::nodeToPosition) == "9:[6, 8:[7:[5, 4], 3], 2, 1, 0]");
51
52 // if some leaves cannot be made consecutive, the update returns false and leaves the tree unchanged
53 OGDF_ASSERT(tree.makeConsecutive({leaves.at(2), leaves.at(0)}) == false);
54 OGDF_ASSERT(tree.uniqueID(uid_utils::nodeToPosition) == "9:[6, 8:[7:[5, 4], 3], 2, 1, 0]");
55 OGDF_ASSERT(tree.possibleOrders<int>() == 8);
56
57 // we can query the (arbitrary) current order of leaves and check whether any order is represented by the tree
58 std::vector<PCNode*> currentLeafOrder =
59 tree.currentLeafOrder(); // same entries as `leaves`, different order
60 OGDF_ASSERT(tree.isValidOrder(currentLeafOrder));
61 // use tree.getLeaves() to get the leaves in creation order
62
63 // iterator for all inner nodes
64 auto innerNode_it = tree.innerNodes();
65 std::vector<PCNode*> innerNodes {innerNode_it.begin(), innerNode_it.end()};
66 OGDF_ASSERT(innerNodes.size() == tree.getPNodeCount() + tree.getCNodeCount());
67 OGDF_ASSERT(innerNodes.front() == tree.getRootNode());
68
69 // we can also manually walk the tree
70 PCNode* root = tree.getRootNode();
71 OGDF_ASSERT(root->getChildCount() == 5); // 6, 8:[...], 2, 1, 0
72 OGDF_ASSERT(root->getChild1()->isLeaf());
73 for (PCNode* n : root->children()) {
74 std::cout << n->index() << " ";
75 }
76 std::cout << std::endl;
77
78 // we can visualize the PCTree
82 tree.getTree(G, &GA, pc_repr);
84 l.rootSelection(RadialTreeLayout::RootSelectionType::Source);
85 l.call(GA);
86 GraphIO::write(GA, "pctree.svg");
87
88 // PCTrees can also be reconstructed from strings
89 PCTree from_string {"9:[6, 8:[7:[5, 4], 3], 2, 1, 0]", true};
90 OGDF_ASSERT(from_string.getLeafCount() == tree.getLeafCount());
91 OGDF_ASSERT(from_string.possibleOrders<int>() == tree.possibleOrders<int>());
92 OGDF_ASSERT(from_string.uniqueID(uid_utils::nodeToPosition) == "9:[6, 8:[7:[5, 4], 3], 2, 1, 0]");
93 // tree.getRestrictions() yields a list of updated via which the tree can also be reconstructed
94
95 // alternatively, they can also be constructed manually
96 PCTree manual;
97 auto nr = manual.newNode(pc_tree::PCNodeType::CNode);
98 auto n1 = manual.newNode(pc_tree::PCNodeType::PNode, nr);
99 manual.insertLeaves(3, nr);
100 auto n2 = manual.newNode(pc_tree::PCNodeType::PNode, nr);
101 manual.insertLeaves(3, n2);
102 manual.insertLeaves(3, nr);
103 manual.insertLeaves(3, n1);
104 std::stringstream ss;
105 ss << manual;
106 OGDF_ASSERT(ss.str() == "0:[11, 10, 9, 5:(8, 7, 6), 4, 3, 2, 1:(14, 13, 12)]");
107
108 return 0;
109}
Includes declaration of graph class.
Declaration of class GraphAttributes which extends a Graph by additional attributes.
Declares class GraphIO which provides access to all graph read and write functionality.
Predeclaration of various PC-tree related classes and enums.
A node in a PC-tree that is either a P-node, C-node or leaf.
A registry that allows labelling the nodes of a PC-tree.
The main class of the PC-tree.
Utils for PCTree::allNodes(), PCTree::innerNodes(), PCNode::children() and PCNode::neighbors().
Declaration of linear time layout algorithm for free trees (class RadialTreeLayout).
Basic declarations, included by all source files.
Stores additional attributes of a graph (like layout information).
Data type for general directed graphs (adjacency list representation).
Definition Graph_d.h:866
static bool write(const Graph &G, const string &filename, WriterFunc writer=nullptr)
Writes graph G to a file with name filename and infers the format to use from the file's extension.
The radial tree layout algorithm.
RootSelectionType rootSelection() const
Returns the option rootSelection.
virtual void call(GraphAttributes &GA) override
Calls the algorithm for graph attributes GA.
Dynamic arrays indexed with arbitrary keys.
A node in a PC-tree that is either a P-node, C-node or leaf.
Definition PCNode.h:62
bool isLeaf() const
Definition PCNode.h:310
PCNode * getChild1() const
Definition PCNode.h:460
PCNodeChildrenIterable children()
size_t getChildCount() const
Definition PCNode.h:456
A PC-tree represents a set of cyclic orders of its leaves by labeling its inner nodes as either P- or...
Definition PCTree.h:118
void insertLeaves(int count, PCNode *parent, std::vector< PCNode * > *added=nullptr)
Attach count leaves to P- or C-node parent and optionally store the new leaves in a vector added.
PCNode * newNode(PCNodeType type, PCNode *parent=nullptr, int id=-1)
Create a new node.
#define OGDF_ASSERT(expr)
Assert condition expr. See doc/build.md for more information.
Definition basic.h:52
void nodeToPosition(std::ostream &os, PCNode *n, int pos)
Print the position pos of a node n.
int factorial(int n)
The namespace for all OGDF objects.
@ tree
for every hyperedge e a minimal subcubic tree connecting all hypernodes incident with e together is a...
int main()
Definition pctree.cpp:20