Open
Graph Drawing
Framework

 v. 2023.09 (Elderberry)
 

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 
17 using namespace ogdf;
18 using namespace pc_tree;
19 
20 int 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
79  ogdf::Graph G;
82  tree.getTree(G, &GA, pc_repr);
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 }
ogdf
The namespace for all OGDF objects.
Definition: multilevelmixer.cpp:39
ogdf::GraphAttributes
Stores additional attributes of a graph (like layout information).
Definition: GraphAttributes.h:72
GraphAttributes.h
Declaration of class GraphAttributes which extends a Graph by additional attributes.
ogdf::RegisteredArray
Dynamic arrays indexed with arbitrary keys.
Definition: RegisteredArray.h:817
ogdf::pc_tree::PCNodeType::CNode
@ CNode
Graph.h
Includes declaration of graph class.
ogdf::pc_tree::uid_utils::nodeToPosition
void nodeToPosition(std::ostream &os, PCNode *n, int pos)
Print the position pos of a node n.
ogdf::GraphIO::write
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.
OGDF_ASSERT
#define OGDF_ASSERT(expr)
Assert condition expr. See doc/build.md for more information.
Definition: basic.h:66
ogdf::pc_tree::PCNodeType::PNode
@ PNode
ogdf::pc_tree::PCTree
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
ogdf::pc_tree::PCNode::getChild1
PCNode * getChild1() const
Definition: PCNode.h:460
ogdf::pc_tree::PCNode::isLeaf
bool isLeaf() const
Definition: PCNode.h:310
ogdf::pc_tree::PCTree::insertLeaves
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.
ogdf::pc_tree::PCNode::getChildCount
size_t getChildCount() const
Definition: PCNode.h:456
RadialTreeLayout.h
Declaration of linear time layout algorithm for free trees (class RadialTreeLayout).
ogdf::RadialTreeLayout::call
virtual void call(GraphAttributes &GA) override
Calls the algorithm for graph attributes GA.
GraphIO.h
Declares class GraphIO which provides access to all graph read and write functionality.
ogdf::pc_tree::factorial
int factorial(int n)
Returns n!.
Definition: Math.h:147
PCRegistry.h
A registry that allows labelling the nodes of a PC-tree.
main
int main()
Definition: pctree.cpp:20
ogdf::RadialTreeLayout::RootSelectionType::Source
@ Source
Select a source in the graph.
ogdf::Graph
Data type for general directed graphs (adjacency list representation).
Definition: Graph_d.h:869
ogdf::RadialTreeLayout
The radial tree layout algorithm.
Definition: RadialTreeLayout.h:65
ogdf::EdgeStandardType::tree
@ tree
for every hyperedge e a minimal subcubic tree connecting all hypernodes incident with e together is a...
PCEnum.h
Predeclaration of various PC-tree related classes and enums.
PCTreeIterators.h
Utils for PCTree::allNodes(), PCTree::innerNodes(), PCNode::children() and PCNode::neighbors().
ogdf::pc_tree::PCTree::newNode
PCNode * newNode(PCNodeType type, PCNode *parent=nullptr, int id=-1)
Create a new node.
ogdf::pc_tree::PCNode
A node in a PC-tree that is either a P-node, C-node or leaf.
Definition: PCNode.h:62
PCNode.h
A node in a PC-tree that is either a P-node, C-node or leaf.
ogdf::pc_tree::PCNode::children
PCNodeChildrenIterable children()
basic.h
Basic declarations, included by all source files.
ogdf::RadialTreeLayout::rootSelection
RootSelectionType rootSelection() const
Returns the option rootSelection.
Definition: RadialTreeLayout.h:136
PCTree.h
The main class of the PC-tree.