Open
Graph Drawing
Framework

 v.2012.05
 

MaxSequencePQTree.h
Go to the documentation of this file.
00001 /*
00002  * $Revision: 2299 $
00003  * 
00004  * last checkin:
00005  *   $Author: gutwenger $ 
00006  *   $Date: 2012-05-07 15:57:08 +0200 (Mon, 07 May 2012) $ 
00007  ***************************************************************/
00008  
00046 #ifdef _MSC_VER
00047 #pragma once
00048 #endif
00049 
00050 #ifndef OGDF_MAX_SEQUENCE_PQTREE_H
00051 #define OGDF_MAX_SEQUENCE_PQTREE_H
00052 
00053 
00054 
00055 #include <string.h>
00056 
00057 #include <ogdf/internal/planarity/PQTree.h>
00058 #include <ogdf/internal/planarity/PQLeafKey.h>
00059 #include <ogdf/internal/planarity/whaInfo.h>
00060 
00061 namespace ogdf{
00062 
00063     
00064 //Extra node status defines
00065 
00071 #define ELIMINATED 6    
00072 
00077 #define WHA_DELETE 7    
00078 
00083 #define PERTROOT   8    
00084 
00085 
00136 template<class T,class Y>
00137 class MaxSequencePQTree: public PQTree<T,whaInfo*,Y>
00138 {
00139 public:
00140 
00141     MaxSequencePQTree() : PQTree<T,whaInfo*,Y>() { }
00142 
00143     ~MaxSequencePQTree() {
00144         while (!eliminatedNodes.empty())
00145         {
00146             PQNode<T,whaInfo*,Y> *nodePtr = eliminatedNodes.popFrontRet();
00147             CleanNode(nodePtr);
00148             delete nodePtr;
00149         }
00150     }
00151 
00152 
00154 
00157     virtual void CleanNode(PQNode<T,whaInfo*,Y>* nodePtr);
00158 
00160     virtual void clientDefinedEmptyNode(PQNode<T,whaInfo*,Y>* nodePtr);
00161 
00163     virtual void emptyAllPertinentNodes();
00164 
00172     int determineMinRemoveSequence(SListPure<PQLeafKey<T,whaInfo*,Y>*> &leafKeys,
00173                           SList<PQLeafKey<T,whaInfo*,Y>*> &eliminatedKeys);
00174 
00175 protected:
00176 
00178 
00183     virtual bool Bubble(
00184         SListPure<PQLeafKey<T,whaInfo*,Y>*> &leafKeys/*,
00185         int redNumber = 0*/);
00186 
00188     PQNode<T,whaInfo*,Y>* GetParent(PQNode<T,whaInfo*,Y>* nodePtr);
00189 
00196     SListPure<PQNode<T,whaInfo*,Y>*> cleanUp;
00197 
00205     SListPure<PQNode<edge,whaInfo*,bool>*> eliminatedNodes;
00206 
00207 private:
00208 
00218     void findMinWHASequence(StackPure<PQNode<T,whaInfo*,Y>*> &archiv,
00219                       SList<PQLeafKey<T,whaInfo*,Y>*> &eliminatedKeys);
00220 
00230     int setHchild(PQNode<T,whaInfo*,Y> *h_child1);
00231 
00239     int setAchildren(PQNode<T,whaInfo*,Y> *hChild2,
00240                      PQNode<T,whaInfo*,Y> *hChild2Sib);
00241 
00250     void markPertinentChildren(PQNode<T,whaInfo*,Y>  *nodePtr,
00251                                int label,
00252                                int del_typ);
00253 
00258     void haNumPnode(PQNode<T,whaInfo*,Y> *nodePtr);
00259 
00266     void haNumQnode(PQNode<T,whaInfo*,Y> *nodePtr);   
00267 
00269     void aNumQnode(PQNode<T,whaInfo*,Y> *nodePtr,
00270                    int sumAllW);
00271 
00273     void hNumQnode(PQNode<T,whaInfo*,Y> *nodePtr,
00274                    int sumAllW);               
00275     
00286     int alpha1beta1Number(PQNode<T,whaInfo*,Y> *nodePtr,
00287                           PQNode<T,whaInfo*,Y> **aChild);
00288 
00294     int sumPertChild(PQNode<T,whaInfo*,Y> *nodePtr);
00295 };
00296 
00297 
00298 /************************************************************************
00299                           Bubble
00300 ************************************************************************/ 
00301 
00302 template<class T,class Y> 
00303 bool MaxSequencePQTree<T,Y>::Bubble(SListPure<PQLeafKey<T,whaInfo*,Y>*> &leafKeys/*,
00304                                     int redNumber*/)
00305 {
00324     // queue for storing all pertinent nodes that still have
00325     // to be processed. 
00326     Queue<PQNode<T,whaInfo*,Y>*>     processNodes;
00327 
00328     /*
00329     Enter the [[Full]] leaves into the queue [[processNodes]].
00330     In a first step the pertinent leaves have to be identified in the tree
00331     and entered on to the queue [[processNodes]]. The identification of
00332     the leaves can be done with the help of a pointer stored in every 
00333     [[PQLeafKey]] (see \ref{PQLeafKey}) in constant time for every element. 
00334     */
00335     SListIterator<PQLeafKey<T,whaInfo*,Y>*> it;
00336     for (it  = leafKeys.begin(); it.valid(); ++it) 
00337     {
00338         PQNode<T,whaInfo*,Y>* checkLeaf = (*it)->nodePointer();
00339         processNodes.append(checkLeaf);
00340         cleanUp.pushBack(checkLeaf);
00341         if (!checkLeaf->getNodeInfo())  // if leaf does not have an information
00342                                         // class for storing the [wha]-number
00343                                         // allocate one.
00344         {
00345             whaInfo *newInfo = OGDF_NEW whaInfo;
00346             PQNodeKey<T,whaInfo*,Y> *infoPtr = OGDF_NEW PQNodeKey<T,whaInfo*,Y>(newInfo);
00347             checkLeaf->setNodeInfo(infoPtr);
00348             infoPtr->setNodePointer(checkLeaf);
00349         }
00350         checkLeaf->getNodeInfo()->userStructInfo()->m_notVisitedCount = 1;
00351         checkLeaf->mark(QUEUED);
00352     }
00353 
00354 
00355  
00356     /*
00357     For every node in [[processNodes]], its father is detected using the
00358     function [[GetParent]] \ref{GetParent}. The father is placed onto the
00359     queue as well, if [[_nodePtr]] is its first child, that is popped from
00360     the queue. In that case, the father is marked as [[QUEUED]] to
00361     prevent the node from queue more than once. In any case, the number
00362     of pertinent children of the father is updated. This is an important
00363     number for computing the maximal pertinent sequence. 
00364     */
00365     while (!processNodes.empty())
00366     {
00367         PQNode<T,whaInfo*,Y>* nodePtr = processNodes.pop();
00368         nodePtr->parent(GetParent(nodePtr));
00369         if (nodePtr->parent() && 
00370             !nodePtr->parent()->getNodeInfo())  
00371                                         // if the parent does not have an information
00372                                         // class for storing the [wha]-number
00373                                         // allocate one.
00374         {
00375             whaInfo *newInfo = OGDF_NEW whaInfo;
00376             PQNodeKey<T,whaInfo*,Y> *infoPtr = OGDF_NEW PQNodeKey<T,whaInfo*,Y>(newInfo);
00377             nodePtr->parent()->setNodeInfo(infoPtr);
00378             infoPtr->setNodePointer(nodePtr->parent());
00379         }
00380         if (nodePtr != this->m_root)
00381         {
00382             if (nodePtr->parent()->mark() == UNMARKED)
00383             {
00384                 processNodes.append(nodePtr->parent());
00385                 cleanUp.pushBack(nodePtr->parent());
00386                 nodePtr->parent()->mark(QUEUED);
00387             }
00388             nodePtr->parent()->getNodeInfo()->userStructInfo()->m_notVisitedCount++;
00389             int childCount = nodePtr->parent()->pertChildCount();
00390             nodePtr->parent()->pertChildCount(++childCount);
00391         }
00392     }
00393 
00394 
00395     /*
00396     This chunk belongs to the function [[Bubble]]. After doing some
00397     cleaning up and resetting the flags that have been left at the
00398     pertinent nodes during the first bubble up, this chunk computes the
00399     maximal pertinent sequence by calling the function [[determineMinRemoveSequence]].
00400     It then removes
00401     all leaves from the tree that have been marked as [[ELIMINATED]] and
00402     possibly some internal nodes of the $PQ$-tree and stores pointers of
00403     type [[leafKey]] for the pertinent leaves in the maximal sequence in the
00404     array [[survivedElements]]. 
00405     */
00406 
00407     SListIterator<PQNode<T,whaInfo*,Y>*> itn;
00408     for (itn = cleanUp.begin(); itn.valid(); itn++)
00409         (*itn)->mark(UNMARKED);
00410 
00411     return true;
00412 }
00413 
00414 
00415 
00416 /**************************************************************************************
00417                         cleanNode
00418 ***************************************************************************************/ 
00419 
00420 template<class T,class Y> 
00421 void MaxSequencePQTree<T,Y>::CleanNode(PQNode<T,whaInfo*,Y>* nodePtr)
00422 {
00429     if (nodePtr->getNodeInfo())
00430     {
00431         delete nodePtr->getNodeInfo()->userStructInfo();
00432         delete nodePtr->getNodeInfo();
00433     }
00434 }
00435 
00436 
00437 /**************************************************************************************
00438                         clientDefinedEmptyNode   
00439 ***************************************************************************************/ 
00440 
00441 template<class T,class Y> 
00442 void MaxSequencePQTree<T,Y>::clientDefinedEmptyNode(PQNode<T,whaInfo*,Y>* nodePtr)
00443 {
00452     if (nodePtr->status() == ELIMINATED)
00453     {   
00454         emptyNode(nodePtr);
00455         nodePtr->status(ELIMINATED);
00456     }
00457     else if (nodePtr->status() == PERTROOT)
00458         emptyNode(nodePtr);
00459     else {
00460         // Node has an invalid status?
00461         OGDF_ASSERT(nodePtr->status() == EMPTY)
00462         emptyNode(nodePtr);
00463     }
00464 }
00465 
00466 
00467 /**************************************************************************************
00468                         emptyAllPertinentNodes   
00469 ***************************************************************************************/ 
00470 
00471 template<class T,class Y> 
00472 void MaxSequencePQTree<T,Y>::emptyAllPertinentNodes()
00473 {
00519     PQNode<T,whaInfo*,Y>* nodePtr = 0;
00520 
00521     while (!cleanUp.empty())
00522     {
00523         nodePtr = cleanUp.popFrontRet();
00524         nodePtr->pertChildCount(0);
00525         if (nodePtr->status() == WHA_DELETE && nodePtr->type() == PQNodeRoot::leaf)
00526         {
00527             CleanNode(nodePtr);
00528             delete nodePtr;
00529         }
00530 
00531         else {
00532             // node must have an Information if contained in cleanUp
00533             OGDF_ASSERT(nodePtr->getNodeInfo() != 0)
00534         
00535             nodePtr->getNodeInfo()->userStructInfo()->m_notVisitedCount = 0;
00536             nodePtr->getNodeInfo()->userStructInfo()->m_pertLeafCount = 0;
00537         }
00538     }
00539 
00540     ListIterator<PQNode<T,whaInfo*,Y>*> it;
00541     for (it = this->m_pertinentNodes->begin();it.valid();it++)
00542     {
00543         nodePtr = (*it);
00544         if (nodePtr->status() == TO_BE_DELETED)
00545         {
00546             nodePtr->status(ELIMINATED);
00547             eliminatedNodes.pushBack(nodePtr);
00548         } 
00549         else if (nodePtr->status() == FULL)
00550             nodePtr->status(TO_BE_DELETED);
00551         else if (nodePtr->status() == WHA_DELETE)
00552             nodePtr->status(TO_BE_DELETED);
00553         else if (nodePtr->getNodeInfo())
00554             nodePtr->getNodeInfo()->userStructInfo()->defaultValues();
00555     }
00556     PQTree<T,whaInfo*,Y>::emptyAllPertinentNodes();
00557 }
00558 
00559 
00560 
00561 /************************************************************************
00562                           determineMinRemoveSequence
00563 ************************************************************************/ 
00564 
00565 template<class T,class Y> 
00566 int MaxSequencePQTree<T,Y>::
00567 determineMinRemoveSequence(SListPure<PQLeafKey<T,whaInfo*,Y>*> &leafKeys,
00568                   SList<PQLeafKey<T,whaInfo*,Y>*> &eliminatedKeys)
00569 {
00596     PQNode<T,whaInfo*,Y>                *nodePtr            = 0; // dummy
00597     PQNode<T,whaInfo*,Y>                *checkLeaf          = 0; // dummy
00598 
00599     //Number of leaves that have to be deleted
00600     int                                 countDeletedLeaves  = 0;  
00601     //Number of pertinent leaves
00602     int                                 maxPertLeafCount    = 0;
00603 
00604 
00605     // A queue storing the nodes whose $[w,h,a]$-number has to be computed next. 
00606     // A node is stored in [[processNodes]], if for all of its children the 
00607     // [w,h,a]-number has been computed.
00608     Queue<PQNode<T,whaInfo*,Y>*>        processNodes;
00609 
00610     // A stack storing all nodes where a $[w,h,a]$-number
00611     // has been computed. This is necessary for a valid cleanup.
00612     StackPure<PQNode<T,whaInfo*,Y>*>    archiv;
00613 
00614 
00615 
00616 
00617 
00618     // Compute a valid parent pointer for every pertinent node.
00619     Bubble(leafKeys);
00620 
00621     // Get all pertinent leaves and stores them on [[processNodes]] 
00622     // and [[_archiv]].
00623     SListIterator<PQLeafKey<T,whaInfo*,Y>*> it;
00624     for (it = leafKeys.begin(); it.valid(); ++it)
00625     {
00626         checkLeaf = (*it)->nodePointer(); 
00627         checkLeaf->getNodeInfo()->userStructInfo()->m_pertLeafCount = 1;
00628         checkLeaf->getNodeInfo()->userStructInfo()->m_notVisitedCount--;
00629         processNodes.append(checkLeaf);
00630         archiv.push(checkLeaf);
00631 
00632         maxPertLeafCount++;
00633     }
00634 
00635     while (!processNodes.empty())
00636     {
00637         nodePtr = processNodes.pop();
00638         // Compute the $[w,h,a]$ number of [[nodePtr]]. Computing this number is 
00639         // trivial for leaves and full nodes. When considering a partial node, the
00640         // computation has to distinguish between $P$- and $Q$-nodes.
00641         if (nodePtr->getNodeInfo()->userStructInfo()->m_pertLeafCount < maxPertLeafCount)
00642         {
00643             // In case that the actual node, depicted by the pointer 
00644             // [[nodePtr]] is not the root, the counts of the pertinent 
00645             // children of [[nodePtr]]'s parent are
00646             // updated. In case that all pertinent children of the parent of
00647             // [[nodePtr]] have a valid $[w,h,a]$-number, it is possible to compute
00648             // the $[w,h,a]$-number of parent. Hence the parent is placed onto
00649             // [[processNodes]]and [[_archiv]].
00650             nodePtr->parent()->getNodeInfo()->userStructInfo()->m_pertLeafCount = 
00651                 nodePtr->parent()->getNodeInfo()->userStructInfo()->m_pertLeafCount
00652                 + nodePtr->getNodeInfo()->userStructInfo()->m_pertLeafCount;
00653             nodePtr->parent()->getNodeInfo()->userStructInfo()->m_notVisitedCount--;
00654             if (!nodePtr->parent()->getNodeInfo()->userStructInfo()->m_notVisitedCount)
00655             {
00656                 processNodes.append(nodePtr->parent());
00657                 archiv.push(nodePtr->parent());
00658             }           
00659         }
00660         if (nodePtr->type() == PQNodeRoot::leaf)
00661         {
00662             // Compute the $[w,h,a]$-number of a leaf. The computation is trivial.
00663             nodePtr->status(FULL);
00664             nodePtr->getNodeInfo()->userStructInfo()->m_w = 1;
00665             nodePtr->getNodeInfo()->userStructInfo()->m_h = 0;
00666             nodePtr->getNodeInfo()->userStructInfo()->m_a = 0;
00667             if (nodePtr->getNodeInfo()->userStructInfo()->m_pertLeafCount < maxPertLeafCount)
00668                fullChildren(nodePtr->parent())->pushFront(nodePtr);        
00669         }
00670         else
00671         {
00672             // [[nodePtr]] is a $P$- or $Q$-node
00673             // The $[w,h,a]$ number of $P$- or $Q$-nodes is computed identically. 
00674             // This is done calling the function [[sumPertChild]].
00675             nodePtr->getNodeInfo()->userStructInfo()->m_w = sumPertChild(nodePtr);
00676                                 
00677             if (fullChildren(nodePtr)->size() == nodePtr->childCount())   
00678             {
00679                 // computes the $h$- and $a$-numbers of a full node. The computation 
00680                 // is trivial. It also updates the list of full nodes of the parent
00681                 // of [[nodePtr]].
00682                 nodePtr->status(FULL);
00683                 if (nodePtr->getNodeInfo()->userStructInfo()->m_pertLeafCount 
00684                     < maxPertLeafCount)
00685                     fullChildren(nodePtr->parent())->pushFront(nodePtr);
00686                 nodePtr->getNodeInfo()->userStructInfo()->m_h = 0;
00687                 nodePtr->getNodeInfo()->userStructInfo()->m_a = 0;
00688             } 
00689             else
00690             {
00691                 // computes the $[w,h,a]$-number of a partial node. The computation is
00692                 // nontrivial for both $P$- and $Q$-nodes and is performed in the
00693                 // function [[haNumPnode]] for $P$-nodes and in the 
00694                 // function [[haNumQnode]] for $Q$-nodes.
00695                 // This chunk also updates the partial children stack of the parent.
00696                 nodePtr->status(PARTIAL);
00697                 if (nodePtr->getNodeInfo()->userStructInfo()->m_pertLeafCount < 
00698                     maxPertLeafCount)
00699                     partialChildren(nodePtr->parent())->pushFront(nodePtr);
00700 
00701                 if (nodePtr->type() == PQNodeRoot::PNode)
00702                    haNumPnode(nodePtr);
00703                 else
00704                    haNumQnode(nodePtr);
00705             }
00706         }
00707 
00708     }
00709 
00710     // Determine the root of the pertinent subtree, which the last processed node
00711     //[[nodePtr]] and finds the minimum of the $h$- and $a$-number of
00712     //[[m_pertinentRoot]]. In case that the minimum is equal to $0$, the
00713     //[[m_pertinentRoot]] stays of type $B$. Otherwise the type is selected
00714     //according to the minimum.
00715     this->m_pertinentRoot = nodePtr; 
00716     if (this->m_pertinentRoot->getNodeInfo()->userStructInfo()->m_h <
00717         this->m_pertinentRoot->getNodeInfo()->userStructInfo()->m_a)
00718        countDeletedLeaves = this->m_pertinentRoot->getNodeInfo()->userStructInfo()->m_h;
00719     else
00720        countDeletedLeaves = this->m_pertinentRoot->getNodeInfo()->userStructInfo()->m_a;
00721 
00722     if (countDeletedLeaves > 0)
00723     {
00724         if (this->m_pertinentRoot->getNodeInfo()->userStructInfo()->m_h <
00725             this->m_pertinentRoot->getNodeInfo()->userStructInfo()->m_a)
00726             this->m_pertinentRoot->getNodeInfo()->userStructInfo()->m_deleteTyp = H_TYPE;
00727         else         
00728             this->m_pertinentRoot->getNodeInfo()->userStructInfo()->m_deleteTyp = A_TYPE;
00729     }   
00730 
00731     findMinWHASequence(archiv,eliminatedKeys);
00732 
00733     return countDeletedLeaves;
00734 }
00735    
00736 
00737 
00738 /************************************************************************
00739                           findMinWHASequence
00740 ************************************************************************/ 
00741 
00742 template<class T,class Y> 
00743 void MaxSequencePQTree<T,Y>::
00744 findMinWHASequence(StackPure<PQNode<T,whaInfo*,Y>*> &archiv,
00745              SList<PQLeafKey<T,whaInfo*,Y>*> &eliminatedKeys)
00746 {
00768     //a pointer to a pertinent node of the $PQ$-tree that is currently examined.
00769     PQNode<T,whaInfo*,Y>   *nodePtr     = 0;
00770 
00771     //a pointer to the first child of type $h$ of [[nodePtr]].
00772     PQNode<T,whaInfo*,Y>   *hChild1     = 0;
00773 
00774     //a pointer to the second child of type $h$ of [[nodePtr]].
00775     PQNode<T,whaInfo*,Y>   *hChild2     = 0;
00776 
00777     //a pointer to the child of type $a$ of [[nodePtr]].
00778     PQNode<T,whaInfo*,Y>   *aChild      = 0;
00779 
00780     // pertinent sibling of hChild1
00781     PQNode<T,whaInfo*,Y>   *hChild2Sib  = 0;
00782 
00783     //counts the number of children of [[nodePtr]].
00784     int                     childCount  = 0;
00785 
00786     while (!archiv.empty())
00787     {
00788         childCount = 0;
00789         nodePtr = archiv.pop();
00790         /*
00791         Check if [[nodePtr]] is a full node whose delete type is either of 
00792         type $h$ or type $a$. Since there are no empty leaves in its 
00793         frontier, the node must therefore keep all its pertinent leaves 
00794         in its frontier and is depicted to be of type $b$.
00795         */
00796         if (nodePtr->status() == FULL && 
00797             (nodePtr->getNodeInfo()->userStructInfo()->m_deleteTyp == H_TYPE ||
00798              nodePtr->getNodeInfo()->userStructInfo()->m_deleteTyp == A_TYPE))
00799         {
00800             nodePtr->getNodeInfo()->userStructInfo()->m_deleteTyp = B_TYPE;
00801             this->m_pertinentNodes->pushFront(nodePtr);
00802         }
00803 
00804         /*
00805         Check if [[nodePtr]] is a leaf whose delete type is either of type $w$ or
00806         $b$. In case it is of type $w$, the leaf has to be removed from the
00807         tree to gain reducibility of the set $S$. 
00808         */
00809         else if (nodePtr->type() == PQNodeRoot::leaf)
00810         {
00811             if (nodePtr->getNodeInfo()->userStructInfo()->m_deleteTyp == W_TYPE)
00812                 eliminatedKeys.pushBack(nodePtr->getKey());
00813             else
00814                 this->m_pertinentNodes->pushFront(nodePtr);
00815         }
00816 
00817         /*
00818         Manage the case of [[nodePtr]] being either a partial $P$-node, a partial
00819         $Q$-node, or a full $P$- or $Q$-node, where in the latter case the
00820         delete type of [[nodePtr]] is of type $b$.
00821         */
00822         else
00823         switch (nodePtr->getNodeInfo()->userStructInfo()->m_deleteTyp)
00824         {
00825             case B_TYPE:
00826                 this->m_pertinentNodes->pushFront(nodePtr);
00827                 break;
00828 
00829             case W_TYPE:
00830                 markPertinentChildren(nodePtr,PERTINENT,W_TYPE);             
00831                 nodePtr->pertChildCount(0);
00832                 this->m_pertinentNodes->pushFront(nodePtr);
00833                 break;
00834                  
00835             case H_TYPE:
00836                 if (nodePtr->type() == PQNodeRoot::PNode)
00837                 {
00838                     /*
00839                     [[nodePtr]] is a $P$-node of type $h$. Mark all full
00840                     children of [[nodePtr]] to be of type $b$ (by doing nothing, since
00841                     the default is type $b$). It furthermore marks all partial children to
00842                     be of type $w$ except for the child stored in [[hChild1]] of the
00843                     information class of type [[whaInfo*]] of [[nodePtr]]. This child is
00844                     marked to be of type $h$.  
00845                     */
00846                     markPertinentChildren(nodePtr,PARTIAL,W_TYPE);
00847                     markPertinentChildren(nodePtr,FULL,B_TYPE);
00848                     if (nodePtr->getNodeInfo()->userStructInfo()->m_hChild1)
00849                     {
00850                         hChild1 = (PQNode<T,whaInfo*,Y>*)
00851                             nodePtr->getNodeInfo()->userStructInfo()->m_hChild1;   
00852                         hChild1->getNodeInfo()->userStructInfo()->m_deleteTyp = H_TYPE;
00853                         if (hChild1->getNodeInfo()->userStructInfo()->m_h < 
00854                             hChild1->getNodeInfo()->userStructInfo()->m_w )
00855                             childCount = 1;
00856                     }
00857                     nodePtr->pertChildCount(nodePtr->pertChildCount() + 
00858                         childCount - partialChildren(nodePtr)->size());
00859                 }   
00860                 else
00861                 {      
00862                     /*
00863                     [[nodePtr]] is a $Q$-node. Mark all pertinent children
00864                     to be of type $w$, except for the full children between the
00865                     [[hChild1]] and the endmost child of [[nodePtr]]. These full
00866                     children are marked $b$ while [[hChild1]] is marked to be of type
00867                     $h$. Setting the type of children to $b$ or $h$ is hidden in the
00868                     function call [[setHchild]] \label{setHChild}.
00869                     */
00870                     markPertinentChildren(nodePtr,PERTINENT,W_TYPE);
00871                     hChild1 = (PQNode<T,whaInfo*,Y>*)
00872                         nodePtr->getNodeInfo()->userStructInfo()->m_hChild1;
00873                     nodePtr->pertChildCount(setHchild(hChild1));
00874                 }
00875                 this->m_pertinentNodes->pushFront(nodePtr);
00876                 break;
00877 
00878                  
00879             case A_TYPE:
00880                 if (nodePtr->type() == PQNodeRoot::PNode)
00881                 {
00882                     /*
00883                     [[nodePtr]] is a $P$-node of type $a$. 
00884                     Distinguish two main cases, based on the existence of a 
00885                     child of [[nodePtr]] stored in [[aChild]] of the information
00886                     class of type [[_whaInfo]] of [[nodePtr]].
00887                     \begin{enumerate}
00888                     \item
00889                     If [[aChild]] is not empty, the chunk marks all full
00890                     and partial children of [[nodePtr]] to be of type $w$ and 
00891                     marks the child [[aChild]] to be of type $a$. 
00892                     \item
00893                     If [[aChild]] is empty, the chunk 
00894                     marks all full children of [[nodePtr]] to be of type $b$ 
00895                     (by doing nothing, since the default is type $b$). 
00896                     It furthermore marks all partial children to be of type $w$ 
00897                     except for the children stored in [[hChild1]] and
00898                     [[hChild2]] of the information class of type [[whaInfo*]] of
00899                     [[nodePtr]] which are marked to be of type $h$. Observe that
00900                     we have to distinguish the cases where both, [[_hChild]] and
00901                     [[hChild2]] are available, just [[_h_Child1]] is available or
00902                     none of the nodes exist.
00903                     \end{enumerate}
00904                     */
00905                     if (nodePtr->getNodeInfo()->userStructInfo()->m_aChild)
00906                     {
00907                         markPertinentChildren(nodePtr,PERTINENT,W_TYPE);
00908                         aChild = (PQNode<T,whaInfo*,Y>*)
00909                             nodePtr->getNodeInfo()->userStructInfo()->m_aChild;
00910                         aChild->getNodeInfo()->userStructInfo()->m_deleteTyp = A_TYPE;
00911                         nodePtr->pertChildCount(1);
00912                     }
00913                     else
00914                     {
00915                         markPertinentChildren(nodePtr,FULL,B_TYPE);
00916                         markPertinentChildren(nodePtr,PARTIAL,W_TYPE);
00917                         if (nodePtr->getNodeInfo()->userStructInfo()->m_hChild1)
00918                         {
00919                             hChild1 = (PQNode<T,whaInfo*,Y>*)
00920                                 nodePtr->getNodeInfo()->userStructInfo()->m_hChild1;
00921                             hChild1->getNodeInfo()->userStructInfo()->m_deleteTyp = H_TYPE;
00922                             if (hChild1->getNodeInfo()->userStructInfo()->m_h < 
00923                                 hChild1->getNodeInfo()->userStructInfo()->m_w)
00924                                 childCount = 1;
00925                         }
00926                         if (nodePtr->getNodeInfo()->userStructInfo()->m_hChild2)
00927                         {
00928                             hChild2 = (PQNode<T,whaInfo*,Y>*)
00929                                 nodePtr->getNodeInfo()->userStructInfo()->m_hChild2;
00930                             hChild2->getNodeInfo()->userStructInfo()->m_deleteTyp = H_TYPE;
00931                             if (hChild2->getNodeInfo()->userStructInfo()->m_h < 
00932                                 hChild2->getNodeInfo()->userStructInfo()->m_w)
00933                                 childCount++;
00934                         }
00935                         nodePtr->pertChildCount(nodePtr->pertChildCount() + childCount -
00936                                                 partialChildren(nodePtr)->size());
00937                     }
00938                 }
00939                 else
00940                 {
00941                     /*
00942                     [[nodePtr]] is a $Q$-node of type $a$. 
00943                     Distinguish two main cases, based on the existence of a child of
00944                     [[nodePtr]] stored in [[aChild]] of the information class of type 
00945                     [[_whaInfo]] of [[nodePtr]].
00946                     \begin{enumerate}
00947                     \item
00948                     If [[aChild]] is not empty, the chunk marks all full
00949                     and partial children of [[nodePtr]] to be of type $w$ and marks the
00950                     child [[aChild]] to be of type $a$. 
00951                     \item
00952                     If [[aChild]] is empty, the chunk 
00953                     marks all full and partial children of [[nodePtr]] to be of type $w$ 
00954                     except for the ones in the largest consecutive sequence of pertinent
00955                     children. This sequence
00956                     is depicted by the children [[hChild1]] and [[hChild2]] which may be
00957                     either full or partial. The children between [[hChild1]] and
00958                     [[hChild2]] are full and are marked $b$, while [[hChild1]] and
00959                     [[hChild2]] are marked $b$ or $h$, according to their status (see \cite{Lei97}).
00960                     Setting the type of the nodes is hidden in calling the function
00961                     [[setAchildren]] (see \ref{setAchildren}).
00962                     \end{enumerate}
00963                     */
00964                     if (nodePtr->getNodeInfo()->userStructInfo()->m_aChild)
00965                     {
00966                         aChild = (PQNode<T,whaInfo*,Y>*)
00967                             nodePtr->getNodeInfo()->userStructInfo()->m_aChild;
00968                         markPertinentChildren(nodePtr,PERTINENT,W_TYPE);
00969                         aChild->getNodeInfo()->userStructInfo()->m_deleteTyp = A_TYPE;
00970                         nodePtr->pertChildCount(1);
00971                     }
00972                     else
00973                     {
00974                         markPertinentChildren(nodePtr,PERTINENT,W_TYPE);
00975                         hChild2 = (PQNode<T,whaInfo*,Y>*)
00976                             nodePtr->getNodeInfo()->userStructInfo()->m_hChild2;
00977                         hChild2Sib = (PQNode<T,whaInfo*,Y>*)
00978                             nodePtr->getNodeInfo()->userStructInfo()->m_hChild2Sib;
00979                         nodePtr->pertChildCount(setAchildren(hChild2,hChild2Sib));
00980                     }
00981                 }
00982                 this->m_pertinentNodes->pushFront(nodePtr);
00983                 break;
00984         }
00985 
00986         /*
00987         After successfully determining the type of the children of [[nodePtr]],
00988         this chunk cleans up the information needed during the
00989         computation at the [[nodePtr]].
00990         */
00991         fullChildren(nodePtr)->clear();
00992         partialChildren(nodePtr)->clear();
00993         nodePtr->status(EMPTY);
00994         nodePtr->getNodeInfo()->userStructInfo()->m_hChild1 = 0;
00995         nodePtr->getNodeInfo()->userStructInfo()->m_hChild2 = 0;
00996         nodePtr->getNodeInfo()->userStructInfo()->m_aChild = 0;
00997         nodePtr->getNodeInfo()->userStructInfo()->m_w = 0;
00998         nodePtr->getNodeInfo()->userStructInfo()->m_h = 0;
00999         nodePtr->getNodeInfo()->userStructInfo()->m_a = 0;
01000         nodePtr->getNodeInfo()->userStructInfo()->m_deleteTyp = B_TYPE;
01001 
01002     }
01003 
01004 }
01005                 
01006    
01007 /************************************************************************
01008                           setHchild
01009 ************************************************************************/ 
01010    
01011 template<class T,class Y> 
01012 int MaxSequencePQTree<T,Y>::setHchild(PQNode<T,whaInfo*,Y> *hChild1)
01013 
01014 {
01027     // counts the number of pertinent children corresponding to the $[w,h,a]$-numbering.
01028     int                     pertinentChildCount = 0;
01029 
01030     // is [[true]] as long as children with a full label are found, [[false]] otherwise.
01031     bool                    fullLabel           = false; 
01032 
01033 
01034     PQNode<T,whaInfo*,Y>    *currentNode         = hChild1; // dummy
01035     PQNode<T,whaInfo*,Y>    *nextSibling         = 0;       // dummy
01036     PQNode<T,whaInfo*,Y>    *oldSibling          = 0;       // dummy
01037 
01038     if (hChild1 != 0)
01039         fullLabel = true;
01040 
01041       
01042     /*
01043     Trace the sequence of full children with at most one incident
01044     pertinent child. It marks all full nodes as $b$-node and the partial
01045     child, if available as $h$-child. The beginning of the sequence is
01046     stored in [[currentNode]] which is equal to [[h_child1]] before
01047     entering the while loop. Observe that this chunk cases if the while
01048     loop while scanning the sequence has reached the second endmost child
01049     of the $Q$-node (see [[if (nextSibling == 0)]]). This case may
01050     appear, if all children of the $Q$-node are pertinent and the second
01051     endmost child is the only partial child. The value [[fullLabel]] is
01052     set to [[false]] as soon as the end of the sequence is detected.
01053     */
01054     while (fullLabel)
01055     {
01056        nextSibling = currentNode->getNextSib(oldSibling);
01057        if (!nextSibling)
01058           fullLabel = false;
01059 
01060        if (currentNode->status() == FULL)
01061        {
01062           currentNode->getNodeInfo()->userStructInfo()->m_deleteTyp = B_TYPE;
01063           pertinentChildCount++;
01064        }
01065 
01066        else
01067        {
01068           if (currentNode->status() == PARTIAL)
01069           {
01070               currentNode->getNodeInfo()->userStructInfo()->m_deleteTyp = H_TYPE;
01071               if ((currentNode->getNodeInfo()->userStructInfo()->m_pertLeafCount - 
01072                    currentNode->getNodeInfo()->userStructInfo()->m_h) > 0)
01073                  pertinentChildCount++;
01074           }
01075           fullLabel = false;
01076        }
01077        oldSibling = currentNode;
01078        currentNode = nextSibling;
01079     }
01080 
01081 
01082     return pertinentChildCount;
01083 }
01084    
01085 
01086 
01087    
01088 /************************************************************************
01089                           setAchildren
01090 ************************************************************************/ 
01091 
01092 template<class T,class Y>
01093 int MaxSequencePQTree<T,Y>::
01094 setAchildren(PQNode<T,whaInfo*,Y> *hChild2,
01095              PQNode<T,whaInfo*,Y> *hChild2Sib)     
01096 {
01122     // counts the pertinent children of the sequence.
01123     int                   pertinentChildCount = 0;
01124 
01125     //is [[false]] as long as the end of the sequence is not detected. 
01126     //[[true]] otherwise.   
01127     bool                   reachedEnd          = false;
01128 
01129     PQNode<T,whaInfo*,Y>    *currentNode         = hChild2; // dummy
01130     PQNode<T,whaInfo*,Y>    *nextSibling         = 0;       // dummy
01131     PQNode<T,whaInfo*,Y>    *oldSibling          = 0;       // dummy
01132    
01133 
01134     //Mark [[hChild2]] either as $b$- or as $h$-node.
01135     if (hChild2->status() == FULL)
01136         hChild2->getNodeInfo()->userStructInfo()->m_deleteTyp = B_TYPE;
01137     else {
01138         //1. node of sequence is EMPTY?
01139         OGDF_ASSERT(hChild2->status() == PARTIAL)
01140         hChild2->getNodeInfo()->userStructInfo()->m_deleteTyp = H_TYPE;
01141     }
01142     
01143     if (currentNode->getNodeInfo()->userStructInfo()->m_w - 
01144         currentNode->getNodeInfo()->userStructInfo()->m_h > 0)
01145         pertinentChildCount++;
01146   
01147     //Trace the sequence of pertinent children, marking the full children as $b$-node.
01148     //If a partial or empty node is detected, the end of the sequence is
01149     //reached and the partial node is marked as $h$-node.
01150     nextSibling = hChild2Sib;
01151     oldSibling = hChild2;
01152 
01153     if (nextSibling != 0)
01154     {
01155         currentNode = nextSibling;
01156         reachedEnd = false;
01157         while(!reachedEnd)
01158         {
01159             if (currentNode->status() == FULL)
01160             {
01161                 currentNode->getNodeInfo()->userStructInfo()->m_deleteTyp = B_TYPE;
01162                 pertinentChildCount++;
01163             }
01164             else
01165             {
01166                 if (currentNode->status() == PARTIAL)
01167                 {
01168                     currentNode->getNodeInfo()->userStructInfo()->m_deleteTyp = H_TYPE;
01169                     if ((currentNode->getNodeInfo()->userStructInfo()->m_w - 
01170                         currentNode->getNodeInfo()->userStructInfo()->m_h) > 0)
01171                     pertinentChildCount++;
01172                 }
01173                 reachedEnd = true;
01174             }
01175             if (!reachedEnd)
01176             {
01177                 nextSibling = currentNode->getNextSib(oldSibling);
01178                 if (nextSibling == 0)
01179                     reachedEnd = true;
01180                 oldSibling = currentNode;
01181                 currentNode = nextSibling;
01182             }
01183         }
01184     }
01185 
01186     return pertinentChildCount;   
01187 }
01188 
01189 
01190 
01191 
01192 /************************************************************************
01193                           markPertinentChildren
01194 ************************************************************************/ 
01195             
01196 template<class T,class Y>
01197 void MaxSequencePQTree<T,Y>::
01198 markPertinentChildren(PQNode<T,whaInfo*,Y>  *nodePtr,
01199                       int label,
01200                       int deleteTyp)
01201 {
01215     //PQNode<T,whaInfo*,Y>  *currentNode = 0;
01216   
01217     if (label == PERTINENT)
01218     {
01219         ListIterator<PQNode<T,whaInfo*,Y>*> it;
01220         for (it = partialChildren(nodePtr)->begin(); it.valid(); it++)
01221             (*it)->getNodeInfo()->userStructInfo()->m_deleteTyp = deleteTyp;
01222         for (it = fullChildren(nodePtr)->begin(); it.valid(); it++)
01223             (*it)->getNodeInfo()->userStructInfo()->m_deleteTyp = deleteTyp;
01224     }
01225     else if (label == PARTIAL)
01226     {  
01227         ListIterator<PQNode<T,whaInfo*,Y>*> it;
01228         for (it = partialChildren(nodePtr)->begin(); it.valid(); it++)
01229             (*it)->getNodeInfo()->userStructInfo()->m_deleteTyp = deleteTyp;   
01230     }
01231    
01232     else
01233     {
01234         ListIterator<PQNode<T,whaInfo*,Y>*> it;
01235         for (it = fullChildren(nodePtr)->begin(); it.valid(); it++)
01236             (*it)->getNodeInfo()->userStructInfo()->m_deleteTyp = deleteTyp;
01237     }
01238 }
01239      
01240 
01241 
01242 /************************************************************************
01243                           haNumPnode
01244 ************************************************************************/ 
01245 
01246 template<class T,class Y> 
01247 void MaxSequencePQTree<T,Y>::haNumPnode(PQNode<T,whaInfo*,Y> *nodePtr)
01248 
01249 
01250 {
01270     int                 sumParW   = 0;
01271     int                 sumMax1    = 0;
01272     int                 sumMax2    = 0;
01273     int                 sumHelp    = 0;
01274     PQNode<T,whaInfo*,Y>  *currentNode = 0;
01275     PQNode<T,whaInfo*,Y>  *hChild1    = 0;
01276     PQNode<T,whaInfo*,Y>  *hChild2    = 0;
01277     PQNode<T,whaInfo*,Y>  *aChild     = 0;
01278   
01279     /*
01280     Computes the $h$-number 
01281     \[ h = \sum_{i \in Par(\mbox{[[nodePtr]]})}w_i - \max_{i\in
01282       Par(\mbox{[[nodePtr]]})}1\left\{(w_i - h_i)\right\}\]   
01283     of the $P$-node [[nodePtr]].
01284     This is done by scanning all partial children stored in the
01285     [[partialChildrenStack]] of [[nodePtr]] summing up the $w_i$ for every
01286     $i \in Par(\mbox{[[nodePtr]]})$ and detecting 
01287     \[\max_{i\in Par(\mbox{[[nodePtr]]})}1\left\{(w_i - h_i)\right\}.\]
01288     Since this can be simultaneously it also computes
01289     \[\max_{i\in Par(\mbox{[[nodePtr]]})}2\left\{(w_i - h_i)\right\}\]
01290     which is needed to determine the $a$-number.
01291     After successfully determining the $h$-number, the [[hChild1]] and
01292     [[hChild2]] of [[nodePtr]] are set. 
01293     */
01294 
01295     ListIterator<PQNode<T,whaInfo*,Y>*> it;
01296     for (it = partialChildren(nodePtr)->begin(); it.valid(); it++)
01297     {
01298         currentNode = (*it);
01299         sumParW = sumParW + currentNode->getNodeInfo()->userStructInfo()->m_w;
01300         sumHelp = currentNode->getNodeInfo()->userStructInfo()->m_w -
01301                    currentNode->getNodeInfo()->userStructInfo()->m_h;
01302         if (sumMax1 <= sumHelp)
01303         {
01304             sumMax2 = sumMax1;
01305             hChild2 = hChild1;
01306             sumMax1 = sumHelp;
01307             hChild1 = currentNode;
01308         }
01309         else if (sumMax2 <= sumHelp)
01310         {
01311             sumMax2 = sumHelp;
01312             hChild2 = currentNode;
01313         }     
01314     }
01315     nodePtr->getNodeInfo()->userStructInfo()->m_hChild1 = hChild1;
01316     nodePtr->getNodeInfo()->userStructInfo()->m_hChild2 = hChild2;
01317     nodePtr->getNodeInfo()->userStructInfo()->m_h = sumParW - sumMax1;
01318 
01319     /*
01320     Compute the $a$-number of the $P$-node [[nodePtr]] where 
01321     \[ a = \min \{ \alpha_1, \alpha_2\}\]
01322     such that
01323     \[\alpha_1 = \sum_{i \in P(\mbox{[[nodePtr]]})}w_i - \max_{i\in
01324       P(\mbox{[[nodePtr]]})}\left\{(w_i - h_i)\right\} \]
01325     which can be computed calling the function [[alpha1beta1Number]] and 
01326     \[{\alpha}_2 \sum_{i \in Par(\mbox{[[nodePtr]]})}w_i - 
01327     \max_{i\in Par(\mbox{[[nodePtr]]})}1\left\{(w_i - h_i)\right\}
01328     - \max_{i\in Par(\mbox{[[nodePtr]]})}2\left\{(w_i - h_i)\right\}\]
01329     This chunk uses two extra variables
01330     \begin{description}
01331     \item[[alpha1]] $ = \alpha_1$.
01332     \item[[alpha2]] $ = \alpha_2$.
01333     \end{description}
01334     */
01335     int  alpha2 = sumParW - sumMax1 - sumMax2;
01336     int  alpha1 = alpha1beta1Number(nodePtr,&aChild);
01337                                 
01338     if (alpha1 <= alpha2)
01339     {
01340         nodePtr->getNodeInfo()->userStructInfo()->m_a = alpha1;
01341         nodePtr->getNodeInfo()->userStructInfo()->m_aChild = aChild;
01342     }
01343     else
01344     {
01345        nodePtr->getNodeInfo()->userStructInfo()->m_a = alpha2;
01346        nodePtr->getNodeInfo()->userStructInfo()->m_aChild = 0;
01347     }
01348 
01349 }// haNumPnode
01350   
01351 
01352 
01353 
01354 /************************************************************************
01355                           haNumQnode
01356 ************************************************************************/ 
01357 
01358 template<class T,class Y> 
01359 void MaxSequencePQTree<T,Y>::haNumQnode(PQNode<T,whaInfo*,Y> *nodePtr)               
01360 
01361 {
01373     int sumAllW = sumPertChild(nodePtr);
01374 
01375     hNumQnode(nodePtr,sumAllW);                  
01376     aNumQnode(nodePtr,sumAllW);
01377 }
01378 
01379 
01380 /************************************************************************
01381                           hNumQnode
01382 ************************************************************************/ 
01383 
01384 template<class T,class Y> 
01385 void MaxSequencePQTree<T,Y>::hNumQnode(PQNode<T,whaInfo*,Y> *nodePtr,
01386                                        int sumAllW)               
01387 
01388 {
01416     int                  sumLeft     = 0; 
01417     int                  sumRight    = 0;
01418     bool                  fullLabel = true;
01419     PQNode<T,whaInfo*,Y>   *leftChild    = 0;
01420     PQNode<T,whaInfo*,Y>   *rightChild   = 0;
01421     PQNode<T,whaInfo*,Y>   *holdSibling  = 0;
01422     PQNode<T,whaInfo*,Y>   *checkSibling = 0;
01423 
01424 
01425    
01426     //Compute the $h$-number of the $Q$-node [[nodePtr]]
01427 
01428     //Get endmost children of the $Q$-node [[nodePtr]].
01429     leftChild = nodePtr->getEndmost(0);
01430     rightChild = nodePtr->getEndmost(leftChild);
01431     OGDF_ASSERT(leftChild && rightChild)
01432 
01433     /*
01434     Check the left
01435     side of the $Q$-node [[nodePtr]] for the maximal consecutive sequence
01436     of full nodes, including at most one partial child at the end of the sequence.
01437 
01438     The variable [[fullLabel]] is [[true]] as long as the [[while]]-loop
01439     has not detected an partial {\bf or} empty child (see case [[if
01440     (leftChild->status() != FULL)]]. Observe that the
01441     construction of the [[while]]-loop examines the last child if it is a
01442     partial child as well (see case [[if (leftChild->status() !=
01443     EMPTY)]] where in the computation in [[sumLeft]] we  take advantage
01444     of the fact, that the $h$-number of a full child is zero).
01445     */
01446     while (fullLabel)            
01447     {
01448         if (leftChild->status() != FULL)
01449             fullLabel = false;
01450         if (leftChild->status() != EMPTY)
01451         {
01452             sumLeft = sumLeft +
01453                         leftChild->getNodeInfo()->userStructInfo()->m_w -
01454                         leftChild->getNodeInfo()->userStructInfo()->m_h;
01455             checkSibling = leftChild->getNextSib(holdSibling);
01456             if (checkSibling == 0)
01457                 fullLabel = false;
01458             holdSibling = leftChild;
01459             leftChild = checkSibling;
01460         }
01461     }
01462 
01463     /*
01464     Check the right
01465     side of the $Q$-node [[nodePtr]] for the maximal consecutive sequence
01466     of full nodes, including at most one partial child at the end of the sequence.
01467 
01468     The variable [[fullLabel]] is [[true]] as long as the [[while]]-loop
01469     has not detected an partial {\bf or} empty child (see case [[if
01470     (leftChild->status() != FULL)]]. Observe that the
01471     construction of the [[while]]-loop examines the last child if it is a
01472     partial child as well (see case [[if (leftChild->status() !=
01473     EMPTY)]] where in the computation in [[sumLeft]] we  take advantage
01474     of the fact, that the $h$-number of a full child is zero).
01475     */
01476     holdSibling = 0;           
01477     checkSibling = 0;           
01478     fullLabel = true;            
01479     while (fullLabel)            
01480     {
01481         if (rightChild->status() != FULL)
01482             fullLabel = false;
01483         if (rightChild->status() != EMPTY)
01484         {
01485             sumRight = sumRight +
01486                     rightChild->getNodeInfo()->userStructInfo()->m_w -
01487                        rightChild->getNodeInfo()->userStructInfo()->m_h;
01488 
01489             checkSibling = rightChild->getNextSib(holdSibling);
01490 
01491             if (checkSibling == 0)
01492                 fullLabel = false;
01493  
01494             holdSibling = rightChild;
01495             rightChild = checkSibling;
01496         }
01497     }
01498 
01499     /*
01500     After computing the number of pertinent leaves that stay in the $PQ$-tree
01501     when keeping either the left pertinent or the right pertinent side of
01502     the $Q$-node in the tree, this chunk chooses the side where the
01503     maximum number of leaves stay in the tree.  
01504     Observe that we have to case the fact, that on both sides of the
01505     $Q$-node [[nodePtr]] no pertinent children are.
01506     */
01507     leftChild = nodePtr->getEndmost(0);
01508     rightChild = nodePtr->getEndmost(leftChild);
01509     if (sumLeft == 0 && sumRight == 0)
01510     {
01511         nodePtr->getNodeInfo()->userStructInfo()->m_h = sumAllW;
01512         nodePtr->getNodeInfo()->userStructInfo()->m_hChild1 = 0;
01513     }
01514     else if (sumLeft < sumRight)
01515     {
01516         nodePtr->getNodeInfo()->userStructInfo()->m_h = sumAllW - sumRight;
01517         nodePtr->getNodeInfo()->userStructInfo()->m_hChild1 = rightChild;
01518     }
01519     else
01520     {
01521         nodePtr->getNodeInfo()->userStructInfo()->m_h = sumAllW - sumLeft;
01522         nodePtr->getNodeInfo()->userStructInfo()->m_hChild1 = leftChild;
01523     }
01524 }
01525 
01526 
01527 
01528 /************************************************************************
01529                           aNumQnode
01530 ************************************************************************/ 
01531 
01532 template<class T,class Y> 
01533 void MaxSequencePQTree<T,Y>::aNumQnode(PQNode<T,whaInfo*,Y> *nodePtr,
01534                                        int sumAllW)               
01535 
01536 {
01582     PQNode<T,whaInfo*,Y>   *aChild      = 0;
01583     int                     beta1       = alpha1beta1Number(nodePtr,&aChild);
01584     int                     beta2       = 0;
01585     int                     aSum        = 0;     
01586     int                     aHoldSum    = 0;
01587     bool                    endReached  = 0;   
01588     PQNode<T,whaInfo*,Y>   *leftMost      = 0;
01589     PQNode<T,whaInfo*,Y>   *leftSib       = 0;
01590     PQNode<T,whaInfo*,Y>   *leftMostHold  = 0;
01591     PQNode<T,whaInfo*,Y>   *leftSibHold   = 0;
01592     PQNode<T,whaInfo*,Y>   *actualNode    = 0;
01593     PQNode<T,whaInfo*,Y>   *currentNode    = 0;
01594     PQNode<T,whaInfo*,Y>   *lastChild     = 0;
01595     PQNode<T,whaInfo*,Y>   *holdSibling  = 0;
01596     PQNode<T,whaInfo*,Y>   *checkSibling = 0;
01597                                       // pointer to the second endmost child
01598 
01599     SList<PQNode<T,whaInfo*,Y>*> sequence; 
01600                              
01601     actualNode   = nodePtr->getEndmost(0);
01602     lastChild    = nodePtr->getEndmost(actualNode);
01603 
01604     endReached = false;
01605     while (!endReached)
01606     {
01607         /*
01608         Process the children of a $Q$-node [[nodePtr]] from one end of [[nodePtr]] to the
01609         other, searching for a consecutive sequence of pertinent nodes with
01610         the maximum number of pertinent leaves, such that all nodes of the
01611         pertinent sequence are full except possibly the two endmost children
01612         which are allowed to be partial.
01613         */
01614         if (sequence.empty())
01615         {
01616             /*
01617             Currently no consecutive sequence of pertinent children
01618             is detected while scanning the children of the $Q$-node. 
01619             Check the [[actualNode]] if it is the first child of
01620             such a sequence. If so, place [[actualNode]] on the stack [[sequence]].
01621             */
01622             if (actualNode->status() != EMPTY)
01623             {
01624                 sequence.pushFront(actualNode);
01625                 leftMost = 0;
01626                 leftSib = 0;
01627             }
01628         }
01629         else
01630         {
01631             /*
01632             [[actualNode]] is a sibling of a consecutive pertinent sequence that has
01633             been detected in an earlier step, while scanning the children of the $Q$-node. 
01634             This chunk cases on the status of the [[actualNode]]. 
01635 
01636             In case that the status of
01637             the [[actualNode]] is [[Full]], [[actualNode]] is included into the
01638             sequence of pertinent children by pushing it onto the stack
01639             [[sequence]]. 
01640 
01641             If [[actualNode]] is EMPTY, we have reached the end of
01642             the actual consecutive sequence of pertinent children. In this case
01643             the $a$-numbers of the nodes in the sequence have to be summed up.
01644 
01645             If the [[actualNode]] is [[PARTIAL]], the end of the consecutive sequence
01646             is reached and similar actions to the [[EMPTY]] have to be
01647             performed. However, [[actualNode]] might mark the beginning of
01648             another pertinent sequence. Hence it has to be stored again in [[sequence]].
01649             */
01650             if (actualNode->status() == FULL)
01651                 sequence.pushFront(actualNode);
01652 
01653             else if (actualNode->status() == EMPTY)
01654             {
01655                 /*
01656                 If [[actualNode]] is EMPTY, the end of
01657                 the actual consecutive sequence of pertinent children is reached . In
01658                 this case, all nodes of the currently examined consecutive sequence are stored in
01659                 [[sequence]].
01660                 They are removed from the stack and their $a$-numbers are summed up.
01661                 If necessary, the sequence with the largest number of full leaves in
01662                 its frontier is updated. 
01663                 */
01664                 aSum = 0;
01665 
01666                 while (!sequence.empty())
01667                 {
01668                    currentNode = sequence.popFrontRet();
01669                    aSum = aSum + currentNode->getNodeInfo()->userStructInfo()->m_w
01670                             - currentNode->getNodeInfo()->userStructInfo()->m_h;
01671                    if (sequence.size() == 1)
01672                        leftSib = currentNode;
01673                 }
01674                 leftMost = currentNode;
01675 
01676                 if (aHoldSum < aSum)
01677                 {
01678                     aHoldSum = aSum;
01679                     leftMostHold = leftMost;
01680                     leftSibHold = leftSib;
01681                 }
01682 
01683             }
01684             else
01685             {
01686                 /*
01687                 If the [[actualNode]] is [[PARTIAL]], the end of the consecutive sequence
01688                 is reached. In
01689                 this case, all nodes of the currently examined consecutive sequence are stored in
01690                 [[sequence]].
01691                 They are removed from the stack and their $a$-numbers are summed up.
01692                 If necessary, the sequence with the largest number of full leaves in
01693                 its frontier is updated. 
01694                 However, [[actualNode]] might mark the beginning of
01695                 another pertinent sequence. Hence it has to be stored again in [[sequence]].
01696                 */
01697                 sequence.pushFront(actualNode);
01698                 aSum = 0;
01699                 while (!sequence.empty())
01700                 {
01701                     currentNode = sequence.popFrontRet();
01702                     aSum = aSum + currentNode->getNodeInfo()->userStructInfo()->m_w -
01703                             currentNode->getNodeInfo()->userStructInfo()->m_h;
01704                     if (sequence.size() == 1)
01705                         leftSib = currentNode;
01706                 }
01707                 if (leftSib == 0)
01708                     leftSib = actualNode;
01709                 leftMost = currentNode;
01710 
01711                 if (aHoldSum < aSum)
01712                 {
01713                     aHoldSum = aSum;
01714                     leftMostHold = leftMost;
01715                     leftSibHold = leftSib;
01716                 }
01717 
01718                 sequence.pushFront(actualNode);
01719 
01720             }
01721         }
01722 
01723         // Get the next sibling
01724         if (actualNode != lastChild)
01725         {
01726             checkSibling = actualNode->getNextSib(holdSibling);
01727             holdSibling = actualNode;
01728             actualNode = checkSibling;
01729         }
01730         else
01731                                           // End of Q-node reached.
01732            endReached = true;
01733     }
01734 
01735 
01736     /*
01737     After processing
01738     the last child of the $Q$-node, this chunk checks, if this child was
01739     part of a pertinent consecutive sequence. If this is the case, the
01740     stack storing this seuquence was not emptied and the number of
01741     pertinent leaves in its frontier was not computed. Furhtermore the
01742     last child was not stored in [[sequence]]. 
01743     This chunk does the necessary updates for the last consecutive sequence.
01744     */
01745     if (!sequence.empty())
01746     {
01747         aSum = 0; 
01748         while (!sequence.empty())
01749         {
01750             currentNode = sequence.popFrontRet();
01751             aSum = aSum + currentNode->getNodeInfo()->userStructInfo()->m_w - 
01752                    currentNode->getNodeInfo()->userStructInfo()->m_h;
01753             if (sequence.size() == 1)
01754                 leftSib = currentNode;
01755         }
01756         leftMost = currentNode;
01757 
01758         if (aHoldSum < aSum)
01759         {
01760             aHoldSum = aSum;
01761             leftMostHold = leftMost;
01762             leftSibHold = leftSib;
01763         }
01764     }
01765     /*
01766     After computing 
01767     ${\beta}_1$ and ${\beta}_2$, describing the number of pertinent leaves
01768     that have to be deleted when choosing either one node to be an
01769     $a$-node or a complete sequence, this chunk gets the $a$-number of the
01770     $Q$-node [[nodePtr]] by choosing 
01771     \[a = \min\{{\beta}_1,{\beta}_2\]
01772     Also set [[aChild]] and [[hChild2]] of [[nodePtr]] according to the
01773     chosen minimum.
01774     */
01775     beta2 = sumAllW - aHoldSum;
01776     if (beta2 < beta1)
01777     {
01778         nodePtr->getNodeInfo()->userStructInfo()->m_a = beta2;
01779         nodePtr->getNodeInfo()->userStructInfo()->m_hChild2 = leftMostHold;
01780         nodePtr->getNodeInfo()->userStructInfo()->m_hChild2Sib = leftSibHold;
01781         nodePtr->getNodeInfo()->userStructInfo()->m_aChild = 0;
01782     }
01783     else
01784     {
01785         nodePtr->getNodeInfo()->userStructInfo()->m_a = beta1;
01786         nodePtr->getNodeInfo()->userStructInfo()->m_hChild2 = 0;
01787         nodePtr->getNodeInfo()->userStructInfo()->m_hChild2Sib = 0;
01788         nodePtr->getNodeInfo()->userStructInfo()->m_aChild = aChild;
01789     }
01790 
01791 }
01792 
01793 
01794 /************************************************************************
01795                           alpha1beta1Number
01796 ************************************************************************/ 
01797       
01798 template<class T,class Y> 
01799 int MaxSequencePQTree<T,Y>::
01800 alpha1beta1Number(PQNode<T,whaInfo*,Y> *nodePtr,
01801                   PQNode<T,whaInfo*,Y> **aChild)
01802                 
01803 {
01827     int                 sumMaxA   = 0;
01828     int                 sumAllW   = 0;
01829     int                 sumHelp    = 0;
01830     PQNode<T,whaInfo*,Y>  *currentNode = 0;
01831   
01832     ListIterator<PQNode<T,whaInfo*,Y>*> it;
01833     for (it = fullChildren(nodePtr)->begin(); it.valid(); it++)
01834     {
01835         currentNode = (*it);
01836         sumAllW = sumAllW +
01837                   currentNode->getNodeInfo()->userStructInfo()->m_w;
01838         sumHelp = currentNode->getNodeInfo()->userStructInfo()->m_w
01839                   - currentNode->getNodeInfo()->userStructInfo()->m_a;
01840         if (sumMaxA < sumHelp)
01841         {
01842             sumMaxA = sumHelp;
01843             (*aChild) = currentNode;
01844         }
01845     }
01846    
01847     for (it = partialChildren(nodePtr)->begin(); it.valid(); it++)
01848     {
01849         currentNode = (*it);
01850         sumAllW = sumAllW +
01851                     currentNode->getNodeInfo()->userStructInfo()->m_w;
01852         sumHelp = currentNode->getNodeInfo()->userStructInfo()->m_w -
01853                   currentNode->getNodeInfo()->userStructInfo()->m_a;
01854         if (sumMaxA < sumHelp)
01855         {
01856             sumMaxA = sumHelp;
01857             (*aChild) = currentNode;
01858         }
01859     }
01860     return (sumAllW - sumMaxA);
01861 
01862 }
01863 
01864 
01865 /************************************************************************
01866                           sumPertChild
01867 ************************************************************************/ 
01868 
01869 template<class T,class Y> 
01870 int MaxSequencePQTree<T,Y>::sumPertChild(PQNode<T,whaInfo*,Y> *nodePtr)
01871 
01872 {
01888     int                  sum = 0;
01889     ListIterator<PQNode<T,whaInfo*,Y>*> it;
01890     for (it = fullChildren(nodePtr)->begin(); it.valid(); it++)
01891       sum = sum + (*it)->getNodeInfo()->userStructInfo()->m_w;
01892     for (it = partialChildren(nodePtr)->begin(); it.valid(); it++)
01893       sum = sum + (*it)->getNodeInfo()->userStructInfo()->m_w;
01894 
01895     return sum;
01896 }
01897 
01898 
01899 /**************************************************************************************
01900                            GetParent
01901 ***************************************************************************************/ 
01902 
01903 template<class T,class Y> 
01904 PQNode<T,whaInfo*,Y>* MaxSequencePQTree<T,Y>::
01905 GetParent(PQNode<T,whaInfo*,Y>* nodePtr)
01906 
01907 {
01929     if (nodePtr->parent() == 0)
01930         return 0;
01931     else if (nodePtr->parent()->status() != ELIMINATED)
01932         return nodePtr->parent();
01933     else
01934     {
01935         PQNode<T,whaInfo*,Y>         *nextNode    = nodePtr;
01936         PQNode<T,whaInfo*,Y>         *currentNode = 0;
01937         PQNode<T,whaInfo*,Y>         *oldSib      = 0;
01938         SListPure<PQNode<T,whaInfo*,Y>*> L;
01939 
01940         currentNode = nodePtr->getNextSib(0);
01941         oldSib = nodePtr;
01942         L.pushFront(nodePtr);
01943         while (currentNode->parent()->status() == ELIMINATED)
01944         {
01945             L.pushFront(currentNode);
01946             nextNode = currentNode->getNextSib(oldSib);
01947             oldSib = currentNode;
01948             currentNode = nextNode;
01949         }
01950         while (!L.empty())
01951             L.popFrontRet()->parent(currentNode->parent());
01952         return currentNode->parent();
01953    }
01954 }
01955 
01956 
01957 
01958 }
01959 
01960 #endif
01961 
01962 
01963