lemon/elevator.h
author Alpar Juttner <alpar@cs.elte.hu>
Mon, 17 Nov 2008 15:41:15 +0000
changeset 396 b04e431907bc
parent 395 d916b8995e22
child 397 61fbd77f0f44
permissions -rw-r--r--
Avoid STL panic at Elevator when compiled with -D_GLIBCXX_DEBUG
     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[*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[i]=p;
    86         }
    87     }
    88     void swap(Vit i, Vit j)
    89     {
    90       Item ti=*i;
    91       Vit ct = _where[ti];
    92       _where[ti]=_where[*i=*j];
    93       _where[*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       ++_level[*_last_active[_highest_active]];
   231       swap(_last_active[_highest_active]--,_last_active[_highest_active+1]);
   232       --_first[++_highest_active];
   233     }
   234 
   235     ///Lift the highest active item.
   236 
   237     ///Lift the item returned by highestActive() to level \c new_level.
   238     ///
   239     ///\warning \c new_level must be strictly higher
   240     ///than the current level.
   241     ///
   242     void liftHighestActive(int new_level)
   243     {
   244       const Item li = *_last_active[_highest_active];
   245 
   246       copy(--_first[_highest_active+1],_last_active[_highest_active]--);
   247       for(int l=_highest_active+1;l<new_level;l++)
   248         {
   249           copy(--_first[l+1],_first[l]);
   250           --_last_active[l];
   251         }
   252       copy(li,_first[new_level]);
   253       _level[li]=new_level;
   254       _highest_active=new_level;
   255     }
   256 
   257     ///Lift the highest active item.
   258 
   259     ///Lift the item returned by highestActive() to the top level and
   260     ///deactivates it.
   261     ///
   262     ///\warning \c new_level must be strictly higher
   263     ///than the current level.
   264     ///
   265     void liftHighestActiveToTop()
   266     {
   267       const Item li = *_last_active[_highest_active];
   268 
   269       copy(--_first[_highest_active+1],_last_active[_highest_active]--);
   270       for(int l=_highest_active+1;l<_max_level;l++)
   271         {
   272           copy(--_first[l+1],_first[l]);
   273           --_last_active[l];
   274         }
   275       copy(li,_first[_max_level]);
   276       --_last_active[_max_level];
   277       _level[li]=_max_level;
   278 
   279       while(_highest_active>=0 &&
   280             _last_active[_highest_active]<_first[_highest_active])
   281         _highest_active--;
   282     }
   283 
   284     ///@}
   285 
   286     ///\name Active Item on Certain Level
   287     ///Functions for working with the active items.
   288 
   289     ///@{
   290 
   291     ///Returns an active item on level \c l.
   292 
   293     ///Returns an active item on level \c l.
   294     ///
   295     ///Returns an active item on level \c l or \ref INVALID if there is no such
   296     ///an item. (\c l must be from the range [0...\c max_level].
   297     Item activeOn(int l) const
   298     {
   299       return _last_active[l]>=_first[l]?*_last_active[l]:INVALID;
   300     }
   301 
   302     ///Lifts the active item returned by \c activeOn() member function.
   303 
   304     ///Lifts the active item returned by \c activeOn() member function
   305     ///by one.
   306     Item liftActiveOn(int level)
   307     {
   308       ++_level[*_last_active[level]];
   309       swap(_last_active[level]--, --_first[level+1]);
   310       if (level+1>_highest_active) ++_highest_active;
   311     }
   312 
   313     ///Lifts the active item returned by \c activeOn() member function.
   314 
   315     ///Lifts the active item returned by \c activeOn() member function
   316     ///to the given level.
   317     void liftActiveOn(int level, int new_level)
   318     {
   319       const Item ai = *_last_active[level];
   320 
   321       copy(--_first[level+1], _last_active[level]--);
   322       for(int l=level+1;l<new_level;l++)
   323         {
   324           copy(_last_active[l],_first[l]);
   325           copy(--_first[l+1], _last_active[l]--);
   326         }
   327       copy(ai,_first[new_level]);
   328       _level[ai]=new_level;
   329       if (new_level>_highest_active) _highest_active=new_level;
   330     }
   331 
   332     ///Lifts the active item returned by \c activeOn() member function.
   333 
   334     ///Lifts the active item returned by \c activeOn() member function
   335     ///to the top level.
   336     void liftActiveToTop(int level)
   337     {
   338       const Item ai = *_last_active[level];
   339 
   340       copy(--_first[level+1],_last_active[level]--);
   341       for(int l=level+1;l<_max_level;l++)
   342         {
   343           copy(_last_active[l],_first[l]);
   344           copy(--_first[l+1], _last_active[l]--);
   345         }
   346       copy(ai,_first[_max_level]);
   347       --_last_active[_max_level];
   348       _level[ai]=_max_level;
   349 
   350       if (_highest_active==level) {
   351         while(_highest_active>=0 &&
   352               _last_active[_highest_active]<_first[_highest_active])
   353           _highest_active--;
   354       }
   355     }
   356 
   357     ///@}
   358 
   359     ///Lift an active item to a higher level.
   360 
   361     ///Lift an active item to a higher level.
   362     ///\param i The item to be lifted. It must be active.
   363     ///\param new_level The new level of \c i. It must be strictly higher
   364     ///than the current level.
   365     ///
   366     void lift(Item i, int new_level)
   367     {
   368       const int lo = _level[i];
   369       const Vit w = _where[i];
   370 
   371       copy(_last_active[lo],w);
   372       copy(--_first[lo+1],_last_active[lo]--);
   373       for(int l=lo+1;l<new_level;l++)
   374         {
   375           copy(_last_active[l],_first[l]);
   376           copy(--_first[l+1],_last_active[l]--);
   377         }
   378       copy(i,_first[new_level]);
   379       _level[i]=new_level;
   380       if(new_level>_highest_active) _highest_active=new_level;
   381     }
   382 
   383     ///Move an inactive item to the top but one level (in a dirty way).
   384 
   385     ///This function moves an inactive item to the top but one level.
   386     ///It makes the underlying datastructure corrupt, so use is only if
   387     ///you really know what it is for.
   388     ///\pre The item is on the top level.
   389     void dirtyTopButOne(Item i) {
   390       _level[i] = _max_level - 1;
   391     }
   392 
   393     ///Lift all items on and above a level to the top (and deactivate them).
   394 
   395     ///This function lifts all items on and above level \c l to \c
   396     ///maxLevel(), and also deactivates them.
   397     void liftToTop(int l)
   398     {
   399       const Vit f=_first[l];
   400       const Vit tl=_first[_max_level];
   401       for(Vit i=f;i!=tl;++i)
   402         _level[*i]=_max_level;
   403       for(int i=l;i<=_max_level;i++)
   404         {
   405           _first[i]=f;
   406           _last_active[i]=f-1;
   407         }
   408       for(_highest_active=l-1;
   409           _highest_active>=0 &&
   410             _last_active[_highest_active]<_first[_highest_active];
   411           _highest_active--) ;
   412     }
   413 
   414   private:
   415     int _init_lev;
   416     Vit _init_num;
   417 
   418   public:
   419 
   420     ///\name Initialization
   421     ///Using this function you can initialize the levels of the item.
   422     ///\n
   423     ///This initializatios is started with calling \c initStart().
   424     ///Then the
   425     ///items should be listed levels by levels statring with the lowest one
   426     ///(with level 0). This is done by using \c initAddItem()
   427     ///and \c initNewLevel(). Finally \c initFinish() must be called.
   428     ///The items not listed will be put on the highest level.
   429     ///@{
   430 
   431     ///Start the initialization process.
   432 
   433     void initStart()
   434     {
   435       _init_lev=0;
   436       _init_num=&_items[0];
   437       _first[0]=&_items[0];
   438       _last_active[0]=&_items[0]-1;
   439       Vit n=&_items[0];
   440       for(typename ItemSetTraits<Graph,Item>::ItemIt i(_g);i!=INVALID;++i)
   441         {
   442           *n=i;
   443           _where[i]=n;
   444           _level[i]=_max_level;
   445           ++n;
   446         }
   447     }
   448 
   449     ///Add an item to the current level.
   450 
   451     void initAddItem(Item i)
   452     {
   453      swap(_where[i],_init_num);
   454       _level[i]=_init_lev;
   455       ++_init_num;
   456     }
   457 
   458     ///Start a new level.
   459 
   460     ///Start a new level.
   461     ///It shouldn't be used before the items on level 0 are listed.
   462     void initNewLevel()
   463     {
   464       _init_lev++;
   465       _first[_init_lev]=_init_num;
   466       _last_active[_init_lev]=_init_num-1;
   467     }
   468 
   469     ///Finalize the initialization process.
   470 
   471     void initFinish()
   472     {
   473       for(_init_lev++;_init_lev<=_max_level;_init_lev++)
   474         {
   475           _first[_init_lev]=_init_num;
   476           _last_active[_init_lev]=_init_num-1;
   477         }
   478       _first[_max_level+1]=&_items[0]+_item_num;
   479       _last_active[_max_level+1]=&_items[0]+_item_num-1;
   480       _highest_active = -1;
   481     }
   482 
   483     ///@}
   484 
   485   };
   486 
   487   ///Class for handling "labels" in push-relabel type algorithms.
   488 
   489   ///A class for handling "labels" in push-relabel type algorithms.
   490   ///
   491   ///\ingroup auxdat
   492   ///Using this class you can assign "labels" (nonnegative integer numbers)
   493   ///to the edges or nodes of a graph, manipulate and query them through
   494   ///operations typically arising in "push-relabel" type algorithms.
   495   ///
   496   ///Each item is either \em active or not, and you can also choose a
   497   ///highest level active item.
   498   ///
   499   ///\sa Elevator
   500   ///
   501   ///\param Graph the underlying graph type
   502   ///\param Item Type of the items the data is assigned to (Graph::Node,
   503   ///Graph::Edge, Graph::UEdge)
   504   template <class Graph, class Item>
   505   class LinkedElevator {
   506   public:
   507 
   508     typedef Item Key;
   509     typedef int Value;
   510 
   511   private:
   512 
   513     typedef typename ItemSetTraits<Graph,Item>::
   514     template Map<Item>::Type ItemMap;
   515     typedef typename ItemSetTraits<Graph,Item>::
   516     template Map<int>::Type IntMap;
   517     typedef typename ItemSetTraits<Graph,Item>::
   518     template Map<bool>::Type BoolMap;
   519 
   520     const Graph &_graph;
   521     int _max_level;
   522     int _item_num;
   523     std::vector<Item> _first, _last;
   524     ItemMap _prev, _next;
   525     int _highest_active;
   526     IntMap _level;
   527     BoolMap _active;
   528 
   529   public:
   530     ///Constructor with given maximum level.
   531 
   532     ///Constructor with given maximum level.
   533     ///
   534     ///\param g The underlying graph
   535     ///\param max_level Set the range of the possible labels to
   536     ///[0...\c max_level]
   537     LinkedElevator(const Graph& graph, int max_level)
   538       : _graph(graph), _max_level(max_level), _item_num(_max_level),
   539         _first(_max_level + 1), _last(_max_level + 1),
   540         _prev(graph), _next(graph),
   541         _highest_active(-1), _level(graph), _active(graph) {}
   542 
   543     ///Constructor.
   544 
   545     ///Constructor.
   546     ///
   547     ///\param g The underlying graph
   548     ///The range of the possible labels is [0...\c max_level],
   549     ///where \c max_level is equal to the number of labeled items in the graph.
   550     LinkedElevator(const Graph& graph)
   551       : _graph(graph), _max_level(countItems<Graph, Item>(graph)),
   552         _item_num(_max_level),
   553         _first(_max_level + 1), _last(_max_level + 1),
   554         _prev(graph, INVALID), _next(graph, INVALID),
   555         _highest_active(-1), _level(graph), _active(graph) {}
   556 
   557 
   558     ///Activate item \c i.
   559 
   560     ///Activate item \c i.
   561     ///\pre Item \c i shouldn't be active before.
   562     void activate(Item i) {
   563       _active.set(i, true);
   564 
   565       int level = _level[i];
   566       if (level > _highest_active) {
   567         _highest_active = level;
   568       }
   569 
   570       if (_prev[i] == INVALID || _active[_prev[i]]) return;
   571       //unlace
   572       _next.set(_prev[i], _next[i]);
   573       if (_next[i] != INVALID) {
   574         _prev.set(_next[i], _prev[i]);
   575       } else {
   576         _last[level] = _prev[i];
   577       }
   578       //lace
   579       _next.set(i, _first[level]);
   580       _prev.set(_first[level], i);
   581       _prev.set(i, INVALID);
   582       _first[level] = i;
   583 
   584     }
   585 
   586     ///Deactivate item \c i.
   587 
   588     ///Deactivate item \c i.
   589     ///\pre Item \c i must be active before.
   590     void deactivate(Item i) {
   591       _active.set(i, false);
   592       int level = _level[i];
   593 
   594       if (_next[i] == INVALID || !_active[_next[i]])
   595         goto find_highest_level;
   596 
   597       //unlace
   598       _prev.set(_next[i], _prev[i]);
   599       if (_prev[i] != INVALID) {
   600         _next.set(_prev[i], _next[i]);
   601       } else {
   602         _first[_level[i]] = _next[i];
   603       }
   604       //lace
   605       _prev.set(i, _last[level]);
   606       _next.set(_last[level], i);
   607       _next.set(i, INVALID);
   608       _last[level] = i;
   609 
   610     find_highest_level:
   611       if (level == _highest_active) {
   612         while (_highest_active >= 0 && activeFree(_highest_active))
   613           --_highest_active;
   614       }
   615     }
   616 
   617     ///Query whether item \c i is active
   618     bool active(Item i) const { return _active[i]; }
   619 
   620     ///Return the level of item \c i.
   621     int operator[](Item i) const { return _level[i]; }
   622 
   623     ///Return the number of items on level \c l.
   624     int onLevel(int l) const {
   625       int num = 0;
   626       Item n = _first[l];
   627       while (n != INVALID) {
   628         ++num;
   629         n = _next[n];
   630       }
   631       return num;
   632     }
   633 
   634     ///Return true if the level is empty.
   635     bool emptyLevel(int l) const {
   636       return _first[l] == INVALID;
   637     }
   638 
   639     ///Return the number of items above level \c l.
   640     int aboveLevel(int l) const {
   641       int num = 0;
   642       for (int level = l + 1; level < _max_level; ++level)
   643         num += onLevel(level);
   644       return num;
   645     }
   646 
   647     ///Return the number of active items on level \c l.
   648     int activesOnLevel(int l) const {
   649       int num = 0;
   650       Item n = _first[l];
   651       while (n != INVALID && _active[n]) {
   652         ++num;
   653         n = _next[n];
   654       }
   655       return num;
   656     }
   657 
   658     ///Return true if there is not active item on level \c l.
   659     bool activeFree(int l) const {
   660       return _first[l] == INVALID || !_active[_first[l]];
   661     }
   662 
   663     ///Return the maximum allowed level.
   664     int maxLevel() const {
   665       return _max_level;
   666     }
   667 
   668     ///\name Highest Active Item
   669     ///Functions for working with the highest level
   670     ///active item.
   671 
   672     ///@{
   673 
   674     ///Return a highest level active item.
   675 
   676     ///Return a highest level active item.
   677     ///
   678     ///\return the highest level active item or INVALID if there is no
   679     ///active item.
   680     Item highestActive() const {
   681       return _highest_active >= 0 ? _first[_highest_active] : INVALID;
   682     }
   683 
   684     ///Return a highest active level.
   685 
   686     ///Return a highest active level.
   687     ///
   688     ///\return the level of the highest active item or -1 if there is
   689     ///no active item.
   690     int highestActiveLevel() const {
   691       return _highest_active;
   692     }
   693 
   694     ///Lift the highest active item by one.
   695 
   696     ///Lift the item returned by highestActive() by one.
   697     ///
   698     void liftHighestActive() {
   699       Item i = _first[_highest_active];
   700       if (_next[i] != INVALID) {
   701         _prev.set(_next[i], INVALID);
   702         _first[_highest_active] = _next[i];
   703       } else {
   704         _first[_highest_active] = INVALID;
   705         _last[_highest_active] = INVALID;
   706       }
   707       _level.set(i, ++_highest_active);
   708       if (_first[_highest_active] == INVALID) {
   709         _first[_highest_active] = i;
   710         _last[_highest_active] = i;
   711         _prev.set(i, INVALID);
   712         _next.set(i, INVALID);
   713       } else {
   714         _prev.set(_first[_highest_active], i);
   715         _next.set(i, _first[_highest_active]);
   716         _first[_highest_active] = i;
   717       }
   718     }
   719 
   720     ///Lift the highest active item.
   721 
   722     ///Lift the item returned by highestActive() to level \c new_level.
   723     ///
   724     ///\warning \c new_level must be strictly higher
   725     ///than the current level.
   726     ///
   727     void liftHighestActive(int new_level) {
   728       Item i = _first[_highest_active];
   729       if (_next[i] != INVALID) {
   730         _prev.set(_next[i], INVALID);
   731         _first[_highest_active] = _next[i];
   732       } else {
   733         _first[_highest_active] = INVALID;
   734         _last[_highest_active] = INVALID;
   735       }
   736       _level.set(i, _highest_active = new_level);
   737       if (_first[_highest_active] == INVALID) {
   738         _first[_highest_active] = _last[_highest_active] = i;
   739         _prev.set(i, INVALID);
   740         _next.set(i, INVALID);
   741       } else {
   742         _prev.set(_first[_highest_active], i);
   743         _next.set(i, _first[_highest_active]);
   744         _first[_highest_active] = i;
   745       }
   746     }
   747 
   748     ///Lift the highest active to top.
   749 
   750     ///Lift the item returned by highestActive() to the top level and
   751     ///deactivates the item.
   752     ///
   753     void liftHighestActiveToTop() {
   754       Item i = _first[_highest_active];
   755       _level.set(i, _max_level);
   756       if (_next[i] != INVALID) {
   757         _prev.set(_next[i], INVALID);
   758         _first[_highest_active] = _next[i];
   759       } else {
   760         _first[_highest_active] = INVALID;
   761         _last[_highest_active] = INVALID;
   762       }
   763       while (_highest_active >= 0 && activeFree(_highest_active))
   764         --_highest_active;
   765     }
   766 
   767     ///@}
   768 
   769     ///\name Active Item on Certain Level
   770     ///Functions for working with the active items.
   771 
   772     ///@{
   773 
   774     ///Returns an active item on level \c l.
   775 
   776     ///Returns an active item on level \c l.
   777     ///
   778     ///Returns an active item on level \c l or \ref INVALID if there is no such
   779     ///an item. (\c l must be from the range [0...\c max_level].
   780     Item activeOn(int l) const
   781     {
   782       return _active[_first[l]] ? _first[l] : INVALID;
   783     }
   784 
   785     ///Lifts the active item returned by \c activeOn() member function.
   786 
   787     ///Lifts the active item returned by \c activeOn() member function
   788     ///by one.
   789     Item liftActiveOn(int l)
   790     {
   791       Item i = _first[l];
   792       if (_next[i] != INVALID) {
   793         _prev.set(_next[i], INVALID);
   794         _first[l] = _next[i];
   795       } else {
   796         _first[l] = INVALID;
   797         _last[l] = INVALID;
   798       }
   799       _level.set(i, ++l);
   800       if (_first[l] == INVALID) {
   801         _first[l] = _last[l] = i;
   802         _prev.set(i, INVALID);
   803         _next.set(i, INVALID);
   804       } else {
   805         _prev.set(_first[l], i);
   806         _next.set(i, _first[l]);
   807         _first[l] = i;
   808       }
   809       if (_highest_active < l) {
   810         _highest_active = l;
   811       }
   812     }
   813 
   814     /// \brief Lifts the active item returned by \c activeOn() member function.
   815     ///
   816     /// Lifts the active item returned by \c activeOn() member function
   817     /// to the given level.
   818     void liftActiveOn(int l, int new_level)
   819     {
   820       Item i = _first[l];
   821       if (_next[i] != INVALID) {
   822         _prev.set(_next[i], INVALID);
   823         _first[l] = _next[i];
   824       } else {
   825         _first[l] = INVALID;
   826         _last[l] = INVALID;
   827       }
   828       _level.set(i, l = new_level);
   829       if (_first[l] == INVALID) {
   830         _first[l] = _last[l] = i;
   831         _prev.set(i, INVALID);
   832         _next.set(i, INVALID);
   833       } else {
   834         _prev.set(_first[l], i);
   835         _next.set(i, _first[l]);
   836         _first[l] = i;
   837       }
   838       if (_highest_active < l) {
   839         _highest_active = l;
   840       }
   841     }
   842 
   843     ///Lifts the active item returned by \c activeOn() member function.
   844 
   845     ///Lifts the active item returned by \c activeOn() member function
   846     ///to the top level.
   847     void liftActiveToTop(int l)
   848     {
   849       Item i = _first[l];
   850       if (_next[i] != INVALID) {
   851         _prev.set(_next[i], INVALID);
   852         _first[l] = _next[i];
   853       } else {
   854         _first[l] = INVALID;
   855         _last[l] = INVALID;
   856       }
   857       _level.set(i, _max_level);
   858       if (l == _highest_active) {
   859         while (_highest_active >= 0 && activeFree(_highest_active))
   860           --_highest_active;
   861       }
   862     }
   863 
   864     ///@}
   865 
   866     /// \brief Lift an active item to a higher level.
   867     ///
   868     /// Lift an active item to a higher level.
   869     /// \param i The item to be lifted. It must be active.
   870     /// \param new_level The new level of \c i. It must be strictly higher
   871     /// than the current level.
   872     ///
   873     void lift(Item i, int new_level) {
   874       if (_next[i] != INVALID) {
   875         _prev.set(_next[i], _prev[i]);
   876       } else {
   877         _last[new_level] = _prev[i];
   878       }
   879       if (_prev[i] != INVALID) {
   880         _next.set(_prev[i], _next[i]);
   881       } else {
   882         _first[new_level] = _next[i];
   883       }
   884       _level.set(i, new_level);
   885       if (_first[new_level] == INVALID) {
   886         _first[new_level] = _last[new_level] = i;
   887         _prev.set(i, INVALID);
   888         _next.set(i, INVALID);
   889       } else {
   890         _prev.set(_first[new_level], i);
   891         _next.set(i, _first[new_level]);
   892         _first[new_level] = i;
   893       }
   894       if (_highest_active < new_level) {
   895         _highest_active = new_level;
   896       }
   897     }
   898 
   899     ///Move an inactive item to the top but one level (in a dirty way).
   900 
   901     ///This function moves an inactive item to the top but one level.
   902     ///It makes the underlying datastructure corrupt, so use is only if
   903     ///you really know what it is for.
   904     ///\pre The item is on the top level.
   905     void dirtyTopButOne(Item i) {
   906       _level.set(i, _max_level - 1);
   907     }
   908 
   909     ///Lift all items on and above a level to the top (and deactivate them).
   910 
   911     ///This function lifts all items on and above level \c l to \c
   912     ///maxLevel(), and also deactivates them.
   913     void liftToTop(int l)  {
   914       for (int i = l + 1; _first[i] != INVALID; ++i) {
   915         Item n = _first[i];
   916         while (n != INVALID) {
   917           _level.set(n, _max_level);
   918           n = _next[n];
   919         }
   920         _first[i] = INVALID;
   921         _last[i] = INVALID;
   922       }
   923       if (_highest_active > l - 1) {
   924         _highest_active = l - 1;
   925         while (_highest_active >= 0 && activeFree(_highest_active))
   926           --_highest_active;
   927       }
   928     }
   929 
   930   private:
   931 
   932     int _init_level;
   933 
   934   public:
   935 
   936     ///\name Initialization
   937     ///Using this function you can initialize the levels of the item.
   938     ///\n
   939     ///This initializatios is started with calling \c initStart().
   940     ///Then the
   941     ///items should be listed levels by levels statring with the lowest one
   942     ///(with level 0). This is done by using \c initAddItem()
   943     ///and \c initNewLevel(). Finally \c initFinish() must be called.
   944     ///The items not listed will be put on the highest level.
   945     ///@{
   946 
   947     ///Start the initialization process.
   948 
   949     void initStart() {
   950 
   951       for (int i = 0; i <= _max_level; ++i) {
   952         _first[i] = _last[i] = INVALID;
   953       }
   954       _init_level = 0;
   955       for(typename ItemSetTraits<Graph,Item>::ItemIt i(_graph);
   956           i != INVALID; ++i) {
   957         _level.set(i, _max_level);
   958         _active.set(i, false);
   959       }
   960     }
   961 
   962     ///Add an item to the current level.
   963 
   964     void initAddItem(Item i) {
   965       _level.set(i, _init_level);
   966       if (_last[_init_level] == INVALID) {
   967         _first[_init_level] = i;
   968         _last[_init_level] = i;
   969         _prev.set(i, INVALID);
   970         _next.set(i, INVALID);
   971       } else {
   972         _prev.set(i, _last[_init_level]);
   973         _next.set(i, INVALID);
   974         _next.set(_last[_init_level], i);
   975         _last[_init_level] = i;
   976       }
   977     }
   978 
   979     ///Start a new level.
   980 
   981     ///Start a new level.
   982     ///It shouldn't be used before the items on level 0 are listed.
   983     void initNewLevel() {
   984       ++_init_level;
   985     }
   986 
   987     ///Finalize the initialization process.
   988 
   989     void initFinish() {
   990       _highest_active = -1;
   991     }
   992 
   993     ///@}
   994 
   995   };
   996 
   997 
   998 } //END OF NAMESPACE LEMON
   999 
  1000 #endif
  1001