- The number of gcc-4.0 warnings has significantly decreases.
- Some code clean-up in gui
     2  * lemon/fib_heap.h - Part of LEMON, a generic C++ optimization library
 
     4  * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
 
     5  * (Egervary Research Group on Combinatorial Optimization, EGRES).
 
     7  * Permission to use, modify and distribute this software is granted
 
     8  * provided that this copyright notice appears in all copies. For
 
     9  * precise terms see the accompanying LICENSE file.
 
    11  * This software is provided "AS IS" with no warranty of any kind,
 
    12  * express or implied, and with no claim as to its suitability for any
 
    17 #ifndef LEMON_FIB_HEAP_H
 
    18 #define LEMON_FIB_HEAP_H
 
    22 ///\brief Fibonacci Heap implementation.
 
    30   /// \addtogroup auxdat
 
    35   ///This class implements the \e Fibonacci \e heap data structure. A \e heap
 
    36   ///is a data structure for storing items with specified values called \e
 
    37   ///priorities in such a way that finding the item with minimum priority is
 
    38   ///efficient. \c Compare specifies the ordering of the priorities. In a heap
 
    39   ///one can change the priority of an item, add or erase an item, etc.
 
    41   ///The methods \ref increase and \ref erase are not efficient in a Fibonacci
 
    42   ///heap. In case of many calls to these operations, it is better to use a
 
    45   ///\param Item Type of the items to be stored.  
 
    46   ///\param Prio Type of the priority of the items.
 
    47   ///\param ItemIntMap A read and writable Item int map, used internally
 
    48   ///to handle the cross references.
 
    49   ///\param Compare A class for the ordering of the priorities. The
 
    50   ///default is \c std::less<Prio>.
 
    54   ///\author Jacint Szabo 
 
    57   template <typename Item, 
 
    62   template <typename Item, 
 
    65 	    typename Compare = std::less<Prio> >
 
    69     typedef Prio PrioType;
 
    74     std::vector<store> container;
 
    81     ///Status of the nodes
 
    83       ///The node is in the heap
 
    85       ///The node has never been in the heap
 
    87       ///The node was in the heap but it got out of it
 
    94        \c _iimap should be given to the constructor, since it is
 
    95        used internally to handle the cross references.
 
    97     explicit FibHeap(ItemIntMap &_iimap) 
 
    98       : minimum(0), iimap(_iimap), num_items() {} 
 
   103        \c _iimap should be given to the constructor, since it is used
 
   104        internally to handle the cross references. \c _comp is an
 
   105        object for ordering of the priorities. 
 
   107     FibHeap(ItemIntMap &_iimap, const Compare &_comp) : minimum(0), 
 
   108 		  iimap(_iimap), comp(_comp), num_items() {}
 
   110     ///The number of items stored in the heap.
 
   113        Returns the number of items stored in the heap.
 
   115     int size() const { return num_items; }
 
   117     ///Checks if the heap stores no items.
 
   120        Returns \c true if and only if the heap stores no items.
 
   122     bool empty() const { return num_items==0; }
 
   124     ///\c item gets to the heap with priority \c value independently if \c item was already there.
 
   127        This method calls \ref push(\c item, \c value) if \c item is not
 
   128        stored in the heap and it calls \ref decrease(\c item, \c value) or
 
   129        \ref increase(\c item, \c value) otherwise.
 
   131     void set (Item const item, PrioType const value); 
 
   133     ///Adds \c item to the heap with priority \c value. 
 
   136        Adds \c item to the heap with priority \c value. 
 
   137        \pre \c item must not be stored in the heap. 
 
   139     void push (Item const item, PrioType const value);
 
   141     ///Returns the item with minimum priority relative to \c Compare.
 
   144        This method returns the item with minimum priority relative to \c
 
   146        \pre The heap must be nonempty.  
 
   148     Item top() const { return container[minimum].name; }
 
   150     ///Returns the minimum priority relative to \c Compare.
 
   153        It returns the minimum priority relative to \c Compare.
 
   154        \pre The heap must be nonempty.
 
   156     PrioType prio() const { return container[minimum].prio; }
 
   158     ///Returns the priority of \c item.
 
   161        This function returns the priority of \c item.
 
   162        \pre \c item must be in the heap.
 
   164     PrioType& operator[](const Item& item) { 
 
   165       return container[iimap[item]].prio; 
 
   168     ///Returns the priority of \c item.
 
   171        It returns the priority of \c item.
 
   172        \pre \c item must be in the heap.
 
   174     const PrioType& operator[](const Item& item) const { 
 
   175       return container[iimap[item]].prio; 
 
   179     ///Deletes the item with minimum priority relative to \c Compare.
 
   182     This method deletes the item with minimum priority relative to \c
 
   183     Compare from the heap.  
 
   184     \pre The heap must be non-empty.  
 
   188     ///Deletes \c item from the heap.
 
   191        This method deletes \c item from the heap, if \c item was already
 
   192        stored in the heap. It is quite inefficient in Fibonacci heaps.
 
   194     void erase (const Item& item); 
 
   196     ///Decreases the priority of \c item to \c value.
 
   199        This method decreases the priority of \c item to \c value.
 
   200        \pre \c item must be stored in the heap with priority at least \c
 
   201        value relative to \c Compare.
 
   203     void decrease (Item item, PrioType const value); 
 
   205     ///Increases the priority of \c item to \c value.
 
   208        This method sets the priority of \c item to \c value. Though
 
   209        there is no precondition on the priority of \c item, this
 
   210        method should be used only if it is indeed necessary to increase
 
   211        (relative to \c Compare) the priority of \c item, because this
 
   212        method is inefficient.
 
   214     void increase (Item item, PrioType const value) {
 
   220     ///Returns if \c item is in, has already been in, or has never been in the heap.
 
   223        This method returns PRE_HEAP if \c item has never been in the
 
   224        heap, IN_HEAP if it is in the heap at the moment, and POST_HEAP
 
   225        otherwise. In the latter case it is possible that \c item will
 
   226        get back to the heap again.
 
   228     state_enum state(const Item &item) const {
 
   231 	if ( container[i].in ) i=0;
 
   234       return state_enum(i);
 
   240     void makeroot(int c);
 
   241     void cut(int a, int b);
 
   243     void fuse(int a, int b);
 
   248       friend class FibHeap;
 
   260       store() : parent(-1), child(-1), degree(), marked(false), in(true) {} 
 
   266     // **********************************************************************
 
   268     // **********************************************************************
 
   270   template <typename Item, typename Prio, typename ItemIntMap, 
 
   272   void FibHeap<Item, Prio, ItemIntMap, Compare>::set 
 
   273   (Item const item, PrioType const value) 
 
   276     if ( i >= 0 && container[i].in ) {
 
   277       if ( comp(value, container[i].prio) ) decrease(item, value); 
 
   278       if ( comp(container[i].prio, value) ) increase(item, value); 
 
   279     } else push(item, value);
 
   282   template <typename Item, typename Prio, typename ItemIntMap, 
 
   284   void FibHeap<Item, Prio, ItemIntMap, Compare>::push 
 
   285   (Item const item, PrioType const value) {
 
   288 	int s=container.size();
 
   289 	iimap.set( item, s );	
 
   292 	container.push_back(st);
 
   295 	container[i].parent=container[i].child=-1;
 
   296 	container[i].degree=0;
 
   297 	container[i].in=true;
 
   298 	container[i].marked=false;
 
   302 	container[container[minimum].right_neighbor].left_neighbor=i;
 
   303 	container[i].right_neighbor=container[minimum].right_neighbor;
 
   304 	container[minimum].right_neighbor=i;
 
   305 	container[i].left_neighbor=minimum;
 
   306 	if ( comp( value, container[minimum].prio) ) minimum=i; 
 
   308 	container[i].right_neighbor=container[i].left_neighbor=i;
 
   311       container[i].prio=value;
 
   315   template <typename Item, typename Prio, typename ItemIntMap, 
 
   317   void FibHeap<Item, Prio, ItemIntMap, Compare>::pop() {
 
   318       /*The first case is that there are only one root.*/
 
   319       if ( container[minimum].left_neighbor==minimum ) {
 
   320 	container[minimum].in=false;
 
   321 	if ( container[minimum].degree!=0 ) { 
 
   322 	  makeroot(container[minimum].child);
 
   323 	  minimum=container[minimum].child;
 
   327 	int right=container[minimum].right_neighbor;
 
   329 	container[minimum].in=false;
 
   330 	if ( container[minimum].degree > 0 ) {
 
   331 	  int left=container[minimum].left_neighbor;
 
   332 	  int child=container[minimum].child;
 
   333 	  int last_child=container[child].left_neighbor;
 
   337 	  container[left].right_neighbor=child;
 
   338 	  container[child].left_neighbor=left;
 
   339 	  container[right].left_neighbor=last_child;
 
   340 	  container[last_child].right_neighbor=right;
 
   344       } // the case where there are more roots
 
   349   template <typename Item, typename Prio, typename ItemIntMap, 
 
   351   void FibHeap<Item, Prio, ItemIntMap, Compare>::erase 
 
   355       if ( i >= 0 && container[i].in ) { 	
 
   356 	if ( container[i].parent!=-1 ) {
 
   357 	  int p=container[i].parent;
 
   361 	minimum=i;     //As if its prio would be -infinity
 
   366   template <typename Item, typename Prio, typename ItemIntMap, 
 
   368   void FibHeap<Item, Prio, ItemIntMap, Compare>::decrease 
 
   369   (Item item, PrioType const value) {
 
   371       container[i].prio=value;
 
   372       int p=container[i].parent;
 
   374       if ( p!=-1 && comp(value, container[p].prio) ) {
 
   378       if ( comp(value, container[minimum].prio) ) minimum=i; 
 
   382   template <typename Item, typename Prio, typename ItemIntMap, 
 
   384   void FibHeap<Item, Prio, ItemIntMap, Compare>::balance() {      
 
   386     int maxdeg=int( std::floor( 2.08*log(double(container.size()))))+1;
 
   388     std::vector<int> A(maxdeg,-1); 
 
   391      *Recall that now minimum does not point to the minimum prio element.
 
   392      *We set minimum to this during balance().
 
   394     int anchor=container[minimum].left_neighbor; 
 
   400 	if ( anchor==active ) end=true;
 
   401 	int d=container[active].degree;
 
   402 	next=container[active].right_neighbor;
 
   405 	  if( comp(container[active].prio, container[A[d]].prio) ) {
 
   418        while ( container[minimum].parent >=0 ) minimum=container[minimum].parent;
 
   422 	 if ( comp(container[s].prio, container[minimum].prio) ) minimum=s;
 
   423 	 s=container[s].right_neighbor;
 
   427   template <typename Item, typename Prio, typename ItemIntMap, 
 
   429   void FibHeap<Item, Prio, ItemIntMap, Compare>::makeroot 
 
   433 	container[s].parent=-1;
 
   434 	s=container[s].right_neighbor;
 
   439   template <typename Item, typename Prio, typename ItemIntMap, 
 
   441   void FibHeap<Item, Prio, ItemIntMap, Compare>::cut 
 
   444      *Replacing a from the children of b.
 
   446     --container[b].degree;
 
   448     if ( container[b].degree !=0 ) {
 
   449       int child=container[b].child;
 
   451 	container[b].child=container[child].right_neighbor;
 
   456     /*Lacing a to the roots.*/
 
   457     int right=container[minimum].right_neighbor;
 
   458     container[minimum].right_neighbor=a;
 
   459     container[a].left_neighbor=minimum;
 
   460     container[a].right_neighbor=right;
 
   461     container[right].left_neighbor=a;
 
   463     container[a].parent=-1;
 
   464     container[a].marked=false;
 
   468   template <typename Item, typename Prio, typename ItemIntMap, 
 
   470   void FibHeap<Item, Prio, ItemIntMap, Compare>::cascade 
 
   473       if ( container[a].parent!=-1 ) {
 
   474 	int p=container[a].parent;
 
   476 	if ( container[a].marked==false ) container[a].marked=true;
 
   485   template <typename Item, typename Prio, typename ItemIntMap, 
 
   487   void FibHeap<Item, Prio, ItemIntMap, Compare>::fuse 
 
   491       /*Lacing b under a.*/
 
   492       container[b].parent=a;
 
   494       if (container[a].degree==0) {
 
   495 	container[b].left_neighbor=b;
 
   496 	container[b].right_neighbor=b;
 
   497 	container[a].child=b;	
 
   499 	int child=container[a].child;
 
   500 	int last_child=container[child].left_neighbor;
 
   501 	container[child].left_neighbor=b;
 
   502 	container[b].right_neighbor=child;
 
   503 	container[last_child].right_neighbor=b;
 
   504 	container[b].left_neighbor=last_child;
 
   507       ++container[a].degree;
 
   509       container[b].marked=false;
 
   514    *It is invoked only if a has siblings.
 
   516   template <typename Item, typename Prio, typename ItemIntMap, 
 
   518   void FibHeap<Item, Prio, ItemIntMap, Compare>::unlace 
 
   520       int leftn=container[a].left_neighbor;
 
   521       int rightn=container[a].right_neighbor;
 
   522       container[leftn].right_neighbor=rightn;
 
   523       container[rightn].left_neighbor=leftn;
 
   530 #endif //LEMON_FIB_HEAP_H