|
Open Graph Drawing Framework |
v. 2023.09 (Elderberry)
|
|
|
Go to the documentation of this file.
46 #include <initializer_list>
54 class GraphAttributes;
134 size_t m_pNodeCount = 0;
135 size_t m_cNodeCount = 0;
142 size_t m_partialCount = 0;
143 size_t m_terminalPathLength = 0;
147 bool m_apexCandidateIsFix =
false;
151 bool m_externalForest =
true;
167 m_externalForest =
true;
170 m_externalForest =
false;
178 explicit PCTree(
int leafNum, std::vector<PCNode*>* added =
nullptr,
195 explicit PCTree(
const std::string& str,
bool keep_ids =
false,
PCTreeForest* forest =
nullptr);
232 void insertLeaves(
int count,
PCNode* parent, std::vector<PCNode*>* added =
nullptr);
237 void replaceLeaf(
int leafCount,
PCNode* leaf, std::vector<PCNode*>* added =
nullptr);
247 bool assumeConsecutive =
false) {
248 return mergeLeaves(consecutiveLeaves.begin(), consecutiveLeaves.end(), assumeConsecutive);
258 template<
typename It>
262 if (!assumeConsecutive && !makeConsecutive(
begin,
end)) {
268 for (
auto it =
begin; it != back; ++it) {
284 void destroyLeaf(
PCNode* leaf);
337 return makeConsecutive(consecutiveLeaves.begin(), consecutiveLeaves.end());
341 return makeConsecutive(consecutiveLeaves.begin(), consecutiveLeaves.end());
351 template<
typename It>
354 for (
auto obs : m_observers) {
355 obs->makeConsecutiveCalled(*
this, iter);
362 for (
auto it =
begin; it !=
end; ++it) {
370 for (
auto obs : m_observers) {
371 obs->makeConsecutiveDone(*
this, Observer::Stage::Trivial,
true);
380 return makeFullNodesConsecutive();
388 m_firstPartial = m_lastPartial =
nullptr;
390 m_apexCandidate =
nullptr;
391 m_apexCandidateIsFix =
false;
392 m_terminalPathLength = 0;
393 m_apexTPPred2 =
nullptr;
400 template<
typename It>
402 for (
auto it =
begin; it !=
end; ++it) {
416 template<
typename It>
420 if (fullNodeOrder !=
nullptr) {
421 fullNodeOrder->reserve(m_cNodeCount + m_pNodeCount);
424 for (
auto it =
begin; it !=
end; ++it) {
425 PCNode* full_parent = markFull(*it, fullNodeOrder);
426 while (full_parent !=
nullptr) {
427 full_parent = markFull(full_parent, fullNodeOrder);
438 bool makeFullNodesConsecutive();
443 PCNode* markFull(
PCNode* full_node, std::vector<PCNode*>* fullNodeOrder =
nullptr);
445 bool findTerminalPath();
447 void updateSingletonTerminalPath();
449 PCNode* createCentralNode();
451 int updateTerminalPath(
PCNode* central,
PCNode* tpNeigh);
455 void addPartialNode(
PCNode* partial);
457 void removePartialNode(
PCNode* partial);
464 bool setApexCandidate(
PCNode* ac,
bool fix =
false);
494 void restoreSubtrees(
PCTreeNodeArray<std::vector<PCNode*>>& blockNodes,
511 [[nodiscard]]
bool isTrivial()
const;
537 template<
typename Container>
540 if (leaf->isLeaf()) {
541 container.push_back(leaf);
548 std::vector<PCNode*> container;
549 currentLeafOrder(container);
554 bool checkValid(
bool allow_small_deg =
true)
const;
557 bool isValidOrder(
const std::vector<PCNode*>& order)
const;
562 bool mark_full =
false,
bool show_sibs =
false)
const;
568 void getRestrictions(std::vector<std::vector<PCNode*>>& restrictions,
569 PCNode* fixedLeaf =
nullptr)
const;
579 R children(
node->getChildCount());
580 if (
node == m_rootNode) {
594 std::ostream& uniqueID(std::ostream& os,
600 [[maybe_unused]]
const std::function<
bool(
PCNode*,
PCNode*)>& compareNodes =
602 std::stringstream sb;
603 uniqueID(sb, printNode, compareNodes);
613 template<
typename It>
635 enum class Stage { Trivial, NoPartials, InvalidTP, SingletonTP, Done };
643 [[maybe_unused]]
PCNode* firstPartial, [[maybe_unused]]
PCNode* lastPartial,
644 [[maybe_unused]]
int partialCount) {};
647 [[maybe_unused]]
PCNode* apexTPPred2, [[maybe_unused]]
int terminalPathLength) {};
650 [[maybe_unused]]
PCNode* central) {};
653 [[maybe_unused]]
PCNode* tpNeigh) {};
656 [[maybe_unused]]
PCNode* mergedNode) {};
659 [[maybe_unused]]
PCNode* tpPred, [[maybe_unused]]
PCNode* fullNeigh) {};
662 [[maybe_unused]]
PCNode* tpNeigh, [[maybe_unused]]
bool tpNeighSiblingsFlipped,
663 [[maybe_unused]]
PCNode* fullNeigh, [[maybe_unused]]
PCNode* fullOuterChild) {};
666 [[maybe_unused]]
PCNode* fullNode) {};
669 [[maybe_unused]]
Stage stage, [[maybe_unused]]
bool success) {};
672 [[maybe_unused]]
PCNode* apexCandidate, [[maybe_unused]]
PCNode* central,
673 [[maybe_unused]]
PCNode* parent) {};
676 [[maybe_unused]]
PCNode* toBeDeleted) {};
678 [[maybe_unused]]
PCNode* replacement) {};
685 int partialCount)
override;
688 int terminalPathLength)
override;
694 void makeConsecutiveDone(
PCTree&
tree,
Stage stage,
bool success)
override;
698 m_observers.push_back(observer);
699 return --m_observers.end();
702 void removeObserver(std::list<Observer*>::const_iterator it) { m_observers.erase(it); }
The namespace for all OGDF objects.
Stores additional attributes of a graph (like layout information).
Dynamic arrays indexed with arbitrary keys.
size_t getPNodeCount() const
Includes declaration of graph class.
void nodeToPosition(std::ostream &os, PCNode *n, int pos)
Print the position pos of a node n.
FilteringPCTreeWalk< true > FilteringPCTreeDFS
void resetTempData()
Reset all makeConsecutive()-related temporary information, especially which leaves are full (should b...
std::list< Observer * >::const_iterator addObserver(Observer *observer)
#define OGDF_ASSERT(expr)
Assert condition expr. See doc/build.md for more information.
PCTreeForest * getForest() const
The PCTreeForest this PCTree belongs to, or nullptr.
HypergraphRegistry< HypernodeElement >::iterator begin(const HypergraphRegistry< HypernodeElement > &self)
bool makeConsecutive(std::initializer_list< PCNode * > consecutiveLeaves)
#define OGDF_HEAVY_ASSERT(expr)
Assert condition expr when using heavy debugging. See OGDF_ASSERT.
A PC-tree represents a set of cyclic orders of its leaves by labeling its inner nodes as either P- or...
virtual void makeConsecutiveDone([[maybe_unused]] PCTree &tree, [[maybe_unused]] Stage stage, [[maybe_unused]] bool success)
An intrusive list for the leaves of a PCTree. TODO should be moved to a central location; merge with ...
void destroyNode(PCNode *&node)
Destroy a node.
FilteringPCTreeDFS innerNodes() const
An iterable through all inner (non-leaf) nodes of this PCTree.
A registry that allows labelling the nodes of a PC-tree.
IntrusiveList< PCNode > m_leaves
virtual void centralCreated([[maybe_unused]] PCTree &tree, [[maybe_unused]] PCNode *central)
bool makeConsecutive(const std::vector< PCNode * > &consecutiveLeaves)
PCTreeRegistry m_nodeArrayRegistry
Interface for Observers that can be notified of all changes made to the tree during an update.
PCTree(PCTreeForest *forest)
Constructs a new PCTree that is part of forest and can thus be merged with any other PCTree of the sa...
virtual void afterMerge([[maybe_unused]] PCTree &tree, [[maybe_unused]] PCNode *successor, [[maybe_unused]] PCNode *mergedNode)
virtual void fullNodeSplit([[maybe_unused]] PCTree &tree, [[maybe_unused]] PCNode *fullNode)
A DFS or BFS through a PCTree.
void markLeavesFull(It begin, It end)
Only marks leaves full, does not update partial/full info of parents.
std::string uniqueID(const std::function< void(std::ostream &os, PCNode *, int)> &printNode=uid_utils::nodeToID, [[maybe_unused]] const std::function< bool(PCNode *, PCNode *)> &compareNodes=uid_utils::compareNodesByID)
void setLabel(NodeLabel l)
virtual void labelsAssigned([[maybe_unused]] PCTree &tree, [[maybe_unused]] PCNode *firstPartial, [[maybe_unused]] PCNode *lastPartial, [[maybe_unused]] int partialCount)
void leafToPosition(std::ostream &os, PCNode *n, int pos)
Print the position pos of a node n if it is a leaf.
Multiple PCTrees can be created within the same PCTreeForest, which allows merging the trees later on...
void removeObserver(Observer *observer)
std::list< Observer * > m_observers
size_t getLeafCount() const
virtual void nodeReplaced([[maybe_unused]] PCTree &tree, [[maybe_unused]] PCNode *replaced, [[maybe_unused]] PCNode *replacement)
bool isTrivialRestriction(int restSize, int leafCount)
int factorial(int n)
Returns n!.
A registry that allows labelling the nodes of a PC-tree.
const IntrusiveList< PCNode > & getLeaves() const
RegisteredArray for nodes, edges and adjEntries of a graph.
Data type for general directed graphs (adjacency list representation).
void markFull(It begin, It end, std::vector< PCNode * > *fullNodeOrder=nullptr)
Marks the leaves contained in the range denoted by iterators begin (inclusive) to end (exclusive) ful...
void removeObserver(std::list< Observer * >::const_iterator it)
void nodeToID(std::ostream &os, PCNode *n, int pos)
Print the index of a node n.
void leafToID(std::ostream &os, PCNode *n, int pos)
Print the index of a node n if it is a leaf.
@ tree
for every hyperedge e a minimal subcubic tree connecting all hypernodes incident with e together is a...
int getTerminalPathLength() const
Predeclaration of various PC-tree related classes and enums.
Utils for PCTree::allNodes(), PCTree::innerNodes(), PCNode::children() and PCNode::neighbors().
PCNode * getRootNode() const
A node in a PC-tree that is either a P-node, C-node or leaf.
FilteringPCTreeDFS allNodes() const
An iterable through all nodes of this PCTree.
A node in a PC-tree that is either a P-node, C-node or leaf.
Basic declarations, included by all source files.
virtual void beforeMerge([[maybe_unused]] PCTree &tree, [[maybe_unused]] int count, [[maybe_unused]] PCNode *tpNeigh)
HypergraphRegistry< HypernodeElement >::iterator end(const HypergraphRegistry< HypernodeElement > &self)
#define OGDF_EXPORT
Specifies that a function or class is exported by the OGDF DLL.
bool makeConsecutive(It begin, It end)
Make the leaves contained in the range denoted by iterators begin (inclusive) to end (exclusive) cons...
int PCTREE_DEBUG_CHECK_FREQ
Allows controlling the frequency of full-tree consistency checks in heavy debug mode.
PCNode * mergeLeaves(It begin, It end, bool assumeConsecutive=false)
Merge multiple leaves into a single one and return it.
virtual void makeConsecutiveCalled([[maybe_unused]] PCTree &tree, [[maybe_unused]] FullLeafIter consecutiveLeaves)
std::vector< PCNode * > currentLeafOrder() const
virtual void nodeDeleted([[maybe_unused]] PCTree &tree, [[maybe_unused]] PCNode *toBeDeleted)
std::function< std::function< PCNode *()>()> FullLeafIter
PCTreeForests contain multiple PCTrees that can be merged with each other.
virtual void whenCNodeMerged([[maybe_unused]] PCTree &tree, [[maybe_unused]] PCNode *tpNeigh, [[maybe_unused]] bool tpNeighSiblingsFlipped, [[maybe_unused]] PCNode *fullNeigh, [[maybe_unused]] PCNode *fullOuterChild)
static int keyToIndex(PCNode *key)
Returns the index of key.
virtual void onNodeCreate([[maybe_unused]] PCNode *node)
PCTree()
Constructs a new PCTree.
bool compareNodesByID(PCNode *a, PCNode *b)
Sort nodes by ascending index.
NextFullLeaf(It it, It an_end)
virtual void onApexMoved([[maybe_unused]] PCTree &tree, [[maybe_unused]] PCNode *apexCandidate, [[maybe_unused]] PCNode *central, [[maybe_unused]] PCNode *parent)
Class for the representation of nodes.
virtual void whenPNodeMerged([[maybe_unused]] PCTree &tree, [[maybe_unused]] PCNode *tpNeigh, [[maybe_unused]] PCNode *tpPred, [[maybe_unused]] PCNode *fullNeigh)
void currentLeafOrder(Container &container) const
Store the order of leaves currently represented by this tree in container.
size_t getCNodeCount() const
PCNode * mergeLeaves(const std::vector< PCNode * > &consecutiveLeaves, bool assumeConsecutive=false)
Merge multiple leaves into a single one and return it.
R possibleOrders() const
Calculate the number of cyclic orders represented by this tree.
virtual void terminalPathFound([[maybe_unused]] PCTree &tree, [[maybe_unused]] PCNode *apex, [[maybe_unused]] PCNode *apexTPPred2, [[maybe_unused]] int terminalPathLength)