예제 #1
0
// 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);
}
예제 #2
0
// 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);
}
예제 #3
0
파일: EmbedPQTree.cpp 프로젝트: ogdf/ogdf
// 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);
}
예제 #4
0
파일: EmbedPQTree.cpp 프로젝트: ogdf/ogdf
// 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);
}
예제 #5
0
// 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();
}
예제 #6
0
// 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);
}
예제 #7
0
// 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;
}
예제 #8
0
파일: EmbedPQTree.cpp 프로젝트: ogdf/ogdf
// 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;
}
예제 #9
0
// 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);
	}
}
예제 #11
0
// 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;
			}
		}
	}
}
예제 #12
0
// 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;
			}
		}
	}
}
예제 #13
0
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);
}
예제 #14
0
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());
}
예제 #15
0
파일: EmbedPQTree.cpp 프로젝트: ogdf/ogdf
// 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;
			}
		}
	}
}