lemon/elevator.h
author Alpar Juttner <alpar@cs.elte.hu>
Fri, 21 Nov 2008 10:41:36 +0000
changeset 382 61fbd77f0f44
parent 381 b04e431907bc
child 383 a8a22a96d495
permissions -rw-r--r--
Don't assume that the default maps are reference maps (in Elevator)
     1 /* -*- mode: C++; indent-tabs-mode: nil; -*-
     2  *
     3  * This file is a part of LEMON, a generic C++ optimization library.
     4  *
     5  * Copyright (C) 2003-2008
     6  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
     7  * (Egervary Research Group on Combinatorial Optimization, EGRES).
     8  *
     9  * Permission to use, modify and distribute this software is granted
    10  * provided that this copyright notice appears in all copies. For
    11  * precise terms see the accompanying LICENSE file.
    12  *
    13  * This software is provided "AS IS" with no warranty of any kind,
    14  * express or implied, and with no claim as to its suitability for any
    15  * purpose.
    16  *
    17  */
    18 
    19 #ifndef LEMON_ELEVATOR_H
    20 #define LEMON_ELEVATOR_H
    21 
    22 ///\ingroup auxdat
    23 ///\file
    24 ///\brief Elevator class
    25 ///
    26 ///Elevator class implements an efficient data structure
    27 ///for labeling items in push-relabel type algorithms.
    28 ///
    29 
    30 #include <test/test_tools.h>
    31 namespace lemon {
    32 
    33   ///Class for handling "labels" in push-relabel type algorithms.
    34 
    35   ///A class for handling "labels" in push-relabel type algorithms.
    36   ///
    37   ///\ingroup auxdat
    38   ///Using this class you can assign "labels" (nonnegative integer numbers)
    39   ///to the edges or nodes of a graph, manipulate and query them through
    40   ///operations typically arising in "push-relabel" type algorithms.
    41   ///
    42   ///Each item is either \em active or not, and you can also choose a
    43   ///highest level active item.
    44   ///
    45   ///\sa LinkedElevator
    46   ///
    47   ///\param Graph the underlying graph type
    48   ///\param Item Type of the items the data is assigned to (Graph::Node,
    49   ///Graph::Edge, Graph::UEdge)
    50   template<class Graph, class Item>
    51   class Elevator
    52   {
    53   public:
    54 
    55     typedef Item Key;
    56     typedef int Value;
    57 
    58   private:
    59 
    60     typedef Item *Vit;
    61     typedef typename ItemSetTraits<Graph,Item>::template Map<Vit>::Type VitMap;
    62     typedef typename ItemSetTraits<Graph,Item>::template Map<int>::Type IntMap;
    63 
    64     const Graph &_g;
    65     int _max_level;
    66     int _item_num;
    67     VitMap _where;
    68     IntMap _level;
    69     std::vector<Item> _items;
    70     std::vector<Vit> _first;
    71     std::vector<Vit> _last_active;
    72 
    73     int _highest_active;
    74 
    75     void copy(Item i, Vit p)
    76     {
    77       _where.set(*p=i,p);
    78     }
    79     void copy(Vit s, Vit p)
    80     {
    81       if(s!=p)
    82         {
    83           Item i=*s;
    84           *p=i;
    85           _where.set(i,p);
    86         }
    87     }
    88     void swap(Vit i, Vit j)
    89     {
    90       Item ti=*i;
    91       Vit ct = _where[ti];
    92       _where.set(ti,_where[*i=*j]);
    93       _where.set(*j,ct);
    94       *j=ti;
    95     }
    96 
    97   public:
    98 
    99     ///Constructor with given maximum level.
   100 
   101     ///Constructor with given maximum level.
   102     ///
   103     ///\param g The underlying graph
   104     ///\param max_level Set the range of the possible labels to
   105     ///[0...\c max_level]
   106     Elevator(const Graph &g,int max_level) :
   107       _g(g),
   108       _max_level(max_level),
   109       _item_num(_max_level),
   110       _where(g),
   111       _level(g,0),
   112       _items(_max_level),
   113       _first(_max_level+2),
   114       _last_active(_max_level+2),
   115       _highest_active(-1) {}
   116     ///Constructor.
   117 
   118     ///Constructor.
   119     ///
   120     ///\param g The underlying graph
   121     ///The range of the possible labels is [0...\c max_level],
   122     ///where \c max_level is equal to the number of labeled items in the graph.
   123     Elevator(const Graph &g) :
   124       _g(g),
   125       _max_level(countItems<Graph, Item>(g)),
   126       _item_num(_max_level),
   127       _where(g),
   128       _level(g,0),
   129       _items(_max_level),
   130       _first(_max_level+2),
   131       _last_active(_max_level+2),
   132       _highest_active(-1)
   133     {
   134     }
   135 
   136     ///Activate item \c i.
   137 
   138     ///Activate item \c i.
   139     ///\pre Item \c i shouldn't be active before.
   140     void activate(Item i)
   141     {
   142       const int l=_level[i];
   143       swap(_where[i],++_last_active[l]);
   144       if(l>_highest_active) _highest_active=l;
   145     }
   146 
   147     ///Deactivate item \c i.
   148 
   149     ///Deactivate item \c i.
   150     ///\pre Item \c i must be active before.
   151     void deactivate(Item i)
   152     {
   153       swap(_where[i],_last_active[_level[i]]--);
   154       while(_highest_active>=0 &&
   155             _last_active[_highest_active]<_first[_highest_active])
   156         _highest_active--;
   157     }
   158 
   159     ///Query whether item \c i is active
   160     bool active(Item i) const { return _where[i]<=_last_active[_level[i]]; }
   161 
   162     ///Return the level of item \c i.
   163     int operator[](Item i) const { return _level[i]; }
   164 
   165     ///Return the number of items on level \c l.
   166     int onLevel(int l) const
   167     {
   168       return _first[l+1]-_first[l];
   169     }
   170     ///Return true if the level is empty.
   171     bool emptyLevel(int l) const
   172     {
   173       return _first[l+1]-_first[l]==0;
   174     }
   175     ///Return the number of items above level \c l.
   176     int aboveLevel(int l) const
   177     {
   178       return _first[_max_level+1]-_first[l+1];
   179     }
   180     ///Return the number of active items on level \c l.
   181     int activesOnLevel(int l) const
   182     {
   183       return _last_active[l]-_first[l]+1;
   184     }
   185     ///Return true if there is not active item on level \c l.
   186     bool activeFree(int l) const
   187     {
   188       return _last_active[l]<_first[l];
   189     }
   190     ///Return the maximum allowed level.
   191     int maxLevel() const
   192     {
   193       return _max_level;
   194     }
   195 
   196     ///\name Highest Active Item
   197     ///Functions for working with the highest level
   198     ///active item.
   199 
   200     ///@{
   201 
   202     ///Return a highest level active item.
   203 
   204     ///Return a highest level active item.
   205     ///
   206     ///\return the highest level active item or INVALID if there is no active
   207     ///item.
   208     Item highestActive() const
   209     {
   210       return _highest_active>=0?*_last_active[_highest_active]:INVALID;
   211     }
   212 
   213     ///Return a highest active level.
   214 
   215     ///Return a highest active level.
   216     ///
   217     ///\return the level of the highest active item or -1 if there is no active
   218     ///item.
   219     int highestActiveLevel() const
   220     {
   221       return _highest_active;
   222     }
   223 
   224     ///Lift the highest active item by one.
   225 
   226     ///Lift the item returned by highestActive() by one.
   227     ///
   228     void liftHighestActive()
   229     {
   230       Item it = *_last_active[_highest_active];
   231       _level.set(it,_level[it]+1);
   232       swap(_last_active[_highest_active]--,_last_active[_highest_active+1]);
   233       --_first[++_highest_active];
   234     }
   235 
   236     ///Lift the highest active item.
   237 
   238     ///Lift the item returned by highestActive() to level \c new_level.
   239     ///
   240     ///\warning \c new_level must be strictly higher
   241     ///than the current level.
   242     ///
   243     void liftHighestActive(int new_level)
   244     {
   245       const Item li = *_last_active[_highest_active];
   246 
   247       copy(--_first[_highest_active+1],_last_active[_highest_active]--);
   248       for(int l=_highest_active+1;l<new_level;l++)
   249         {
   250           copy(--_first[l+1],_first[l]);
   251           --_last_active[l];
   252         }
   253       copy(li,_first[new_level]);
   254       _level.set(li,new_level);
   255       _highest_active=new_level;
   256     }
   257 
   258     ///Lift the highest active item.
   259 
   260     ///Lift the item returned by highestActive() to the top level and
   261     ///deactivates it.
   262     ///
   263     ///\warning \c new_level must be strictly higher
   264     ///than the current level.
   265     ///
   266     void liftHighestActiveToTop()
   267     {
   268       const Item li = *_last_active[_highest_active];
   269 
   270       copy(--_first[_highest_active+1],_last_active[_highest_active]--);
   271       for(int l=_highest_active+1;l<_max_level;l++)
   272         {
   273           copy(--_first[l+1],_first[l]);
   274           --_last_active[l];
   275         }
   276       copy(li,_first[_max_level]);
   277       --_last_active[_max_level];
   278       _level.set(li,_max_level);
   279 
   280       while(_highest_active>=0 &&
   281             _last_active[_highest_active]<_first[_highest_active])
   282         _highest_active--;
   283     }
   284 
   285     ///@}
   286 
   287     ///\name Active Item on Certain Level
   288     ///Functions for working with the active items.
   289 
   290     ///@{
   291 
   292     ///Returns an active item on level \c l.
   293 
   294     ///Returns an active item on level \c l.
   295     ///
   296     ///Returns an active item on level \c l or \ref INVALID if there is no such
   297     ///an item. (\c l must be from the range [0...\c max_level].
   298     Item activeOn(int l) const
   299     {
   300       return _last_active[l]>=_first[l]?*_last_active[l]:INVALID;
   301     }
   302 
   303     ///Lifts the active item returned by \c activeOn() member function.
   304 
   305     ///Lifts the active item returned by \c activeOn() member function
   306     ///by one.
   307     Item liftActiveOn(int level)
   308     {
   309       Item it =*_last_active[level];
   310       _level.set(it,_level[it]+1);
   311       swap(_last_active[level]--, --_first[level+1]);
   312       if (level+1>_highest_active) ++_highest_active;
   313     }
   314 
   315     ///Lifts the active item returned by \c activeOn() member function.
   316 
   317     ///Lifts the active item returned by \c activeOn() member function
   318     ///to the given level.
   319     void liftActiveOn(int level, int new_level)
   320     {
   321       const Item ai = *_last_active[level];
   322 
   323       copy(--_first[level+1], _last_active[level]--);
   324       for(int l=level+1;l<new_level;l++)
   325         {
   326           copy(_last_active[l],_first[l]);
   327           copy(--_first[l+1], _last_active[l]--);
   328         }
   329       copy(ai,_first[new_level]);
   330       _level.set(ai,new_level);
   331       if (new_level>_highest_active) _highest_active=new_level;
   332     }
   333 
   334     ///Lifts the active item returned by \c activeOn() member function.
   335 
   336     ///Lifts the active item returned by \c activeOn() member function
   337     ///to the top level.
   338     void liftActiveToTop(int level)
   339     {
   340       const Item ai = *_last_active[level];
   341 
   342       copy(--_first[level+1],_last_active[level]--);
   343       for(int l=level+1;l<_max_level;l++)
   344         {
   345           copy(_last_active[l],_first[l]);
   346           copy(--_first[l+1], _last_active[l]--);
   347         }
   348       copy(ai,_first[_max_level]);
   349       --_last_active[_max_level];
   350       _level.set(ai,_max_level);
   351 
   352       if (_highest_active==level) {
   353         while(_highest_active>=0 &&
   354               _last_active[_highest_active]<_first[_highest_active])
   355           _highest_active--;
   356       }
   357     }
   358 
   359     ///@}
   360 
   361     ///Lift an active item to a higher level.
   362 
   363     ///Lift an active item to a higher level.
   364     ///\param i The item to be lifted. It must be active.
   365     ///\param new_level The new level of \c i. It must be strictly higher
   366     ///than the current level.
   367     ///
   368     void lift(Item i, int new_level)
   369     {
   370       const int lo = _level[i];
   371       const Vit w = _where[i];
   372 
   373       copy(_last_active[lo],w);
   374       copy(--_first[lo+1],_last_active[lo]--);
   375       for(int l=lo+1;l<new_level;l++)
   376         {
   377           copy(_last_active[l],_first[l]);
   378           copy(--_first[l+1],_last_active[l]--);
   379         }
   380       copy(i,_first[new_level]);
   381       _level.set(i,new_level);
   382       if(new_level>_highest_active) _highest_active=new_level;
   383     }
   384 
   385     ///Move an inactive item to the top but one level (in a dirty way).
   386 
   387     ///This function moves an inactive item to the top but one level.
   388     ///It makes the underlying datastructure corrupt, so use is only if
   389     ///you really know what it is for.
   390     ///\pre The item is on the top level.
   391     void dirtyTopButOne(Item i) {
   392       _level.set(i,_max_level - 1);
   393     }
   394 
   395     ///Lift all items on and above a level to the top (and deactivate them).
   396 
   397     ///This function lifts all items on and above level \c l to \c
   398     ///maxLevel(), and also deactivates them.
   399     void liftToTop(int l)
   400     {
   401       const Vit f=_first[l];
   402       const Vit tl=_first[_max_level];
   403       for(Vit i=f;i!=tl;++i)
   404         _level.set(*i,_max_level);
   405       for(int i=l;i<=_max_level;i++)
   406         {
   407           _first[i]=f;
   408           _last_active[i]=f-1;
   409         }
   410       for(_highest_active=l-1;
   411           _highest_active>=0 &&
   412             _last_active[_highest_active]<_first[_highest_active];
   413           _highest_active--) ;
   414     }
   415 
   416   private:
   417     int _init_lev;
   418     Vit _init_num;
   419 
   420   public:
   421 
   422     ///\name Initialization
   423     ///Using this function you can initialize the levels of the item.
   424     ///\n
   425     ///This initializatios is started with calling \c initStart().
   426     ///Then the
   427     ///items should be listed levels by levels statring with the lowest one
   428     ///(with level 0). This is done by using \c initAddItem()
   429     ///and \c initNewLevel(). Finally \c initFinish() must be called.
   430     ///The items not listed will be put on the highest level.
   431     ///@{
   432 
   433     ///Start the initialization process.
   434 
   435     void initStart()
   436     {
   437       _init_lev=0;
   438       _init_num=&_items[0];
   439       _first[0]=&_items[0];
   440       _last_active[0]=&_items[0]-1;
   441       Vit n=&_items[0];
   442       for(typename ItemSetTraits<Graph,Item>::ItemIt i(_g);i!=INVALID;++i)
   443         {
   444           *n=i;
   445           _where.set(i,n);
   446           _level.set(i,_max_level);
   447           ++n;
   448         }
   449     }
   450 
   451     ///Add an item to the current level.
   452 
   453     void initAddItem(Item i)
   454     {
   455       swap(_where[i],_init_num);
   456       _level.set(i,_init_lev);
   457       ++_init_num;
   458     }
   459 
   460     ///Start a new level.
   461 
   462     ///Start a new level.
   463     ///It shouldn't be used before the items on level 0 are listed.
   464     void initNewLevel()
   465     {
   466       _init_lev++;
   467       _first[_init_lev]=_init_num;
   468       _last_active[_init_lev]=_init_num-1;
   469     }
   470 
   471     ///Finalize the initialization process.
   472 
   473     void initFinish()
   474     {
   475       for(_init_lev++;_init_lev<=_max_level;_init_lev++)
   476         {
   477           _first[_init_lev]=_init_num;
   478           _last_active[_init_lev]=_init_num-1;
   479         }
   480       _first[_max_level+1]=&_items[0]+_item_num;
   481       _last_active[_max_level+1]=&_items[0]+_item_num-1;
   482       _highest_active = -1;
   483     }
   484 
   485     ///@}
   486 
   487   };
   488 
   489   ///Class for handling "labels" in push-relabel type algorithms.
   490 
   491   ///A class for handling "labels" in push-relabel type algorithms.
   492   ///
   493   ///\ingroup auxdat
   494   ///Using this class you can assign "labels" (nonnegative integer numbers)
   495   ///to the edges or nodes of a graph, manipulate and query them through
   496   ///operations typically arising in "push-relabel" type algorithms.
   497   ///
   498   ///Each item is either \em active or not, and you can also choose a
   499   ///highest level active item.
   500   ///
   501   ///\sa Elevator
   502   ///
   503   ///\param Graph the underlying graph type
   504   ///\param Item Type of the items the data is assigned to (Graph::Node,
   505   ///Graph::Edge, Graph::UEdge)
   506   template <class Graph, class Item>
   507   class LinkedElevator {
   508   public:
   509 
   510     typedef Item Key;
   511     typedef int Value;
   512 
   513   private:
   514 
   515     typedef typename ItemSetTraits<Graph,Item>::
   516     template Map<Item>::Type ItemMap;
   517     typedef typename ItemSetTraits<Graph,Item>::
   518     template Map<int>::Type IntMap;
   519     typedef typename ItemSetTraits<Graph,Item>::
   520     template Map<bool>::Type BoolMap;
   521 
   522     const Graph &_graph;
   523     int _max_level;
   524     int _item_num;
   525     std::vector<Item> _first, _last;
   526     ItemMap _prev, _next;
   527     int _highest_active;
   528     IntMap _level;
   529     BoolMap _active;
   530 
   531   public:
   532     ///Constructor with given maximum level.
   533 
   534     ///Constructor with given maximum level.
   535     ///
   536     ///\param g The underlying graph
   537     ///\param max_level Set the range of the possible labels to
   538     ///[0...\c max_level]
   539     LinkedElevator(const Graph& graph, int max_level)
   540       : _graph(graph), _max_level(max_level), _item_num(_max_level),
   541         _first(_max_level + 1), _last(_max_level + 1),
   542         _prev(graph), _next(graph),
   543         _highest_active(-1), _level(graph), _active(graph) {}
   544 
   545     ///Constructor.
   546 
   547     ///Constructor.
   548     ///
   549     ///\param g The underlying graph
   550     ///The range of the possible labels is [0...\c max_level],
   551     ///where \c max_level is equal to the number of labeled items in the graph.
   552     LinkedElevator(const Graph& graph)
   553       : _graph(graph), _max_level(countItems<Graph, Item>(graph)),
   554         _item_num(_max_level),
   555         _first(_max_level + 1), _last(_max_level + 1),
   556         _prev(graph, INVALID), _next(graph, INVALID),
   557         _highest_active(-1), _level(graph), _active(graph) {}
   558 
   559 
   560     ///Activate item \c i.
   561 
   562     ///Activate item \c i.
   563     ///\pre Item \c i shouldn't be active before.
   564     void activate(Item i) {
   565       _active.set(i, true);
   566 
   567       int level = _level[i];
   568       if (level > _highest_active) {
   569         _highest_active = level;
   570       }
   571 
   572       if (_prev[i] == INVALID || _active[_prev[i]]) return;
   573       //unlace
   574       _next.set(_prev[i], _next[i]);
   575       if (_next[i] != INVALID) {
   576         _prev.set(_next[i], _prev[i]);
   577       } else {
   578         _last[level] = _prev[i];
   579       }
   580       //lace
   581       _next.set(i, _first[level]);
   582       _prev.set(_first[level], i);
   583       _prev.set(i, INVALID);
   584       _first[level] = i;
   585 
   586     }
   587 
   588     ///Deactivate item \c i.
   589 
   590     ///Deactivate item \c i.
   591     ///\pre Item \c i must be active before.
   592     void deactivate(Item i) {
   593       _active.set(i, false);
   594       int level = _level[i];
   595 
   596       if (_next[i] == INVALID || !_active[_next[i]])
   597         goto find_highest_level;
   598 
   599       //unlace
   600       _prev.set(_next[i], _prev[i]);
   601       if (_prev[i] != INVALID) {
   602         _next.set(_prev[i], _next[i]);
   603       } else {
   604         _first[_level[i]] = _next[i];
   605       }
   606       //lace
   607       _prev.set(i, _last[level]);
   608       _next.set(_last[level], i);
   609       _next.set(i, INVALID);
   610       _last[level] = i;
   611 
   612     find_highest_level:
   613       if (level == _highest_active) {
   614         while (_highest_active >= 0 && activeFree(_highest_active))
   615           --_highest_active;
   616       }
   617     }
   618 
   619     ///Query whether item \c i is active
   620     bool active(Item i) const { return _active[i]; }
   621 
   622     ///Return the level of item \c i.
   623     int operator[](Item i) const { return _level[i]; }
   624 
   625     ///Return the number of items on level \c l.
   626     int onLevel(int l) const {
   627       int num = 0;
   628       Item n = _first[l];
   629       while (n != INVALID) {
   630         ++num;
   631         n = _next[n];
   632       }
   633       return num;
   634     }
   635 
   636     ///Return true if the level is empty.
   637     bool emptyLevel(int l) const {
   638       return _first[l] == INVALID;
   639     }
   640 
   641     ///Return the number of items above level \c l.
   642     int aboveLevel(int l) const {
   643       int num = 0;
   644       for (int level = l + 1; level < _max_level; ++level)
   645         num += onLevel(level);
   646       return num;
   647     }
   648 
   649     ///Return the number of active items on level \c l.
   650     int activesOnLevel(int l) const {
   651       int num = 0;
   652       Item n = _first[l];
   653       while (n != INVALID && _active[n]) {
   654         ++num;
   655         n = _next[n];
   656       }
   657       return num;
   658     }
   659 
   660     ///Return true if there is not active item on level \c l.
   661     bool activeFree(int l) const {
   662       return _first[l] == INVALID || !_active[_first[l]];
   663     }
   664 
   665     ///Return the maximum allowed level.
   666     int maxLevel() const {
   667       return _max_level;
   668     }
   669 
   670     ///\name Highest Active Item
   671     ///Functions for working with the highest level
   672     ///active item.
   673 
   674     ///@{
   675 
   676     ///Return a highest level active item.
   677 
   678     ///Return a highest level active item.
   679     ///
   680     ///\return the highest level active item or INVALID if there is no
   681     ///active item.
   682     Item highestActive() const {
   683       return _highest_active >= 0 ? _first[_highest_active] : INVALID;
   684     }
   685 
   686     ///Return a highest active level.
   687 
   688     ///Return a highest active level.
   689     ///
   690     ///\return the level of the highest active item or -1 if there is
   691     ///no active item.
   692     int highestActiveLevel() const {
   693       return _highest_active;
   694     }
   695 
   696     ///Lift the highest active item by one.
   697 
   698     ///Lift the item returned by highestActive() by one.
   699     ///
   700     void liftHighestActive() {
   701       Item i = _first[_highest_active];
   702       if (_next[i] != INVALID) {
   703         _prev.set(_next[i], INVALID);
   704         _first[_highest_active] = _next[i];
   705       } else {
   706         _first[_highest_active] = INVALID;
   707         _last[_highest_active] = INVALID;
   708       }
   709       _level.set(i, ++_highest_active);
   710       if (_first[_highest_active] == INVALID) {
   711         _first[_highest_active] = i;
   712         _last[_highest_active] = i;
   713         _prev.set(i, INVALID);
   714         _next.set(i, INVALID);
   715       } else {
   716         _prev.set(_first[_highest_active], i);
   717         _next.set(i, _first[_highest_active]);
   718         _first[_highest_active] = i;
   719       }
   720     }
   721 
   722     ///Lift the highest active item.
   723 
   724     ///Lift the item returned by highestActive() to level \c new_level.
   725     ///
   726     ///\warning \c new_level must be strictly higher
   727     ///than the current level.
   728     ///
   729     void liftHighestActive(int new_level) {
   730       Item i = _first[_highest_active];
   731       if (_next[i] != INVALID) {
   732         _prev.set(_next[i], INVALID);
   733         _first[_highest_active] = _next[i];
   734       } else {
   735         _first[_highest_active] = INVALID;
   736         _last[_highest_active] = INVALID;
   737       }
   738       _level.set(i, _highest_active = new_level);
   739       if (_first[_highest_active] == INVALID) {
   740         _first[_highest_active] = _last[_highest_active] = i;
   741         _prev.set(i, INVALID);
   742         _next.set(i, INVALID);
   743       } else {
   744         _prev.set(_first[_highest_active], i);
   745         _next.set(i, _first[_highest_active]);
   746         _first[_highest_active] = i;
   747       }
   748     }
   749 
   750     ///Lift the highest active to top.
   751 
   752     ///Lift the item returned by highestActive() to the top level and
   753     ///deactivates the item.
   754     ///
   755     void liftHighestActiveToTop() {
   756       Item i = _first[_highest_active];
   757       _level.set(i, _max_level);
   758       if (_next[i] != INVALID) {
   759         _prev.set(_next[i], INVALID);
   760         _first[_highest_active] = _next[i];
   761       } else {
   762         _first[_highest_active] = INVALID;
   763         _last[_highest_active] = INVALID;
   764       }
   765       while (_highest_active >= 0 && activeFree(_highest_active))
   766         --_highest_active;
   767     }
   768 
   769     ///@}
   770 
   771     ///\name Active Item on Certain Level
   772     ///Functions for working with the active items.
   773 
   774     ///@{
   775 
   776     ///Returns an active item on level \c l.
   777 
   778     ///Returns an active item on level \c l.
   779     ///
   780     ///Returns an active item on level \c l or \ref INVALID if there is no such
   781     ///an item. (\c l must be from the range [0...\c max_level].
   782     Item activeOn(int l) const
   783     {
   784       return _active[_first[l]] ? _first[l] : INVALID;
   785     }
   786 
   787     ///Lifts the active item returned by \c activeOn() member function.
   788 
   789     ///Lifts the active item returned by \c activeOn() member function
   790     ///by one.
   791     Item liftActiveOn(int l)
   792     {
   793       Item i = _first[l];
   794       if (_next[i] != INVALID) {
   795         _prev.set(_next[i], INVALID);
   796         _first[l] = _next[i];
   797       } else {
   798         _first[l] = INVALID;
   799         _last[l] = INVALID;
   800       }
   801       _level.set(i, ++l);
   802       if (_first[l] == INVALID) {
   803         _first[l] = _last[l] = i;
   804         _prev.set(i, INVALID);
   805         _next.set(i, INVALID);
   806       } else {
   807         _prev.set(_first[l], i);
   808         _next.set(i, _first[l]);
   809         _first[l] = i;
   810       }
   811       if (_highest_active < l) {
   812         _highest_active = l;
   813       }
   814     }
   815 
   816     /// \brief Lifts the active item returned by \c activeOn() member function.
   817     ///
   818     /// Lifts the active item returned by \c activeOn() member function
   819     /// to the given level.
   820     void liftActiveOn(int l, int new_level)
   821     {
   822       Item i = _first[l];
   823       if (_next[i] != INVALID) {
   824         _prev.set(_next[i], INVALID);
   825         _first[l] = _next[i];
   826       } else {
   827         _first[l] = INVALID;
   828         _last[l] = INVALID;
   829       }
   830       _level.set(i, l = new_level);
   831       if (_first[l] == INVALID) {
   832         _first[l] = _last[l] = i;
   833         _prev.set(i, INVALID);
   834         _next.set(i, INVALID);
   835       } else {
   836         _prev.set(_first[l], i);
   837         _next.set(i, _first[l]);
   838         _first[l] = i;
   839       }
   840       if (_highest_active < l) {
   841         _highest_active = l;
   842       }
   843     }
   844 
   845     ///Lifts the active item returned by \c activeOn() member function.
   846 
   847     ///Lifts the active item returned by \c activeOn() member function
   848     ///to the top level.
   849     void liftActiveToTop(int l)
   850     {
   851       Item i = _first[l];
   852       if (_next[i] != INVALID) {
   853         _prev.set(_next[i], INVALID);
   854         _first[l] = _next[i];
   855       } else {
   856         _first[l] = INVALID;
   857         _last[l] = INVALID;
   858       }
   859       _level.set(i, _max_level);
   860       if (l == _highest_active) {
   861         while (_highest_active >= 0 && activeFree(_highest_active))
   862           --_highest_active;
   863       }
   864     }
   865 
   866     ///@}
   867 
   868     /// \brief Lift an active item to a higher level.
   869     ///
   870     /// Lift an active item to a higher level.
   871     /// \param i The item to be lifted. It must be active.
   872     /// \param new_level The new level of \c i. It must be strictly higher
   873     /// than the current level.
   874     ///
   875     void lift(Item i, int new_level) {
   876       if (_next[i] != INVALID) {
   877         _prev.set(_next[i], _prev[i]);
   878       } else {
   879         _last[new_level] = _prev[i];
   880       }
   881       if (_prev[i] != INVALID) {
   882         _next.set(_prev[i], _next[i]);
   883       } else {
   884         _first[new_level] = _next[i];
   885       }
   886       _level.set(i, new_level);
   887       if (_first[new_level] == INVALID) {
   888         _first[new_level] = _last[new_level] = i;
   889         _prev.set(i, INVALID);
   890         _next.set(i, INVALID);
   891       } else {
   892         _prev.set(_first[new_level], i);
   893         _next.set(i, _first[new_level]);
   894         _first[new_level] = i;
   895       }
   896       if (_highest_active < new_level) {
   897         _highest_active = new_level;
   898       }
   899     }
   900 
   901     ///Move an inactive item to the top but one level (in a dirty way).
   902 
   903     ///This function moves an inactive item to the top but one level.
   904     ///It makes the underlying datastructure corrupt, so use is only if
   905     ///you really know what it is for.
   906     ///\pre The item is on the top level.
   907     void dirtyTopButOne(Item i) {
   908       _level.set(i, _max_level - 1);
   909     }
   910 
   911     ///Lift all items on and above a level to the top (and deactivate them).
   912 
   913     ///This function lifts all items on and above level \c l to \c
   914     ///maxLevel(), and also deactivates them.
   915     void liftToTop(int l)  {
   916       for (int i = l + 1; _first[i] != INVALID; ++i) {
   917         Item n = _first[i];
   918         while (n != INVALID) {
   919           _level.set(n, _max_level);
   920           n = _next[n];
   921         }
   922         _first[i] = INVALID;
   923         _last[i] = INVALID;
   924       }
   925       if (_highest_active > l - 1) {
   926         _highest_active = l - 1;
   927         while (_highest_active >= 0 && activeFree(_highest_active))
   928           --_highest_active;
   929       }
   930     }
   931 
   932   private:
   933 
   934     int _init_level;
   935 
   936   public:
   937 
   938     ///\name Initialization
   939     ///Using this function you can initialize the levels of the item.
   940     ///\n
   941     ///This initializatios is started with calling \c initStart().
   942     ///Then the
   943     ///items should be listed levels by levels statring with the lowest one
   944     ///(with level 0). This is done by using \c initAddItem()
   945     ///and \c initNewLevel(). Finally \c initFinish() must be called.
   946     ///The items not listed will be put on the highest level.
   947     ///@{
   948 
   949     ///Start the initialization process.
   950 
   951     void initStart() {
   952 
   953       for (int i = 0; i <= _max_level; ++i) {
   954         _first[i] = _last[i] = INVALID;
   955       }
   956       _init_level = 0;
   957       for(typename ItemSetTraits<Graph,Item>::ItemIt i(_graph);
   958           i != INVALID; ++i) {
   959         _level.set(i, _max_level);
   960         _active.set(i, false);
   961       }
   962     }
   963 
   964     ///Add an item to the current level.
   965 
   966     void initAddItem(Item i) {
   967       _level.set(i, _init_level);
   968       if (_last[_init_level] == INVALID) {
   969         _first[_init_level] = i;
   970         _last[_init_level] = i;
   971         _prev.set(i, INVALID);
   972         _next.set(i, INVALID);
   973       } else {
   974         _prev.set(i, _last[_init_level]);
   975         _next.set(i, INVALID);
   976         _next.set(_last[_init_level], i);
   977         _last[_init_level] = i;
   978       }
   979     }
   980 
   981     ///Start a new level.
   982 
   983     ///Start a new level.
   984     ///It shouldn't be used before the items on level 0 are listed.
   985     void initNewLevel() {
   986       ++_init_level;
   987     }
   988 
   989     ///Finalize the initialization process.
   990 
   991     void initFinish() {
   992       _highest_active = -1;
   993     }
   994 
   995     ///@}
   996 
   997   };
   998 
   999 
  1000 } //END OF NAMESPACE LEMON
  1001 
  1002 #endif
  1003