// Overloads virtual function of base class PQTree // Allows ignoring the virtual direction indicators during // the template matching algorithm. PQNode<edge,indInfo*,bool>* EmbedPQTree::clientLeftEndmost( PQNode<edge,indInfo*,bool> *nodePtr) const { PQNode<edge,indInfo*,bool> *left = PQTree<edge,indInfo*,bool>::clientLeftEndmost(nodePtr); if (!left || left->status() != INDICATOR) return left; else return clientNextSib(left,NULL); }
// Overloads virtual function of base class PQTree // Allows ignoring the virtual direction indicators during // the template matching algorithm. PQNode<edge,indInfo*,bool>* EmbedPQTree::clientRightEndmost( PQNode<edge,indInfo*,bool> *nodePtr) const { PQNode<edge,indInfo*,bool> *right = PQTree<edge,indInfo*,bool>::clientRightEndmost(nodePtr); if (!right || right->status() != INDICATOR) return right; else return clientNextSib(right,NULL); }
// Overloads virtual function of base class PQTree // Allows ignoring the virtual direction indicators during // the template matching algorithm. PQNode<edge,IndInfo*,bool>* EmbedPQTree::clientRightEndmost( PQNode<edge,IndInfo*,bool> *nodePtr) const { PQNode<edge,IndInfo*,bool> *right = PQTree<edge,IndInfo*,bool>::clientRightEndmost(nodePtr); if (!right || right->status() != PQNodeRoot::PQNodeStatus::Indicator) return right; else return clientNextSib(right,nullptr); }
// Overloads virtual function of base class PQTree // Allows ignoring the virtual direction indicators during // the template matching algorithm. PQNode<edge,IndInfo*,bool>* EmbedPQTree::clientLeftEndmost( PQNode<edge,IndInfo*,bool> *nodePtr) const { PQNode<edge,IndInfo*,bool> *left = PQTree<edge,IndInfo*,bool>::clientLeftEndmost(nodePtr); if (!left || left->status() != PQNodeRoot::PQNodeStatus::Indicator) return left; else return clientNextSib(left,nullptr); }
// The function [[emptyAllPertinentNodes]] has to be called after a reduction // has been processed. This overloaded function first destroys all full nodes // by marking them as TO_BE_DELETED and then calling the base class function // [[emptyAllPertinentNodes]]. void PlanarPQTree::emptyAllPertinentNodes() { ListIterator<PQNode<edge,indInfo*,bool>*> it; for (it = m_pertinentNodes->begin(); it.valid(); it++) { PQNode<edge,indInfo*,bool>* nodePtr = (*it); if (nodePtr->status() == FULL) destroyNode(nodePtr); } if (m_pertinentRoot) m_pertinentRoot->status(FULL); PQTree<edge,indInfo*,bool>::emptyAllPertinentNodes(); }
// Function ReplacePartialRoot replaces all full nodes by a single P-node // with leaves corresponding the keys stored in leafKeys. void PlanarPQTree::ReplacePartialRoot(SListPure<PlanarLeafKey<indInfo*>*> &leafKeys) { m_pertinentRoot->childCount(m_pertinentRoot->childCount() + 1 - fullChildren(m_pertinentRoot)->size()); while (fullChildren(m_pertinentRoot)->size() > 1) removeChildFromSiblings(fullChildren(m_pertinentRoot)->popFrontRet()); PQNode<edge,indInfo*,bool> *currentNode = fullChildren(m_pertinentRoot)->popFrontRet(); currentNode->parent(m_pertinentRoot); m_pertinentRoot = currentNode; ReplaceFullRoot(leafKeys); }
// Overloads virtual function of base class PQTree // Allows ignoring the virtual direction indicators during // the template matching algorithm. PQNode<edge,indInfo*,bool>* EmbedPQTree::clientSibRight( PQNode<edge,indInfo*,bool> *nodePtr) const { PQNode<edge,indInfo*,bool> *predNode = nodePtr; nodePtr = PQTree<edge,indInfo*,bool>::clientSibRight(predNode); while (nodePtr && nodePtr->status() == INDICATOR) { PQNode<edge,indInfo*,bool> *holdSib = predNode; predNode = nodePtr; nodePtr = predNode->getNextSib(holdSib); } return nodePtr; }
// Overloads virtual function of base class PQTree // Allows ignoring the virtual direction indicators during // the template matching algorithm. PQNode<edge,IndInfo*,bool>* EmbedPQTree::clientSibRight( PQNode<edge,IndInfo*,bool> *nodePtr) const { PQNode<edge,IndInfo*,bool> *predNode = nodePtr; nodePtr = PQTree<edge,IndInfo*,bool>::clientSibRight(predNode); while (nodePtr && nodePtr->status() == PQNodeRoot::PQNodeStatus::Indicator) { PQNode<edge,IndInfo*,bool> *holdSib = predNode; predNode = nodePtr; nodePtr = predNode->getNextSib(holdSib); } return nodePtr; }
// The function [[emptyAllPertinentNodes]] has to be called after a reduction // has been processed. This overloaded function first destroys all full nodes // by marking them as TO_BE_DELETED and then calling the base class function // [[emptyAllPertinentNodes]]. void EmbedPQTree::emptyAllPertinentNodes() { ListIterator<PQNode<edge,indInfo*,bool>*> it; for (it = m_pertinentNodes->begin(); it.valid(); it++) { PQNode<edge,indInfo*,bool>* nodePtr = (*it); if (nodePtr->status() == FULL) destroyNode(nodePtr); } if (m_pertinentRoot) // Node was kept in the tree. Do not free it. m_pertinentRoot->status(FULL); PQTree<edge,indInfo*,bool>::emptyAllPertinentNodes(); }
void PlanarSubgraphPQTree:: removeEliminatedLeaves(SList<PQLeafKey<edge,whaInfo*,bool>*> &eliminatedKeys) { PQNode<edge,whaInfo*,bool>* nodePtr = 0; PQNode<edge,whaInfo*,bool>* parent = 0; PQNode<edge,whaInfo*,bool>* sibling = 0; SListIterator<PQLeafKey<edge,whaInfo*,bool>*> it; for (it = eliminatedKeys.begin(); it.valid(); it++) { nodePtr = (*it)->nodePointer(); parent = nodePtr->parent(); sibling = nodePtr->getNextSib(NULL); removeNodeFromTree(parent,nodePtr); checkIfOnlyChild(sibling,parent); if (parent->status() == TO_BE_DELETED) { parent->status(WHA_DELETE); } nodePtr->status(WHA_DELETE); } }
// The function front scans the frontier of nodePtr. It returns the keys // of the leaves found in the frontier of nodePtr in a SListPure. // These keys include keys of direction indicators detected in the frontier. // // No direction is assigned to the direction indicators. // void EmbedPQTree::getFront( PQNode<edge,indInfo*,bool>* nodePtr, SListPure<PQBasicKey<edge,indInfo*,bool>*> &keys) { Stack<PQNode<edge,indInfo*,bool>*> S; S.push(nodePtr); while (!S.empty()) { PQNode<edge,indInfo*,bool> *checkNode = S.pop(); if (checkNode->type() == PQNodeRoot::leaf) keys.pushBack((PQBasicKey<edge,indInfo*,bool>*) checkNode->getKey()); else { PQNode<edge,indInfo*,bool>* firstSon = 0; if (checkNode->type() == PQNodeRoot::PNode) { firstSon = checkNode->referenceChild(); } else if (checkNode->type() == PQNodeRoot::QNode) { firstSon = checkNode->getEndmost(RIGHT); // By this, we make sure that we start on the left side // since the left endmost child will be on top of the stack } if (firstSon->status() == INDICATOR) { keys.pushBack((PQBasicKey<edge,indInfo*,bool>*) firstSon->getNodeInfo()); } else S.push(firstSon); PQNode<edge,indInfo*,bool> *nextSon = firstSon->getNextSib(0); PQNode<edge,indInfo*,bool> *oldSib = firstSon; while (nextSon && nextSon != firstSon) { if (nextSon->status() == INDICATOR) keys.pushBack((PQBasicKey<edge,indInfo*,bool>*) nextSon->getNodeInfo()); else S.push(nextSon); PQNode<edge,indInfo*,bool> *holdSib = nextSon->getNextSib(oldSib); oldSib = nextSon; nextSon = holdSib; } } } }
// The function front scans the frontier of nodePtr. It returns the keys // of the leaves found in the frontier of nodePtr in a SListPure. // These keys include keys of direction indicators detected in the frontier. // // CAREFUL: Funktion marks all full nodes for destruction. // Only to be used in connection with replaceRoot. // void EmbedPQTree::front( PQNode<edge,indInfo*,bool>* nodePtr, SListPure<PQBasicKey<edge,indInfo*,bool>*> &keys) { Stack<PQNode<edge,indInfo*,bool>*> S; S.push(nodePtr); while (!S.empty()) { PQNode<edge,indInfo*,bool> *checkNode = S.pop(); if (checkNode->type() == PQNodeRoot::leaf) keys.pushBack((PQBasicKey<edge,indInfo*,bool>*) checkNode->getKey()); else { PQNode<edge,indInfo*,bool>* firstSon = 0; if (checkNode->type() == PQNodeRoot::PNode) { firstSon = checkNode->referenceChild(); } else if (checkNode->type() == PQNodeRoot::QNode) { firstSon = checkNode->getEndmost(RIGHT); // By this, we make sure that we start on the left side // since the left endmost child will be on top of the stack } if (firstSon->status() == INDICATOR) { keys.pushBack((PQBasicKey<edge,indInfo*,bool>*) firstSon->getNodeInfo()); m_pertinentNodes->pushBack(firstSon); destroyNode(firstSon); } else S.push(firstSon); PQNode<edge,indInfo*,bool> *nextSon = firstSon->getNextSib(0); PQNode<edge,indInfo*,bool> *oldSib = firstSon; while (nextSon && nextSon != firstSon) { if (nextSon->status() == INDICATOR) { // Direction indicators point with their left sibling pointer // in the direction of their sequence. If an indicator is scanned // from the opposite direction, coming from its right sibling // the corresponding sequence must be reversed. if (oldSib == nextSon->getSib(LEFT)) //Direction changed nextSon->getNodeInfo()->userStructInfo()->changeDir = true; keys.pushBack((PQBasicKey<edge,indInfo*,bool>*) nextSon->getNodeInfo()); m_pertinentNodes->pushBack(nextSon); } else S.push(nextSon); PQNode<edge,indInfo*,bool> *holdSib = nextSon->getNextSib(oldSib); oldSib = nextSon; nextSon = holdSib; } } } }
void EmbedPQTree::ReplacePartialRoot( SListPure<PlanarLeafKey<indInfo*>*> &leafKeys, SListPure<PQBasicKey<edge,indInfo*,bool>*> &frontier, node v) { m_pertinentRoot->childCount(m_pertinentRoot->childCount() + 1 - fullChildren(m_pertinentRoot)->size()); PQNode<edge,indInfo*,bool> *predNode = 0; // dummy PQNode<edge,indInfo*,bool> *beginSequence = 0; // marks begin consecuitve seqeunce PQNode<edge,indInfo*,bool> *endSequence = 0; // marks end consecutive sequence PQNode<edge,indInfo*,bool> *beginInd = 0; // initially, marks direct sibling indicator // next to beginSequence not contained // in consectuive sequence // Get beginning and end of sequence. while (fullChildren(m_pertinentRoot)->size()) { PQNode<edge,indInfo*,bool> *currentNode = fullChildren(m_pertinentRoot)->popFrontRet(); if (!clientSibLeft(currentNode) || clientSibLeft(currentNode)->status() == EMPTY) { if (!beginSequence) { beginSequence = currentNode; predNode = clientSibLeft(currentNode); beginInd =PQTree<edge,indInfo*,bool>::clientSibLeft(currentNode); } else endSequence = currentNode; } else if (!clientSibRight(currentNode) || clientSibRight(currentNode)->status() == EMPTY ) { if (!beginSequence) { beginSequence = currentNode; predNode = clientSibRight(currentNode); beginInd =PQTree<edge,indInfo*,bool>::clientSibRight(currentNode); } else endSequence = currentNode; } } SListPure<PQBasicKey<edge,indInfo*,bool>*> partialFrontier; // Now scan the sequence of full nodes. Remove all of them but the last. // Call ReplaceFullRoot on the last one. // For every full node get its frontier. Scan intermediate indicators. PQNode<edge,indInfo*,bool> *currentNode = beginSequence; while (currentNode != endSequence) { PQNode<edge,indInfo*,bool>* nextNode = clientNextSib(currentNode,predNode); front(currentNode,partialFrontier); frontier.conc(partialFrontier); PQNode<edge,indInfo*,bool>* currentInd = PQTree<edge,indInfo*,bool>:: clientNextSib(currentNode,beginInd); // Scan for intermediate direction indicators. while (currentInd != nextNode) { PQNode<edge,indInfo*,bool> *nextInd = PQTree<edge,indInfo*,bool>:: clientNextSib(currentInd,currentNode); if (currentNode == currentInd->getSib(RIGHT)) //Direction changed currentInd->getNodeInfo()->userStructInfo()->changeDir = true; frontier.pushBack((PQBasicKey<edge,indInfo*,bool>*) currentInd->getNodeInfo()); removeChildFromSiblings(currentInd); m_pertinentNodes->pushBack(currentInd); currentInd = nextInd; } removeChildFromSiblings(currentNode); currentNode = nextNode; } currentNode->parent(m_pertinentRoot); m_pertinentRoot = currentNode; ReplaceFullRoot(leafKeys,partialFrontier,v,true,beginInd); frontier.conc(partialFrontier); }
void CconnectClusterPlanar::constructWheelGraph(ClusterGraph &C, Graph &G, cluster &parent, PlanarPQTree* T, EdgeArray<node> &outgoingTable) { const PQNode<edge,IndInfo*,bool>* root = T->root(); const PQNode<edge,IndInfo*,bool>* checkNode = nullptr; Queue<const PQNode<edge,IndInfo*,bool>*> treeNodes; treeNodes.append(root); node correspond = G.newNode(); // Corresponds to the root node. // root node is either a leaf or a P-node C.reassignNode(correspond,parent); Queue<node> graphNodes; graphNodes.append(correspond); node hub; node next = nullptr; node pre; node newNode; // corresponds to anchor of a hub or a cut node while (!treeNodes.empty()) { checkNode = treeNodes.pop(); correspond = graphNodes.pop(); PQNode<edge,IndInfo*,bool>* firstSon = nullptr; PQNode<edge,IndInfo*,bool>* nextSon = nullptr; PQNode<edge,IndInfo*,bool>* oldSib = nullptr; PQNode<edge,IndInfo*,bool>* holdSib = nullptr; if (checkNode->type() == PQNodeRoot::PNode) { // correspond is a cut node OGDF_ASSERT(checkNode->referenceChild()) firstSon = checkNode->referenceChild(); if (firstSon->type() != PQNodeRoot::leaf) { treeNodes.append(firstSon); newNode = G.newNode(); C.reassignNode(newNode,parent); graphNodes.append(newNode); G.newEdge(correspond,newNode); } else { // insert Edge to the outside PQLeaf<edge,IndInfo*,bool>* leaf = (PQLeaf<edge,IndInfo*,bool>*) firstSon; edge f = leaf->getKey()->m_userStructKey; //node x = outgoingTable[f]; G.newEdge(correspond,outgoingTable[f]); delete leaf->getKey(); } nextSon = firstSon->getNextSib(oldSib); oldSib = firstSon; pre = next; while (nextSon && nextSon != firstSon) { if (nextSon->type() != PQNodeRoot::leaf) { treeNodes.append(nextSon); newNode = G.newNode(); // new node corresponding to anchor // or cutnode C.reassignNode(newNode,parent); graphNodes.append(newNode); G.newEdge(correspond,newNode); } else { // insert Edge to the outside PQLeaf<edge,IndInfo*,bool>* leaf = (PQLeaf<edge,IndInfo*,bool>*) nextSon; edge f = leaf->getKey()->m_userStructKey; //node x = outgoingTable[f]; G.newEdge(correspond,outgoingTable[f]); delete leaf->getKey(); } holdSib = nextSon->getNextSib(oldSib); oldSib = nextSon; nextSon = holdSib; } } else if (checkNode->type() == PQNodeRoot::QNode) { // correspond is the anchor of a hub OGDF_ASSERT(checkNode->getEndmost(PQNodeRoot::LEFT)) firstSon = checkNode->getEndmost(PQNodeRoot::LEFT); hub = G.newNode(); C.reassignNode(hub,parent); G.newEdge(hub,correspond); // link anchor and hub next = G.newNode(); // for first son C.reassignNode(next,parent); G.newEdge(hub,next); G.newEdge(correspond,next); if (firstSon->type() != PQNodeRoot::leaf) { treeNodes.append(firstSon); newNode = G.newNode(); C.reassignNode(newNode,parent); graphNodes.append(newNode); G.newEdge(next,newNode); } else { // insert Edge to the outside PQLeaf<edge,IndInfo*,bool>* leaf = (PQLeaf<edge,IndInfo*,bool>*) firstSon; edge f = leaf->getKey()->m_userStructKey; //node x = outgoingTable[f]; G.newEdge(next,outgoingTable[f]); delete leaf->getKey(); } nextSon = firstSon->getNextSib(oldSib); oldSib = firstSon; pre = next; while (nextSon) { next = G.newNode(); C.reassignNode(next,parent); G.newEdge(hub,next); G.newEdge(pre,next); if (nextSon->type() != PQNodeRoot::leaf) { treeNodes.append(nextSon); newNode = G.newNode(); // new node corresponding to anchor // or cutnode C.reassignNode(newNode,parent); graphNodes.append(newNode); G.newEdge(next,newNode); } else { // insert Edge to the outside PQLeaf<edge,IndInfo*,bool>* leaf = (PQLeaf<edge,IndInfo*,bool>*) nextSon; edge f = leaf->getKey()->m_userStructKey; G.newEdge(next,outgoingTable[f]); delete leaf->getKey(); } holdSib = nextSon->getNextSib(oldSib); oldSib = nextSon; nextSon = holdSib; pre = next; } G.newEdge(next,correspond); } } OGDF_ASSERT(C.consistencyCheck()); }
// The function front scans the frontier of nodePtr. It returns the keys // of the leaves found in the frontier of nodePtr in a SListPure. // These keys include keys of direction indicators detected in the frontier. // // No direction is assigned to the direction indicators. // void EmbedPQTree::getFront( PQNode<edge,IndInfo*,bool>* nodePtr, SListPure<PQBasicKey<edge,IndInfo*,bool>*> &keys) { ArrayBuffer<PQNode<edge,IndInfo*,bool>*> S; S.push(nodePtr); while (!S.empty()) { PQNode<edge,IndInfo*,bool> *checkNode = S.popRet(); if (checkNode->type() == PQNodeRoot::PQNodeType::Leaf) keys.pushBack((PQBasicKey<edge,IndInfo*,bool>*) checkNode->getKey()); else { PQNode<edge,IndInfo*,bool>* firstSon = nullptr; if (checkNode->type() == PQNodeRoot::PQNodeType::PNode) { firstSon = checkNode->referenceChild(); } else if (checkNode->type() == PQNodeRoot::PQNodeType::QNode) { firstSon = checkNode->getEndmost(PQNodeRoot::SibDirection::Right); // By this, we make sure that we start on the left side // since the left endmost child will be on top of the stack } if (firstSon->status() == PQNodeRoot::PQNodeStatus::Indicator) { keys.pushBack((PQBasicKey<edge,IndInfo*,bool>*) firstSon->getNodeInfo()); } else S.push(firstSon); PQNode<edge,IndInfo*,bool> *nextSon = firstSon->getNextSib(nullptr); PQNode<edge,IndInfo*,bool> *oldSib = firstSon; while (nextSon && nextSon != firstSon) { if (nextSon->status() == PQNodeRoot::PQNodeStatus::Indicator) keys.pushBack((PQBasicKey<edge,IndInfo*,bool>*) nextSon->getNodeInfo()); else S.push(nextSon); PQNode<edge,IndInfo*,bool> *holdSib = nextSon->getNextSib(oldSib); oldSib = nextSon; nextSon = holdSib; } } } }