Removed some unnecessary files.
     2  * src/lemon/fib_heap.h - Part of LEMON, a generic C++ optimization library
 
     4  * Copyright (C) 2004 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
 
     5  * (Egervary Combinatorial Optimization Research Group, 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, for the usage of
 
    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;
 
    87     FibHeap(ItemIntMap &_iimap) : minimum(0), iimap(_iimap), num_items() {} 
 
    88     FibHeap(ItemIntMap &_iimap, const Compare &_comp) : minimum(0), 
 
    89       iimap(_iimap), comp(_comp), num_items() {}
 
    91     ///The number of items stored in the heap.
 
    94        Returns the number of items stored in the heap.
 
    96     int size() const { return num_items; }
 
    98     ///Checks if the heap stores no items.
 
   101        Returns \c true if and only if the heap stores no items.
 
   103     bool empty() const { return num_items==0; }
 
   105     ///\c item gets to the heap with priority \c value independently if \c item was already there.
 
   108        This method calls \ref push(\c item, \c value) if \c item is not
 
   109        stored in the heap and it calls \ref decrease(\c item, \c value) or
 
   110        \ref increase(\c item, \c value) otherwise.
 
   112     void set (Item const item, PrioType const value); 
 
   114     ///Adds \c item to the heap with priority \c value. 
 
   117        Adds \c item to the heap with priority \c value. 
 
   118        \pre \c item must not be stored in the heap. 
 
   120     void push (Item const item, PrioType const value);
 
   122     ///Returns the item with minimum priority relative to \c Compare.
 
   125        This method returns the item with minimum priority relative to \c
 
   127        \pre The heap must be nonempty.  
 
   129     Item top() const { return container[minimum].name; }
 
   131     ///Returns the minimum priority relative to \c Compare.
 
   134        It returns the minimum priority relative to \c Compare.
 
   135        \pre The heap must be nonempty.
 
   137     PrioType prio() const { return container[minimum].prio; }
 
   139     ///Returns the priority of \c item.
 
   142        This function returns the priority of \c item.
 
   143        \pre \c item must be in the heap.
 
   145     PrioType& operator[](const Item& item) { 
 
   146       return container[iimap[item]].prio; 
 
   149     ///Returns the priority of \c item.
 
   152        It returns the priority of \c item.
 
   153        \pre \c item must be in the heap.
 
   155     const PrioType& operator[](const Item& item) const { 
 
   156       return container[iimap[item]].prio; 
 
   160     ///Deletes the item with minimum priority relative to \c Compare.
 
   163     This method deletes the item with minimum priority relative to \c
 
   164     Compare from the heap.  
 
   165     \pre The heap must be non-empty.  
 
   169     ///Deletes \c item from the heap.
 
   172        This method deletes \c item from the heap, if \c item was already
 
   173        stored in the heap. It is quite inefficient in Fibonacci heaps.
 
   175     void erase (const Item& item); 
 
   177     ///Decreases the priority of \c item to \c value.
 
   180        This method decreases the priority of \c item to \c value.
 
   181        \pre \c item must be stored in the heap with priority at least \c
 
   182        value relative to \c Compare.
 
   184     void decrease (Item item, PrioType const value); 
 
   186     ///Increases the priority of \c item to \c value.
 
   189        This method sets the priority of \c item to \c value. Though
 
   190        there is no precondition on the priority of \c item, this
 
   191        method should be used only if it is indeed necessary to increase
 
   192        (relative to \c Compare) the priority of \c item, because this
 
   193        method is inefficient.
 
   195     void increase (Item item, PrioType const value) {
 
   201     ///Returns if \c item is in, has already been in, or has never been in the heap.
 
   204        This method returns PRE_HEAP if \c item has never been in the
 
   205        heap, IN_HEAP if it is in the heap at the moment, and POST_HEAP
 
   206        otherwise. In the latter case it is possible that \c item will
 
   207        get back to the heap again.
 
   209     state_enum state(const Item &item) const {
 
   212 	if ( container[i].in ) i=0;
 
   215       return state_enum(i);
 
   221     void makeroot(int c);
 
   222     void cut(int a, int b);
 
   224     void fuse(int a, int b);
 
   229       friend class FibHeap;
 
   241       store() : parent(-1), child(-1), degree(), marked(false), in(true) {} 
 
   247     // **********************************************************************
 
   249     // **********************************************************************
 
   251   template <typename Item, typename Prio, typename ItemIntMap, 
 
   253   void FibHeap<Item, Prio, ItemIntMap, Compare>::set 
 
   254   (Item const item, PrioType const value) 
 
   257     if ( i >= 0 && container[i].in ) {
 
   258       if ( comp(value, container[i].prio) ) decrease(item, value); 
 
   259       if ( comp(container[i].prio, value) ) increase(item, value); 
 
   260     } else push(item, value);
 
   263   template <typename Item, typename Prio, typename ItemIntMap, 
 
   265   void FibHeap<Item, Prio, ItemIntMap, Compare>::push 
 
   266   (Item const item, PrioType const value) {
 
   269 	int s=container.size();
 
   270 	iimap.set( item, s );	
 
   273 	container.push_back(st);
 
   276 	container[i].parent=container[i].child=-1;
 
   277 	container[i].degree=0;
 
   278 	container[i].in=true;
 
   279 	container[i].marked=false;
 
   283 	container[container[minimum].right_neighbor].left_neighbor=i;
 
   284 	container[i].right_neighbor=container[minimum].right_neighbor;
 
   285 	container[minimum].right_neighbor=i;
 
   286 	container[i].left_neighbor=minimum;
 
   287 	if ( comp( value, container[minimum].prio) ) minimum=i; 
 
   289 	container[i].right_neighbor=container[i].left_neighbor=i;
 
   292       container[i].prio=value;
 
   296   template <typename Item, typename Prio, typename ItemIntMap, 
 
   298   void FibHeap<Item, Prio, ItemIntMap, Compare>::pop() {
 
   299       /*The first case is that there are only one root.*/
 
   300       if ( container[minimum].left_neighbor==minimum ) {
 
   301 	container[minimum].in=false;
 
   302 	if ( container[minimum].degree!=0 ) { 
 
   303 	  makeroot(container[minimum].child);
 
   304 	  minimum=container[minimum].child;
 
   308 	int right=container[minimum].right_neighbor;
 
   310 	container[minimum].in=false;
 
   311 	if ( container[minimum].degree > 0 ) {
 
   312 	  int left=container[minimum].left_neighbor;
 
   313 	  int child=container[minimum].child;
 
   314 	  int last_child=container[child].left_neighbor;
 
   318 	  container[left].right_neighbor=child;
 
   319 	  container[child].left_neighbor=left;
 
   320 	  container[right].left_neighbor=last_child;
 
   321 	  container[last_child].right_neighbor=right;
 
   325       } // the case where there are more roots
 
   330   template <typename Item, typename Prio, typename ItemIntMap, 
 
   332   void FibHeap<Item, Prio, ItemIntMap, Compare>::erase 
 
   336       if ( i >= 0 && container[i].in ) { 	
 
   337 	if ( container[i].parent!=-1 ) {
 
   338 	  int p=container[i].parent;
 
   342 	minimum=i;     //As if its prio would be -infinity
 
   347   template <typename Item, typename Prio, typename ItemIntMap, 
 
   349   void FibHeap<Item, Prio, ItemIntMap, Compare>::decrease 
 
   350   (Item item, PrioType const value) {
 
   352       container[i].prio=value;
 
   353       int p=container[i].parent;
 
   355       if ( p!=-1 && comp(value, container[p].prio) ) {
 
   359       if ( comp(value, container[minimum].prio) ) minimum=i; 
 
   363   template <typename Item, typename Prio, typename ItemIntMap, 
 
   365   void FibHeap<Item, Prio, ItemIntMap, Compare>::balance() {      
 
   367     int maxdeg=int( floor( 2.08*log(double(container.size()))))+1;
 
   369     std::vector<int> A(maxdeg,-1); 
 
   372      *Recall that now minimum does not point to the minimum prio element.
 
   373      *We set minimum to this during balance().
 
   375     int anchor=container[minimum].left_neighbor; 
 
   381 	if ( anchor==active ) end=true;
 
   382 	int d=container[active].degree;
 
   383 	next=container[active].right_neighbor;
 
   386 	  if( comp(container[active].prio, container[A[d]].prio) ) {
 
   399        while ( container[minimum].parent >=0 ) minimum=container[minimum].parent;
 
   403 	 if ( comp(container[s].prio, container[minimum].prio) ) minimum=s;
 
   404 	 s=container[s].right_neighbor;
 
   408   template <typename Item, typename Prio, typename ItemIntMap, 
 
   410   void FibHeap<Item, Prio, ItemIntMap, Compare>::makeroot 
 
   414 	container[s].parent=-1;
 
   415 	s=container[s].right_neighbor;
 
   420   template <typename Item, typename Prio, typename ItemIntMap, 
 
   422   void FibHeap<Item, Prio, ItemIntMap, Compare>::cut 
 
   425      *Replacing a from the children of b.
 
   427     --container[b].degree;
 
   429     if ( container[b].degree !=0 ) {
 
   430       int child=container[b].child;
 
   432 	container[b].child=container[child].right_neighbor;
 
   437     /*Lacing a to the roots.*/
 
   438     int right=container[minimum].right_neighbor;
 
   439     container[minimum].right_neighbor=a;
 
   440     container[a].left_neighbor=minimum;
 
   441     container[a].right_neighbor=right;
 
   442     container[right].left_neighbor=a;
 
   444     container[a].parent=-1;
 
   445     container[a].marked=false;
 
   449   template <typename Item, typename Prio, typename ItemIntMap, 
 
   451   void FibHeap<Item, Prio, ItemIntMap, Compare>::cascade 
 
   454       if ( container[a].parent!=-1 ) {
 
   455 	int p=container[a].parent;
 
   457 	if ( container[a].marked==false ) container[a].marked=true;
 
   466   template <typename Item, typename Prio, typename ItemIntMap, 
 
   468   void FibHeap<Item, Prio, ItemIntMap, Compare>::fuse 
 
   472       /*Lacing b under a.*/
 
   473       container[b].parent=a;
 
   475       if (container[a].degree==0) {
 
   476 	container[b].left_neighbor=b;
 
   477 	container[b].right_neighbor=b;
 
   478 	container[a].child=b;	
 
   480 	int child=container[a].child;
 
   481 	int last_child=container[child].left_neighbor;
 
   482 	container[child].left_neighbor=b;
 
   483 	container[b].right_neighbor=child;
 
   484 	container[last_child].right_neighbor=b;
 
   485 	container[b].left_neighbor=last_child;
 
   488       ++container[a].degree;
 
   490       container[b].marked=false;
 
   495    *It is invoked only if a has siblings.
 
   497   template <typename Item, typename Prio, typename ItemIntMap, 
 
   499   void FibHeap<Item, Prio, ItemIntMap, Compare>::unlace 
 
   501       int leftn=container[a].left_neighbor;
 
   502       int rightn=container[a].right_neighbor;
 
   503       container[leftn].right_neighbor=rightn;
 
   504       container[rightn].left_neighbor=leftn;
 
   511 #endif //LEMON_FIB_HEAP_H