Open
Graph Drawing
Framework

 v. 2023.09 (Elderberry)
 

pctree.cpp
Go to the documentation of this file.
1 #include <ogdf/basic/Graph.h>
5 
6 using namespace ogdf;
7 using namespace pc_tree;
8 
9 int main() {
10  // create a tree with a given number of leaves
11  std::vector<PCNode*> leaves;
12  PCTree tree(7, &leaves);
13 
14  // the tree allows any order of its leaves
15  OGDF_ASSERT(tree.isTrivial());
16  OGDF_ASSERT(tree.getLeafCount() == 7);
17  OGDF_ASSERT(tree.getPNodeCount() == 1);
18  OGDF_ASSERT(tree.getCNodeCount() == 0);
19  OGDF_ASSERT(tree.possibleOrders<int>() == factorial(6));
20  OGDF_ASSERT(tree.uniqueID(uid_utils::nodeToPosition) == "7:(6, 5, 4, 3, 2, 1, 0)");
21 
22  // now we can force some leaves to be consecutive in all represented orders
23  tree.makeConsecutive({leaves.at(3), leaves.at(4), leaves.at(5)});
24  OGDF_ASSERT(tree.uniqueID(uid_utils::nodeToPosition) == "8:(7:(5, 4, 3), 6, 2, 1, 0)");
25  OGDF_ASSERT(tree.getPNodeCount() == 2);
26  OGDF_ASSERT(tree.possibleOrders<int>() == factorial(3) * factorial(4));
27 
28  // further updates further change the tree
29  tree.makeConsecutive({leaves.at(4), leaves.at(5)});
30  OGDF_ASSERT(tree.uniqueID(uid_utils::nodeToPosition) == "9:(8:[7:[5, 4], 3], 6, 2, 1, 0)");
31 
32  tree.makeConsecutive({leaves.at(0), leaves.at(1)});
33  OGDF_ASSERT(tree.uniqueID(uid_utils::nodeToPosition) == "10:(9:[8:[5, 4], 3], 7:[1, 0], 6, 2)");
34 
35  tree.makeConsecutive({leaves.at(1), leaves.at(2)});
36  OGDF_ASSERT(tree.uniqueID(uid_utils::nodeToPosition) == "10:[9:[8:[5, 4], 3], 7:[2, 1, 0], 6]");
37 
38  tree.makeConsecutive({leaves.at(2), leaves.at(3), leaves.at(4), leaves.at(5)});
39  OGDF_ASSERT(tree.uniqueID(uid_utils::nodeToPosition) == "9:[6, 8:[7:[5, 4], 3], 2, 1, 0]");
40 
41  // if some leaves cannot be made consecutive, the update returns false and leaves the tree unchanged
42  OGDF_ASSERT(tree.makeConsecutive({leaves.at(2), leaves.at(0)}) == false);
43  OGDF_ASSERT(tree.uniqueID(uid_utils::nodeToPosition) == "9:[6, 8:[7:[5, 4], 3], 2, 1, 0]");
44  OGDF_ASSERT(tree.possibleOrders<int>() == 8);
45 
46  // we can query the (arbitrary) current order of leaves and check whether any order is represented by the tree
47  std::vector<PCNode*> currentLeafOrder =
48  tree.currentLeafOrder(); // same entries as `leaves`, different order
49  OGDF_ASSERT(tree.isValidOrder(currentLeafOrder));
50  // use tree.getLeaves() to get the leaves in creation order
51 
52  // iterator for all inner nodes
53  auto innerNode_it = tree.innerNodes();
54  std::vector<PCNode*> innerNodes {innerNode_it.begin(), innerNode_it.end()};
55  OGDF_ASSERT(innerNodes.size() == tree.getPNodeCount() + tree.getCNodeCount());
56  OGDF_ASSERT(innerNodes.front() == tree.getRootNode());
57 
58  // we can also manually walk the tree
59  PCNode* root = tree.getRootNode();
60  OGDF_ASSERT(root->getChildCount() == 5); // 6, 8:[...], 2, 1, 0
61  OGDF_ASSERT(root->getChild1()->isLeaf());
62  for (PCNode* n : root->children()) {
63  std::cout << n->index() << " ";
64  }
65  std::cout << std::endl;
66 
67  // we can visualize the PCTree
68  ogdf::Graph G;
71  tree.getTree(G, &GA, pc_repr);
74  l.call(GA);
75  GraphIO::write(GA, "pctree.svg");
76 
77  // PCTrees can also be reconstructed from strings
78  PCTree from_string {"9:[6, 8:[7:[5, 4], 3], 2, 1, 0]", true};
79  OGDF_ASSERT(from_string.getLeafCount() == tree.getLeafCount());
80  OGDF_ASSERT(from_string.possibleOrders<int>() == tree.possibleOrders<int>());
81  OGDF_ASSERT(from_string.uniqueID(uid_utils::nodeToPosition) == "9:[6, 8:[7:[5, 4], 3], 2, 1, 0]");
82  // tree.getRestrictions() yields a list of updated via which the tree can also be reconstructed
83 
84  // alternatively, they can also be constructed manually
85  PCTree manual;
86  auto nr = manual.newNode(pc_tree::PCNodeType::CNode);
87  auto n1 = manual.newNode(pc_tree::PCNodeType::PNode, nr);
88  manual.insertLeaves(3, nr);
89  auto n2 = manual.newNode(pc_tree::PCNodeType::PNode, nr);
90  manual.insertLeaves(3, n2);
91  manual.insertLeaves(3, nr);
92  manual.insertLeaves(3, n1);
93  std::stringstream ss;
94  ss << manual;
95  OGDF_ASSERT(ss.str() == "0:[11, 10, 9, 5:(8, 7, 6), 4, 3, 2, 1:(14, 13, 12)]");
96 
97  return 0;
98 }
ogdf
The namespace for all OGDF objects.
Definition: AugmentationModule.h:36
ogdf::GraphAttributes
Stores additional attributes of a graph (like layout information).
Definition: GraphAttributes.h:66
ogdf::RegisteredArray
Dynamic arrays indexed with arbitrary keys.
Definition: RegisteredArray.h:808
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:54
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:109
ogdf::pc_tree::PCNode::getChild1
PCNode * getChild1() const
Definition: PCNode.h:456
ogdf::pc_tree::PCNode::isLeaf
bool isLeaf() const
Definition: PCNode.h:306
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:452
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:143
main
int main()
Definition: pctree.cpp:9
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:862
ogdf::RadialTreeLayout
The radial tree layout algorithm.
Definition: RadialTreeLayout.h:60
ogdf::EdgeStandardType::tree
@ tree
for every hyperedge e a minimal subcubic tree connecting all hypernodes incident with e together is a...
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:58
ogdf::pc_tree::PCNode::children
PCNodeChildrenIterable children()
ogdf::RadialTreeLayout::rootSelection
RootSelectionType rootSelection() const
Returns the option rootSelection.
Definition: RadialTreeLayout.h:131
PCTree.h
The main class of the PC-tree.