36#include <ogdf/basic/internal/config_autogen.h>
46#include <initializer_list>
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,
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) {
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>
417 void markFull(It begin, It end, std::vector<PCNode*>* fullNodeOrder =
nullptr) {
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);
537 template<
typename Container>
540 if (leaf->isLeaf()) {
541 container.push_back(leaf);
548 std::vector<PCNode*> container;
549 currentLeafOrder(container);
562 bool mark_full =
false,
bool show_sibs =
false)
const;
569 PCNode* fixedLeaf =
nullptr)
const;
576 if (
node->getNodeType() == PCNodeType::CNode) {
579 R children(
node->getChildCount());
580 if (
node == m_rootNode) {
583 orders *= factorial(children);
595 const std::function<
void(std::ostream& os,
PCNode*,
int)>& printNode = uid_utils::nodeToID,
596 const std::function<
bool(
PCNode*,
PCNode*)>& compareNodes = uid_utils::compareNodesByID);
599 const std::function<
void(std::ostream& os,
PCNode*,
int)>& printNode = uid_utils::nodeToID,
600 [[maybe_unused]]
const std::function<
bool(
PCNode*,
PCNode*)>& compareNodes =
601 uid_utils::compareNodesByID) {
602 std::stringstream sb;
603 uniqueID(sb, printNode, compareNodes);
614 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;
698 m_observers.push_back(observer);
699 return --m_observers.end();
702 void removeObserver(std::list<Observer*>::const_iterator it) { m_observers.erase(it); }
Includes declaration of graph class.
An intrusive list for the leaves of a PCTree.
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.
PCTreeForests contain multiple PCTrees that can be merged with each other.
Utils for PCTree::allNodes(), PCTree::innerNodes(), PCNode::children() and PCNode::neighbors().
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).
Class for the representation of nodes.
Dynamic arrays indexed with arbitrary keys.
RegisteredArray for nodes, edges and adjEntries of a graph.
A DFS or BFS through a PCTree.
A node in a PC-tree that is either a P-node, C-node or leaf.
void setLabel(NodeLabel l)
Multiple PCTrees can be created within the same PCTreeForest, which allows merging the trees later on...
PCTreeRegistry m_nodeArrayRegistry
A PC-tree represents a set of cyclic orders of its leaves by labeling its inner nodes as either P- or...
FilteringPCTreeDFS innerNodes() const
An iterable through all inner (non-leaf) nodes of this PCTree.
void removeObserver(Observer *observer)
PCNodeType changeNodeType(PCNode *node, PCNodeType newType)
Change the type of a node and update all its registrations.
bool makeFullNodesConsecutive()
Updates the tree to make all leaves marked as full consecutive in all represented orders.
std::vector< PCNode * > currentLeafOrder() const
void registerNode(PCNode *node)
PCNode * mergeLeaves(It begin, It end, bool assumeConsecutive=false)
Merge multiple leaves into a single one and return it.
void destroyNode(PCNode *&node)
Destroy a node.
int getTerminalPathLength() const
void replaceTPNeigh(PCNode *central, PCNode *oldTPNeigh, PCNode *newTPNeigh, PCNode *newFullNeigh, PCNode *otherEndOfFullBlock)
bool isTrivial() const
Whether this PCTree allows all orders (consists of a single P-node).
size_t getPNodeCount() const
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 * mergeLeaves(const std::vector< PCNode * > &consecutiveLeaves, bool assumeConsecutive=false)
Merge multiple leaves into a single one and return it.
bool isTrivialRestriction(int size) const
bool isValidOrder(const std::vector< PCNode * > &order) const
Check whether the order order is represented by this tree.
std::string uniqueID(const std::function< void(std::ostream &os, PCNode *, int)> &printNode=uid_utils::nodeToID, const std::function< bool(PCNode *, PCNode *)> &compareNodes=uid_utils::compareNodesByID)
bool setApexCandidate(PCNode *ac, bool fix=false)
FilteringPCTreeDFS allNodes() const
An iterable through all nodes of this PCTree.
PCNode * createCentralNode()
PCNode * getRootNode() const
PCTree(int leafNum, std::vector< PCNode * > *added=nullptr, PCTreeForest *forest=nullptr)
Convenience method generating a PCTree consisting of a single P-node with leafNum leaves,...
PCTree()
Constructs a new PCTree.
size_t getCNodeCount() const
bool makeConsecutive(It begin, It end)
Make the leaves contained in the range denoted by iterators begin (inclusive) to end (exclusive) cons...
void addPartialNode(PCNode *partial)
void resetTempData()
Reset all makeConsecutive()-related temporary information, especially which leaves are full (should b...
PCTreeForest * getForest() const
The PCTreeForest this PCTree belongs to, or nullptr.
PCNode * splitOffFullPNode(PCNode *node, bool skip_parent)
void getRestrictions(std::vector< std::vector< PCNode * > > &restrictions, PCNode *fixedLeaf=nullptr) const
Get a list of all cyclic restrictions used to generate this tree.
void insertTree(PCNode *at, PCTree *tree)
Insert tree tree into this tree at node at.
std::ostream & uniqueID(std::ostream &os, const std::function< void(std::ostream &os, PCNode *, int)> &printNode=uid_utils::nodeToID, const std::function< bool(PCNode *, PCNode *)> &compareNodes=uid_utils::compareNodesByID)
Print a deterministic and unique representation of this PCTree to os.
void unregisterNode(PCNode *node)
void getTree(ogdf::Graph &tree, ogdf::GraphAttributes *g_a, PCTreeNodeArray< ogdf::node > &pc_repr, ogdf::NodeArray< PCNode * > *g_repr=nullptr, bool mark_full=false, bool show_sibs=false) const
Get a graphical representation of this tree as Graph.
void replaceLeaf(int leafCount, PCNode *leaf, std::vector< PCNode * > *added=nullptr)
Convert leaf into a P-node and attach leafCount new leaves to it.
friend std::ostream & operator<<)(std::ostream &, const ogdf::pc_tree::PCNode *)
PCTree(const std::string &str, bool keep_ids=false, PCTreeForest *forest=nullptr)
Deserialize a PCTree from a string str as generated by operator<<(std::ostream&, const PCTree*) or PC...
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...
size_t getLeafCount() const
size_t findEndOfFullBlock(PCNode *node, PCNode *pred, PCNode *curr, PCNode *&fullEnd, PCNode *&emptyEnd) const
bool checkValid(bool allow_small_deg=true) const
Validity check for debugging assertions.
friend std::ostream & operator<<)(std::ostream &, const ogdf::pc_tree::PCTree *)
const IntrusiveList< PCNode > & getLeaves() const
void restoreSubtrees(PCTreeNodeArray< std::vector< PCNode * > > &blockNodes, PCTreeNodeArray< std::vector< PCNode * > > &subtreeNodes, PCTreeNodeArray< PCNode * > &leafPartner, PCTreeNodeArray< bool > &isFront)
bool makeConsecutive(const std::vector< PCNode * > &consecutiveLeaves)
std::list< Observer * >::const_iterator addObserver(Observer *observer)
PCTree(const PCTree &other, PCTreeNodeArray< PCNode * > &nodeMapping, bool keep_ids=false, PCTreeForest *forest=nullptr)
Copy a PCTree.
bool makeConsecutive(std::initializer_list< PCNode * > consecutiveLeaves)
void removeObserver(std::list< Observer * >::const_iterator it)
PCNode * markFull(PCNode *full_node, std::vector< PCNode * > *fullNodeOrder=nullptr)
bool findNodeRestrictions(PCTree &applyTo, PCTreeNodeArray< PCNode * > &mapping, PCTreeNodeArray< std::vector< PCNode * > > &blockNodes, PCTreeNodeArray< std::vector< PCNode * > > &subtreeNodes, PCTreeNodeArray< PCNode * > &leafPartner, PCTreeNodeArray< bool > &isFront)
PCTree(PCTreeForest *forest)
Constructs a new PCTree that is part of forest and can thus be merged with any other PCTree of the sa...
void removePartialNode(PCNode *partial)
bool checkTPPartialCNode(PCNode *node)
PCNode * changeRoot(PCNode *newRoot)
Change the orientation of edges such that newRoot becomes the root of the tree.
std::function< std::function< PCNode *()>()> FullLeafIter
IntrusiveList< PCNode > m_leaves
void currentLeafOrder(Container &container) const
Store the order of leaves currently represented by this tree in container.
bool intersect(PCTree &other, PCTreeNodeArray< PCNode * > &mapping)
Intersect the restrictions represented by this tree with those represented by other,...
PCNode * setRoot(PCNode *newRoot)
Overwrite the stored root for this PC-tree.
std::list< Observer * > m_observers
void updateSingletonTerminalPath()
void destroyNode(PCNode *const &node)
Destroy a node.
int updateTerminalPath(PCNode *central, PCNode *tpNeigh)
R possibleOrders() const
Calculate the number of cyclic orders represented by this tree.
void destroyLeaf(PCNode *leaf)
Remove a leaf and also any newly-introduced inner degree-2 or -1 nodes.
PCNode * newNode(PCNodeType type, PCNode *parent=nullptr, int id=-1)
Create a new node.
void markLeavesFull(It begin, It end)
Only marks leaves full, does not update partial/full info of parents.
A registry that allows labelling the nodes of a PC-tree.
static int keyToIndex(PCNode *key)
Returns the index of key.
#define OGDF_EXPORT
Specifies that a function or class is exported by the OGDF dynamic library (shared object / DLL),...
#define OGDF_HEAVY_ASSERT(expr)
Assert condition expr when using heavy debugging. See OGDF_ASSERT.
#define OGDF_ASSERT(expr)
Assert condition expr. See doc/build.md for more information.
void nodeToID(std::ostream &os, PCNode *n, int pos)
Print the index of a node n.
void nodeToPosition(std::ostream &os, PCNode *n, int pos)
Print the position pos of a node n.
void leafToPosition(std::ostream &os, PCNode *n, int pos)
Print the position pos of a node n if it is a leaf.
bool compareNodesByID(PCNode *a, PCNode *b)
Sort nodes by ascending index.
void leafToID(std::ostream &os, PCNode *n, int pos)
Print the index of a node n if it is a leaf.
bool isTrivialRestriction(int restSize, int leafCount)
int PCTREE_DEBUG_CHECK_FREQ
Allows controlling the frequency of full-tree consistency checks in heavy debug mode.
The namespace for all OGDF objects.
HypergraphRegistry< HypernodeElement >::iterator begin(const HypergraphRegistry< HypernodeElement > &self)
HypergraphRegistry< HypernodeElement >::iterator end(const HypergraphRegistry< HypernodeElement > &self)
void centralCreated(PCTree &tree, PCNode *central) override
void makeConsecutiveCalled(PCTree &tree, FullLeafIter consecutiveLeaves) override
void labelsAssigned(PCTree &tree, PCNode *firstPartial, PCNode *lastPartial, int partialCount) override
void makeConsecutiveDone(PCTree &tree, Stage stage, bool success) override
void beforeMerge(PCTree &tree, int count, PCNode *tpNeigh) override
void terminalPathFound(PCTree &tree, PCNode *apex, PCNode *apexTPPred2, int terminalPathLength) override
NextFullLeaf(It it, It an_end)
Interface for Observers that can be notified of all changes made to the tree during an update.
virtual void nodeReplaced(PCTree &tree, PCNode *replaced, PCNode *replacement)
virtual void whenCNodeMerged(PCTree &tree, PCNode *tpNeigh, bool tpNeighSiblingsFlipped, PCNode *fullNeigh, PCNode *fullOuterChild)
virtual void centralCreated(PCTree &tree, PCNode *central)
virtual void makeConsecutiveCalled(PCTree &tree, FullLeafIter consecutiveLeaves)
virtual void nodeDeleted(PCTree &tree, PCNode *toBeDeleted)
virtual void afterMerge(PCTree &tree, PCNode *successor, PCNode *mergedNode)
virtual void fullNodeSplit(PCTree &tree, PCNode *fullNode)
virtual void terminalPathFound(PCTree &tree, PCNode *apex, PCNode *apexTPPred2, int terminalPathLength)
virtual void labelsAssigned(PCTree &tree, PCNode *firstPartial, PCNode *lastPartial, int partialCount)
virtual void whenPNodeMerged(PCTree &tree, PCNode *tpNeigh, PCNode *tpPred, PCNode *fullNeigh)
virtual void makeConsecutiveDone(PCTree &tree, Stage stage, bool success)
virtual void onApexMoved(PCTree &tree, PCNode *apexCandidate, PCNode *central, PCNode *parent)
virtual void onNodeCreate(PCNode *node)
virtual void beforeMerge(PCTree &tree, int count, PCNode *tpNeigh)