 |
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 dynamic library (shared object / 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)