// Function ReplaceFullRoot either replaces the full root 
// or one full child of a partial root of a pertinent subtree
// by a single P-node  with leaves corresponding the keys stored in leafKeys.
void PlanarSubgraphPQTree::
ReplaceFullRoot(SListPure<PlanarLeafKey<whaInfo*>*> &leafKeys)
{

	PQLeaf<edge,whaInfo*,bool>          *leafPtr     = 0; // dummy
	PQInternalNode<edge,whaInfo*,bool>	*nodePtr     = 0; // dummy
	//PQNodeKey<edge,whaInfo*,bool>	    *nodeInfoPtr = 0; // dummy
	PQNode<edge,whaInfo*,bool>		    *currentNode = 0; // dummy
	SListIterator<PlanarLeafKey<whaInfo*>* >  it;

	if (!leafKeys.empty() && leafKeys.front() == leafKeys.back())
	{
		//ReplaceFullRoot: replace pertinent root by a single leaf
		leafPtr = OGDF_NEW PQLeaf<edge,whaInfo*,bool>(m_identificationNumber++,
                    EMPTY,(PQLeafKey<edge,whaInfo*,bool>*)leafKeys.front());
		exchangeNodes(m_pertinentRoot,(PQNode<edge,whaInfo*,bool>*) leafPtr);
		if (m_pertinentRoot == m_root)
			m_root = (PQNode<edge,whaInfo*,bool>*) leafPtr;      
	}
	else if (!leafKeys.empty()) // at least two leaves
	{
		//replace pertinent root by a $P$-node
		if ((m_pertinentRoot->type() == P_NODE) || 
			(m_pertinentRoot->type() == Q_NODE))
		{
			nodePtr = (PQInternalNode<edge,whaInfo*,bool>*)m_pertinentRoot;
			nodePtr->type(P_NODE);
			nodePtr->status(PERTROOT);
			nodePtr->childCount(0);
			while (!fullChildren(m_pertinentRoot)->empty())
			{	
				currentNode = fullChildren(m_pertinentRoot)->popFrontRet();
				removeChildFromSiblings(currentNode);
			}
		}      
		else if (m_pertinentRoot->type() == LEAF)
		{
			nodePtr = OGDF_NEW PQInternalNode<edge,whaInfo*,bool>(m_identificationNumber++,
														 P_NODE,EMPTY);
			exchangeNodes(m_pertinentRoot,nodePtr);
		}
		SListPure<PQLeafKey<edge,whaInfo*,bool>*> castLeafKeys;
		for (it = leafKeys.begin(); it.valid(); ++it)
			castLeafKeys.pushBack((PQLeafKey<edge,whaInfo*,bool>*) *it);
		addNewLeavesToTree(nodePtr,castLeafKeys);
	}
  
}
Beispiel #2
0
// Function ReplaceFullRoot either replaces the full root 
// or one full child of a partial root of a pertinent subtree
// by a single P-node  with leaves corresponding the keys stored in leafKeys.
void PlanarPQTree::ReplaceFullRoot(SListPure<PlanarLeafKey<indInfo*>*> &leafKeys)
{
	if (!leafKeys.empty() && leafKeys.front() == leafKeys.back())
	{
		//ReplaceFullRoot: replace pertinent root by a single leaf
		PQLeaf<edge,indInfo*,bool> *leafPtr =
			OGDF_NEW PQLeaf<edge,indInfo*,bool>(m_identificationNumber++,
            EMPTY,(PQLeafKey<edge,indInfo*,bool>*)leafKeys.front());

		exchangeNodes(m_pertinentRoot,(PQNode<edge,indInfo*,bool>*) leafPtr);
		if (m_pertinentRoot == m_root)
			m_root = (PQNode<edge,indInfo*,bool>*) leafPtr;      
		m_pertinentRoot = 0;  // check for this emptyAllPertinentNodes
	}

	else if (!leafKeys.empty()) // at least two leaves
	{
		PQInternalNode<edge,indInfo*,bool> *nodePtr = 0; // dummy
		//replace pertinent root by a $P$-node
		if ((m_pertinentRoot->type() == PQNodeRoot::PNode) || 
			(m_pertinentRoot->type() == PQNodeRoot::QNode))
		{
			nodePtr = (PQInternalNode<edge,indInfo*,bool>*)m_pertinentRoot;
			nodePtr->type(PQNodeRoot::PNode);
			nodePtr->childCount(0);
			while (!fullChildren(m_pertinentRoot)->empty())
				removeChildFromSiblings(fullChildren(m_pertinentRoot)->popFrontRet());
		}      
		else if (m_pertinentRoot->type() == PQNodeRoot::leaf)
		{
			nodePtr = OGDF_NEW PQInternalNode<edge,indInfo*,bool>(m_identificationNumber++,
														 PQNodeRoot::PNode,EMPTY);
			exchangeNodes(m_pertinentRoot,nodePtr);
			m_pertinentRoot = 0;  // check for this emptyAllPertinentNodes
		}
		
		SListPure<PQLeafKey<edge,indInfo*,bool>*> castLeafKeys;
		SListIterator<PlanarLeafKey<indInfo*>* >  it;
		for (it = leafKeys.begin(); it.valid(); ++it)
			castLeafKeys.pushBack((PQLeafKey<edge,indInfo*,bool>*) *it);
		addNewLeavesToTree(nodePtr,castLeafKeys);
	}
}
Beispiel #3
0
void EmbedPQTree::ReplaceRoot(
	SListPure<PlanarLeafKey<indInfo*>*> &leafKeys,
	SListPure<edge> &frontier,
	SListPure<node> &opposed,
	SListPure<node> &nonOpposed,
	node v)
{
	SListPure<PQBasicKey<edge,indInfo*,bool>*> nodeFrontier;

	if (leafKeys.empty() && m_pertinentRoot == m_root)
	{
		front(m_pertinentRoot,nodeFrontier);
		m_pertinentRoot = 0;  // check for this emptyAllPertinentNodes

	} else {
		if (m_pertinentRoot->status() == FULL)
			ReplaceFullRoot(leafKeys,nodeFrontier,v);
		else
			ReplacePartialRoot(leafKeys,nodeFrontier,v);
	}

	// Check the frontier and get the direction indicators.
	while (!nodeFrontier.empty())
	{
		PQBasicKey<edge,indInfo*,bool>* entry = nodeFrontier.popFrontRet();
		if (entry->userStructKey()) // is a regular leaf
			frontier.pushBack(entry->userStructKey());

		else if (entry->userStructInfo()) {
			if (entry->userStructInfo()->changeDir)
				opposed.pushBack(entry->userStructInfo()->v);
			else
				nonOpposed.pushBack(entry->userStructInfo()->v);
		}
	}
}
Beispiel #4
0
// extract external facepath in direction CCW and split the highest facepath
// in highest xy-paths. marker marks the node, highMarker is used to check,
// whether the node was visited before by the highest facepath traversal.
// highMarker+1 identifies the nodes that are zNodes.
void FindKuratowskis::extractExternalFacePath(
				SListPure<adjEntry>& externalFacePath,
				const ListPure<adjEntry>& highestFacePath,
				int marker,
				int highMarker)
{
	int dir = CCW;
	// x traverses the external facepath
	node x = pBM->successorWithoutShortCircuit(k.R,dir);
	externalFacePath.pushBack(pBM->beforeShortCircuitEdge(k.R,CCW));
	m_wasHere[k.R] = marker;
	while (x != k.R) {
		// set visited sign on nodes that are both on the highest and external facepath
		if (m_wasHere[x]>=highMarker) m_wasHere[x] = marker;
		externalFacePath.pushBack(pBM->beforeShortCircuitEdge(x,dir));
		x = pBM->successorWithoutShortCircuit(x,dir);
	}

	dir = CCW;
	x = pBM->successorWithoutShortCircuit(k.R,dir);
	ListConstIterator<adjEntry> highIt = highestFacePath.begin();
	OGDF_ASSERT(x == (*highIt)->theNode());
	SListPure<adjEntry> XYPathList;
	SListPure<adjEntry> zList;
	WInfo info;
	adjEntry adj = pBM->beforeShortCircuitEdge(k.R,CCW);
	adjEntry temp;
	while (x != k.R) {
		// go along the highest face path until next visited sign
		OGDF_ASSERT(adj->theNode()==x);
		if (m_wasHere[x] == marker) {
			XYPathList.clear();
			zList.clear();
			info.w = NULL;
			info.minorType = 0;
			info.highestXYPath = NULL;
			info.zPath = NULL;
			info.pxAboveStopX = false;
			info.pyAboveStopY = false;
			info.externEStart = NULL;
			info.externEEnd = NULL;
			info.firstExternEAfterW = NULL;
		}

		// push in wNodes-list
		if (pBM->pertinent(x)) {
			info.w = x;
			k.wNodes.pushBack(info);
		}

		// compute next highestXYPath
		if (m_wasHere[x] == marker &&
					m_wasHere[pBM->constSuccessorWithoutShortCircuit(x,dir)] != marker) {
			// traverse highFacePath to x
			while ((*highIt)->theNode() != x) ++highIt;
			OGDF_ASSERT(highIt.valid());
			XYPathList.pushBack(adj);
			OGDF_ASSERT((*highIt.succ())->theNode() !=
						pBM->constSuccessorWithoutShortCircuit(x,dir));

			// traverse highFacePath to next marker
			do {
				++highIt;
				if (!highIt.valid()) break;
				temp = *highIt;
				XYPathList.pushBack(temp);
				// check, if node is z-node and push one single z-node
				if (m_wasHere[temp->theNode()]==highMarker+1 && zList.empty())
					zList.pushBack(temp);
			} while (m_wasHere[temp->theNode()] != marker);

			// save highestXY-Path
			OGDF_ASSERT(!XYPathList.empty());
			k.highestXYPaths.pushBack(XYPathList);
			info.highestXYPath = &k.highestXYPaths.back();

			// compute path from zNode to V and save it
			if (!zList.empty()) {
				OGDF_ASSERT(zList.size()==1); // just one zNode for now
				temp = zList.back();
				do {
					do {
						temp = temp->cyclicSucc();
						OGDF_ASSERT(m_dfi[temp->twinNode()]==m_dfi[k.R] ||
									m_dfi[temp->twinNode()]>=m_dfi[k.RReal]);
					} while (m_edgeType[temp->theEdge()]==EDGE_BACK_DELETED);
					temp = temp->twin();
					zList.pushBack(temp);
				} while (temp->theNode() != k.R);
				k.zPaths.pushBack(zList);
				info.zPath = &k.zPaths.back();
			}
		}

		// go on
		adj = pBM->beforeShortCircuitEdge(x,dir);
		x = pBM->successorWithoutShortCircuit(x,dir);
	}
}
Beispiel #5
0
void EmbedPQTree::ReplaceFullRoot(
	SListPure<PlanarLeafKey<indInfo*>*> &leafKeys,
	SListPure<PQBasicKey<edge,indInfo*,bool>*> &frontier,
	node v,
	bool addIndicator,
	PQNode<edge,indInfo*,bool> *opposite)
{
	EmbedIndicator *newInd = 0; 

	front(m_pertinentRoot,frontier);
	if (addIndicator)
	{
		indInfo *newInfo = OGDF_NEW indInfo(v);
		embedKey *nodeInfoPtr = OGDF_NEW embedKey(newInfo);
		newInd = OGDF_NEW EmbedIndicator(m_identificationNumber++,
			(PQNodeKey<edge,indInfo*,bool>*)nodeInfoPtr);
		newInd->setNodeInfo(nodeInfoPtr);
		nodeInfoPtr->setNodePointer(newInd);
	}

	if (!leafKeys.empty() && leafKeys.front() == leafKeys.back())
	{
		//ReplaceFullRoot: replace pertinent root by a single leaf
		if (addIndicator)
		{
			opposite = m_pertinentRoot->getNextSib(opposite);
			if (!opposite) // m_pertinentRoot is endmost child
			{
				addNodeToNewParent(m_pertinentRoot->parent(),newInd,
								   m_pertinentRoot,opposite);
			}
			else 
				addNodeToNewParent(0,newInd,m_pertinentRoot,opposite);

			// Setting the sibling pointers into opposite direction of
			// scanning the front allows to track swaps of the indicator
			newInd->changeSiblings(m_pertinentRoot,0);
			newInd->changeSiblings(opposite,0);
			newInd->putSibling(m_pertinentRoot,LEFT);
			newInd->putSibling(opposite,RIGHT);
		}
		PQLeaf<edge,indInfo*,bool> *leafPtr =
			OGDF_NEW PQLeaf<edge,indInfo*,bool>(m_identificationNumber++,
			EMPTY,(PQLeafKey<edge,indInfo*,bool>*)leafKeys.front());
		exchangeNodes(m_pertinentRoot,(PQNode<edge,indInfo*,bool>*) leafPtr);
 		if (m_pertinentRoot == m_root)
			m_root = (PQNode<edge,indInfo*,bool>*) leafPtr;      
		m_pertinentRoot = 0;  // check for this emptyAllPertinentNodes
	}

	else if (!leafKeys.empty()) // at least two leaves
	{
		//replace pertinent root by a $P$-node
		if (addIndicator)
		{
			opposite = m_pertinentRoot->getNextSib(opposite);
			if (!opposite) // m_pertinentRoot is endmost child
			{
				addNodeToNewParent(m_pertinentRoot->parent(),newInd,
								   m_pertinentRoot,opposite);
			}
			else 
				addNodeToNewParent(0,newInd,m_pertinentRoot,opposite);

			// Setting the sibling pointers into opposite direction of
			// scanning the front allows to track swaps of the indicator
			newInd->changeSiblings(m_pertinentRoot,0);
			newInd->changeSiblings(opposite,0);
			newInd->putSibling(m_pertinentRoot,LEFT);
			newInd->putSibling(opposite,RIGHT);
		}

		PQInternalNode<edge,indInfo*,bool> *nodePtr = 0; // dummy
		if ((m_pertinentRoot->type() == PQNodeRoot::PNode) || 
			(m_pertinentRoot->type() == PQNodeRoot::QNode))
		{
			nodePtr = (PQInternalNode<edge,indInfo*,bool>*)m_pertinentRoot;
			nodePtr->type(PQNodeRoot::PNode);
			nodePtr->childCount(0);
			while (!fullChildren(m_pertinentRoot)->empty())
			{	
				PQNode<edge,indInfo*,bool> *currentNode =
					fullChildren(m_pertinentRoot)->popFrontRet();
				removeChildFromSiblings(currentNode);
			}
		}      
		else if (m_pertinentRoot->type() == PQNodeRoot::leaf)
		{
			nodePtr = OGDF_NEW PQInternalNode<edge,indInfo*,bool>(m_identificationNumber++,
														 PQNodeRoot::PNode,EMPTY);
			exchangeNodes(m_pertinentRoot,nodePtr);
			m_pertinentRoot = 0;  // check for this emptyAllPertinentNodes
		}
	
		SListPure<PQLeafKey<edge,indInfo*,bool>*> castLeafKeys;
		SListIterator<PlanarLeafKey<indInfo*>* > it;
		for (it = leafKeys.begin(); it.valid(); ++it)
			castLeafKeys.pushBack((PQLeafKey<edge,indInfo*,bool>*) *it);
		addNewLeavesToTree(nodePtr,castLeafKeys);
	}  
}
Beispiel #6
0
void EmbedPQTree::ReplaceFullRoot(
	SListPure<PlanarLeafKey<IndInfo*>*> &leafKeys,
	SListPure<PQBasicKey<edge,IndInfo*,bool>*> &frontier,
	node v,
	bool addIndicator,
	PQNode<edge,IndInfo*,bool> *opposite)
{
	EmbedIndicator *newInd = nullptr;

	front(m_pertinentRoot,frontier);
	if (addIndicator)
	{
		IndInfo *newInfo = new IndInfo(v);
		PQNodeKey<edge,IndInfo*,bool> *nodeInfoPtr = new PQNodeKey<edge,IndInfo*,bool>(newInfo);
		newInd = new EmbedIndicator(m_identificationNumber++, nodeInfoPtr);
		newInd->setNodeInfo(nodeInfoPtr);
		nodeInfoPtr->setNodePointer(newInd);
	}

	if (!leafKeys.empty() && leafKeys.front() == leafKeys.back())
	{
		//ReplaceFullRoot: replace pertinent root by a single leaf
		if (addIndicator)
		{
			opposite = m_pertinentRoot->getNextSib(opposite);
			if (!opposite) // m_pertinentRoot is endmost child
			{
				addNodeToNewParent(m_pertinentRoot->parent(), newInd, m_pertinentRoot, opposite);
			}
			else
				addNodeToNewParent(nullptr,newInd,m_pertinentRoot,opposite);

			// Setting the sibling pointers into opposite direction of
			// scanning the front allows to track swaps of the indicator
			newInd->changeSiblings(m_pertinentRoot,nullptr);
			newInd->changeSiblings(opposite,nullptr);
			newInd->putSibling(m_pertinentRoot,PQNodeRoot::SibDirection::Left);
			newInd->putSibling(opposite,PQNodeRoot::SibDirection::Right);
		}
		PQLeaf<edge,IndInfo*,bool> *leafPtr =
			new PQLeaf<edge,IndInfo*,bool>(m_identificationNumber++,
			PQNodeRoot::PQNodeStatus::Empty,(PQLeafKey<edge,IndInfo*,bool>*)leafKeys.front());
		exchangeNodes(m_pertinentRoot,(PQNode<edge,IndInfo*,bool>*) leafPtr);
		if (m_pertinentRoot == m_root)
			m_root = (PQNode<edge,IndInfo*,bool>*) leafPtr;
		m_pertinentRoot = nullptr;  // check for this emptyAllPertinentNodes
	}

	else if (!leafKeys.empty()) // at least two leaves
	{
		//replace pertinent root by a $P$-node
		if (addIndicator)
		{
			opposite = m_pertinentRoot->getNextSib(opposite);
			if (!opposite) // m_pertinentRoot is endmost child
			{
				addNodeToNewParent(m_pertinentRoot->parent(), newInd, m_pertinentRoot, opposite);
			}
			else
				addNodeToNewParent(nullptr, newInd, m_pertinentRoot, opposite);

			// Setting the sibling pointers into opposite direction of
			// scanning the front allows to track swaps of the indicator
			newInd->changeSiblings(m_pertinentRoot,nullptr);
			newInd->changeSiblings(opposite,nullptr);
			newInd->putSibling(m_pertinentRoot,PQNodeRoot::SibDirection::Left);
			newInd->putSibling(opposite,PQNodeRoot::SibDirection::Right);
		}

		PQInternalNode<edge,IndInfo*,bool> *nodePtr = nullptr; // dummy
		if ((m_pertinentRoot->type() == PQNodeRoot::PQNodeType::PNode) ||
			(m_pertinentRoot->type() == PQNodeRoot::PQNodeType::QNode))
		{
			nodePtr = (PQInternalNode<edge,IndInfo*,bool>*)m_pertinentRoot;
			nodePtr->type(PQNodeRoot::PQNodeType::PNode);
			nodePtr->childCount(0);
			while (!fullChildren(m_pertinentRoot)->empty())
			{
				PQNode<edge,IndInfo*,bool> *currentNode =
					fullChildren(m_pertinentRoot)->popFrontRet();
				removeChildFromSiblings(currentNode);
			}
		}
		else if (m_pertinentRoot->type() == PQNodeRoot::PQNodeType::Leaf)
		{
			nodePtr = new PQInternalNode<edge,IndInfo*,bool>(m_identificationNumber++,
			                                                 PQNodeRoot::PQNodeType::PNode,
			                                                 PQNodeRoot::PQNodeStatus::Empty);
			exchangeNodes(m_pertinentRoot,nodePtr);
			m_pertinentRoot = nullptr;  // check for this emptyAllPertinentNodes
		}

		SListPure<PQLeafKey<edge, IndInfo*, bool>*> castLeafKeys;
		for (PlanarLeafKey<IndInfo*> *key : leafKeys)
			castLeafKeys.pushBack(static_cast<PQLeafKey<edge, IndInfo*, bool>*>(key));
		addNewLeavesToTree(nodePtr, castLeafKeys);
	}
}