1 /* -*- mode: C++; indent-tabs-mode: nil; -*-
 
     3  * This file is a part of LEMON, a generic C++ optimization library.
 
     5  * Copyright (C) 2003-2009
 
     6  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
 
     7  * (Egervary Research Group on Combinatorial Optimization, EGRES).
 
     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.
 
    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
 
    19 #ifndef LEMON_ELEVATOR_H
 
    20 #define LEMON_ELEVATOR_H
 
    24 ///\brief Elevator class
 
    26 ///Elevator class implements an efficient data structure
 
    27 ///for labeling items in push-relabel type algorithms.
 
    30 #include <lemon/core.h>
 
    31 #include <lemon/bits/traits.h>
 
    35   ///Class for handling "labels" in push-relabel type algorithms.
 
    37   ///A class for handling "labels" in push-relabel type algorithms.
 
    40   ///Using this class you can assign "labels" (nonnegative integer numbers)
 
    41   ///to the edges or nodes of a graph, manipulate and query them through
 
    42   ///operations typically arising in "push-relabel" type algorithms.
 
    44   ///Each item is either \em active or not, and you can also choose a
 
    45   ///highest level active item.
 
    49   ///\param GR Type of the underlying graph.
 
    50   ///\param Item Type of the items the data is assigned to (\c GR::Node,
 
    51   ///\c GR::Arc or \c GR::Edge).
 
    52   template<class GR, class Item>
 
    63     typedef typename ItemSetTraits<GR,Item>::template Map<Vit>::Type VitMap;
 
    64     typedef typename ItemSetTraits<GR,Item>::template Map<int>::Type IntMap;
 
    71     std::vector<Item> _items;
 
    72     std::vector<Vit> _first;
 
    73     std::vector<Vit> _last_active;
 
    77     void copy(Item i, Vit p)
 
    81     void copy(Vit s, Vit p)
 
    90     void swap(Vit i, Vit j)
 
    94       _where[ti] = _where[*i=*j];
 
   101     ///Constructor with given maximum level.
 
   103     ///Constructor with given maximum level.
 
   105     ///\param graph The underlying graph.
 
   106     ///\param max_level The maximum allowed level.
 
   107     ///Set the range of the possible labels to <tt>[0..max_level]</tt>.
 
   108     Elevator(const GR &graph,int max_level) :
 
   110       _max_level(max_level),
 
   111       _item_num(_max_level),
 
   115       _first(_max_level+2),
 
   116       _last_active(_max_level+2),
 
   117       _highest_active(-1) {}
 
   122     ///\param graph The underlying graph.
 
   123     ///Set the range of the possible labels to <tt>[0..max_level]</tt>,
 
   124     ///where \c max_level is equal to the number of labeled items in the graph.
 
   125     Elevator(const GR &graph) :
 
   127       _max_level(countItems<GR, Item>(graph)),
 
   128       _item_num(_max_level),
 
   132       _first(_max_level+2),
 
   133       _last_active(_max_level+2),
 
   138     ///Activate item \c i.
 
   140     ///Activate item \c i.
 
   141     ///\pre Item \c i shouldn't be active before.
 
   142     void activate(Item i)
 
   144       const int l=_level[i];
 
   145       swap(_where[i],++_last_active[l]);
 
   146       if(l>_highest_active) _highest_active=l;
 
   149     ///Deactivate item \c i.
 
   151     ///Deactivate item \c i.
 
   152     ///\pre Item \c i must be active before.
 
   153     void deactivate(Item i)
 
   155       swap(_where[i],_last_active[_level[i]]--);
 
   156       while(_highest_active>=0 &&
 
   157             _last_active[_highest_active]<_first[_highest_active])
 
   161     ///Query whether item \c i is active
 
   162     bool active(Item i) const { return _where[i]<=_last_active[_level[i]]; }
 
   164     ///Return the level of item \c i.
 
   165     int operator[](Item i) const { return _level[i]; }
 
   167     ///Return the number of items on level \c l.
 
   168     int onLevel(int l) const
 
   170       return _first[l+1]-_first[l];
 
   172     ///Return true if level \c l is empty.
 
   173     bool emptyLevel(int l) const
 
   175       return _first[l+1]-_first[l]==0;
 
   177     ///Return the number of items above level \c l.
 
   178     int aboveLevel(int l) const
 
   180       return _first[_max_level+1]-_first[l+1];
 
   182     ///Return the number of active items on level \c l.
 
   183     int activesOnLevel(int l) const
 
   185       return _last_active[l]-_first[l]+1;
 
   187     ///Return true if there is no active item on level \c l.
 
   188     bool activeFree(int l) const
 
   190       return _last_active[l]<_first[l];
 
   192     ///Return the maximum allowed level.
 
   198     ///\name Highest Active Item
 
   199     ///Functions for working with the highest level
 
   204     ///Return a highest level active item.
 
   206     ///Return a highest level active item or INVALID if there is no active
 
   208     Item highestActive() const
 
   210       return _highest_active>=0?*_last_active[_highest_active]:INVALID;
 
   213     ///Return the highest active level.
 
   215     ///Return the level of the highest active item or -1 if there is no active
 
   217     int highestActiveLevel() const
 
   219       return _highest_active;
 
   222     ///Lift the highest active item by one.
 
   224     ///Lift the item returned by highestActive() by one.
 
   226     void liftHighestActive()
 
   228       Item it = *_last_active[_highest_active];
 
   230       swap(_last_active[_highest_active]--,_last_active[_highest_active+1]);
 
   231       --_first[++_highest_active];
 
   234     ///Lift the highest active item to the given level.
 
   236     ///Lift the item returned by highestActive() to level \c new_level.
 
   238     ///\warning \c new_level must be strictly higher
 
   239     ///than the current level.
 
   241     void liftHighestActive(int new_level)
 
   243       const Item li = *_last_active[_highest_active];
 
   245       copy(--_first[_highest_active+1],_last_active[_highest_active]--);
 
   246       for(int l=_highest_active+1;l<new_level;l++)
 
   248           copy(--_first[l+1],_first[l]);
 
   251       copy(li,_first[new_level]);
 
   252       _level[li] = new_level;
 
   253       _highest_active=new_level;
 
   256     ///Lift the highest active item to the top level.
 
   258     ///Lift the item returned by highestActive() to the top level and
 
   260     void liftHighestActiveToTop()
 
   262       const Item li = *_last_active[_highest_active];
 
   264       copy(--_first[_highest_active+1],_last_active[_highest_active]--);
 
   265       for(int l=_highest_active+1;l<_max_level;l++)
 
   267           copy(--_first[l+1],_first[l]);
 
   270       copy(li,_first[_max_level]);
 
   271       --_last_active[_max_level];
 
   272       _level[li] = _max_level;
 
   274       while(_highest_active>=0 &&
 
   275             _last_active[_highest_active]<_first[_highest_active])
 
   281     ///\name Active Item on Certain Level
 
   282     ///Functions for working with the active items.
 
   286     ///Return an active item on level \c l.
 
   288     ///Return an active item on level \c l or \ref INVALID if there is no such
 
   289     ///an item. (\c l must be from the range [0...\c max_level].
 
   290     Item activeOn(int l) const
 
   292       return _last_active[l]>=_first[l]?*_last_active[l]:INVALID;
 
   295     ///Lift the active item returned by \c activeOn(level) by one.
 
   297     ///Lift the active item returned by \ref activeOn() "activeOn(level)"
 
   299     Item liftActiveOn(int level)
 
   301       Item it =*_last_active[level];
 
   303       swap(_last_active[level]--, --_first[level+1]);
 
   304       if (level+1>_highest_active) ++_highest_active;
 
   307     ///Lift the active item returned by \c activeOn(level) to the given level.
 
   309     ///Lift the active item returned by \ref activeOn() "activeOn(level)"
 
   310     ///to the given level.
 
   311     void liftActiveOn(int level, int new_level)
 
   313       const Item ai = *_last_active[level];
 
   315       copy(--_first[level+1], _last_active[level]--);
 
   316       for(int l=level+1;l<new_level;l++)
 
   318           copy(_last_active[l],_first[l]);
 
   319           copy(--_first[l+1], _last_active[l]--);
 
   321       copy(ai,_first[new_level]);
 
   322       _level[ai] = new_level;
 
   323       if (new_level>_highest_active) _highest_active=new_level;
 
   326     ///Lift the active item returned by \c activeOn(level) to the top level.
 
   328     ///Lift the active item returned by \ref activeOn() "activeOn(level)"
 
   329     ///to the top level and deactivate it.
 
   330     void liftActiveToTop(int level)
 
   332       const Item ai = *_last_active[level];
 
   334       copy(--_first[level+1],_last_active[level]--);
 
   335       for(int l=level+1;l<_max_level;l++)
 
   337           copy(_last_active[l],_first[l]);
 
   338           copy(--_first[l+1], _last_active[l]--);
 
   340       copy(ai,_first[_max_level]);
 
   341       --_last_active[_max_level];
 
   342       _level[ai] = _max_level;
 
   344       if (_highest_active==level) {
 
   345         while(_highest_active>=0 &&
 
   346               _last_active[_highest_active]<_first[_highest_active])
 
   353     ///Lift an active item to a higher level.
 
   355     ///Lift an active item to a higher level.
 
   356     ///\param i The item to be lifted. It must be active.
 
   357     ///\param new_level The new level of \c i. It must be strictly higher
 
   358     ///than the current level.
 
   360     void lift(Item i, int new_level)
 
   362       const int lo = _level[i];
 
   363       const Vit w = _where[i];
 
   365       copy(_last_active[lo],w);
 
   366       copy(--_first[lo+1],_last_active[lo]--);
 
   367       for(int l=lo+1;l<new_level;l++)
 
   369           copy(_last_active[l],_first[l]);
 
   370           copy(--_first[l+1],_last_active[l]--);
 
   372       copy(i,_first[new_level]);
 
   373       _level[i] = new_level;
 
   374       if(new_level>_highest_active) _highest_active=new_level;
 
   377     ///Move an inactive item to the top but one level (in a dirty way).
 
   379     ///This function moves an inactive item from the top level to the top
 
   380     ///but one level (in a dirty way).
 
   381     ///\warning It makes the underlying datastructure corrupt, so use it
 
   382     ///only if you really know what it is for.
 
   383     ///\pre The item is on the top level.
 
   384     void dirtyTopButOne(Item i) {
 
   385       _level[i] = _max_level - 1;
 
   388     ///Lift all items on and above the given level to the top level.
 
   390     ///This function lifts all items on and above level \c l to the top
 
   391     ///level and deactivates them.
 
   392     void liftToTop(int l)
 
   394       const Vit f=_first[l];
 
   395       const Vit tl=_first[_max_level];
 
   396       for(Vit i=f;i!=tl;++i)
 
   397         _level[*i] = _max_level;
 
   398       for(int i=l;i<=_max_level;i++)
 
   403       for(_highest_active=l-1;
 
   404           _highest_active>=0 &&
 
   405             _last_active[_highest_active]<_first[_highest_active];
 
   415     ///\name Initialization
 
   416     ///Using these functions you can initialize the levels of the items.
 
   418     ///The initialization must be started with calling \c initStart().
 
   419     ///Then the items should be listed level by level starting with the
 
   420     ///lowest one (level 0) using \c initAddItem() and \c initNewLevel().
 
   421     ///Finally \c initFinish() must be called.
 
   422     ///The items not listed are put on the highest level.
 
   425     ///Start the initialization process.
 
   429       _init_num=&_items[0];
 
   430       _first[0]=&_items[0];
 
   431       _last_active[0]=&_items[0]-1;
 
   433       for(typename ItemSetTraits<GR,Item>::ItemIt i(_g);i!=INVALID;++i)
 
   437           _level[i] = _max_level;
 
   442     ///Add an item to the current level.
 
   443     void initAddItem(Item i)
 
   445       swap(_where[i],_init_num);
 
   446       _level[i] = _init_lev;
 
   450     ///Start a new level.
 
   452     ///Start a new level.
 
   453     ///It shouldn't be used before the items on level 0 are listed.
 
   457       _first[_init_lev]=_init_num;
 
   458       _last_active[_init_lev]=_init_num-1;
 
   461     ///Finalize the initialization process.
 
   464       for(_init_lev++;_init_lev<=_max_level;_init_lev++)
 
   466           _first[_init_lev]=_init_num;
 
   467           _last_active[_init_lev]=_init_num-1;
 
   469       _first[_max_level+1]=&_items[0]+_item_num;
 
   470       _last_active[_max_level+1]=&_items[0]+_item_num-1;
 
   471       _highest_active = -1;
 
   478   ///Class for handling "labels" in push-relabel type algorithms.
 
   480   ///A class for handling "labels" in push-relabel type algorithms.
 
   483   ///Using this class you can assign "labels" (nonnegative integer numbers)
 
   484   ///to the edges or nodes of a graph, manipulate and query them through
 
   485   ///operations typically arising in "push-relabel" type algorithms.
 
   487   ///Each item is either \em active or not, and you can also choose a
 
   488   ///highest level active item.
 
   492   ///\param GR Type of the underlying graph.
 
   493   ///\param Item Type of the items the data is assigned to (\c GR::Node,
 
   494   ///\c GR::Arc or \c GR::Edge).
 
   495   template <class GR, class Item>
 
   496   class LinkedElevator {
 
   504     typedef typename ItemSetTraits<GR,Item>::
 
   505     template Map<Item>::Type ItemMap;
 
   506     typedef typename ItemSetTraits<GR,Item>::
 
   507     template Map<int>::Type IntMap;
 
   508     typedef typename ItemSetTraits<GR,Item>::
 
   509     template Map<bool>::Type BoolMap;
 
   514     std::vector<Item> _first, _last;
 
   515     ItemMap _prev, _next;
 
   521     ///Constructor with given maximum level.
 
   523     ///Constructor with given maximum level.
 
   525     ///\param graph The underlying graph.
 
   526     ///\param max_level The maximum allowed level.
 
   527     ///Set the range of the possible labels to <tt>[0..max_level]</tt>.
 
   528     LinkedElevator(const GR& graph, int max_level)
 
   529       : _graph(graph), _max_level(max_level), _item_num(_max_level),
 
   530         _first(_max_level + 1), _last(_max_level + 1),
 
   531         _prev(graph), _next(graph),
 
   532         _highest_active(-1), _level(graph), _active(graph) {}
 
   538     ///\param graph The underlying graph.
 
   539     ///Set the range of the possible labels to <tt>[0..max_level]</tt>,
 
   540     ///where \c max_level is equal to the number of labeled items in the graph.
 
   541     LinkedElevator(const GR& graph)
 
   542       : _graph(graph), _max_level(countItems<GR, Item>(graph)),
 
   543         _item_num(_max_level),
 
   544         _first(_max_level + 1), _last(_max_level + 1),
 
   545         _prev(graph, INVALID), _next(graph, INVALID),
 
   546         _highest_active(-1), _level(graph), _active(graph) {}
 
   549     ///Activate item \c i.
 
   551     ///Activate item \c i.
 
   552     ///\pre Item \c i shouldn't be active before.
 
   553     void activate(Item i) {
 
   556       int level = _level[i];
 
   557       if (level > _highest_active) {
 
   558         _highest_active = level;
 
   561       if (_prev[i] == INVALID || _active[_prev[i]]) return;
 
   563       _next[_prev[i]] = _next[i];
 
   564       if (_next[i] != INVALID) {
 
   565         _prev[_next[i]] = _prev[i];
 
   567         _last[level] = _prev[i];
 
   570       _next[i] = _first[level];
 
   571       _prev[_first[level]] = i;
 
   577     ///Deactivate item \c i.
 
   579     ///Deactivate item \c i.
 
   580     ///\pre Item \c i must be active before.
 
   581     void deactivate(Item i) {
 
   583       int level = _level[i];
 
   585       if (_next[i] == INVALID || !_active[_next[i]])
 
   586         goto find_highest_level;
 
   589       _prev[_next[i]] = _prev[i];
 
   590       if (_prev[i] != INVALID) {
 
   591         _next[_prev[i]] = _next[i];
 
   593         _first[_level[i]] = _next[i];
 
   596       _prev[i] = _last[level];
 
   597       _next[_last[level]] = i;
 
   602       if (level == _highest_active) {
 
   603         while (_highest_active >= 0 && activeFree(_highest_active))
 
   608     ///Query whether item \c i is active
 
   609     bool active(Item i) const { return _active[i]; }
 
   611     ///Return the level of item \c i.
 
   612     int operator[](Item i) const { return _level[i]; }
 
   614     ///Return the number of items on level \c l.
 
   615     int onLevel(int l) const {
 
   618       while (n != INVALID) {
 
   625     ///Return true if the level is empty.
 
   626     bool emptyLevel(int l) const {
 
   627       return _first[l] == INVALID;
 
   630     ///Return the number of items above level \c l.
 
   631     int aboveLevel(int l) const {
 
   633       for (int level = l + 1; level < _max_level; ++level)
 
   634         num += onLevel(level);
 
   638     ///Return the number of active items on level \c l.
 
   639     int activesOnLevel(int l) const {
 
   642       while (n != INVALID && _active[n]) {
 
   649     ///Return true if there is no active item on level \c l.
 
   650     bool activeFree(int l) const {
 
   651       return _first[l] == INVALID || !_active[_first[l]];
 
   654     ///Return the maximum allowed level.
 
   655     int maxLevel() const {
 
   659     ///\name Highest Active Item
 
   660     ///Functions for working with the highest level
 
   665     ///Return a highest level active item.
 
   667     ///Return a highest level active item or INVALID if there is no active
 
   669     Item highestActive() const {
 
   670       return _highest_active >= 0 ? _first[_highest_active] : INVALID;
 
   673     ///Return the highest active level.
 
   675     ///Return the level of the highest active item or -1 if there is no active
 
   677     int highestActiveLevel() const {
 
   678       return _highest_active;
 
   681     ///Lift the highest active item by one.
 
   683     ///Lift the item returned by highestActive() by one.
 
   685     void liftHighestActive() {
 
   686       Item i = _first[_highest_active];
 
   687       if (_next[i] != INVALID) {
 
   688         _prev[_next[i]] = INVALID;
 
   689         _first[_highest_active] = _next[i];
 
   691         _first[_highest_active] = INVALID;
 
   692         _last[_highest_active] = INVALID;
 
   694       _level[i] = ++_highest_active;
 
   695       if (_first[_highest_active] == INVALID) {
 
   696         _first[_highest_active] = i;
 
   697         _last[_highest_active] = i;
 
   701         _prev[_first[_highest_active]] = i;
 
   702         _next[i] = _first[_highest_active];
 
   703         _first[_highest_active] = i;
 
   707     ///Lift the highest active item to the given level.
 
   709     ///Lift the item returned by highestActive() to level \c new_level.
 
   711     ///\warning \c new_level must be strictly higher
 
   712     ///than the current level.
 
   714     void liftHighestActive(int new_level) {
 
   715       Item i = _first[_highest_active];
 
   716       if (_next[i] != INVALID) {
 
   717         _prev[_next[i]] = INVALID;
 
   718         _first[_highest_active] = _next[i];
 
   720         _first[_highest_active] = INVALID;
 
   721         _last[_highest_active] = INVALID;
 
   723       _level[i] = _highest_active = new_level;
 
   724       if (_first[_highest_active] == INVALID) {
 
   725         _first[_highest_active] = _last[_highest_active] = i;
 
   729         _prev[_first[_highest_active]] = i;
 
   730         _next[i] = _first[_highest_active];
 
   731         _first[_highest_active] = i;
 
   735     ///Lift the highest active item to the top level.
 
   737     ///Lift the item returned by highestActive() to the top level and
 
   739     void liftHighestActiveToTop() {
 
   740       Item i = _first[_highest_active];
 
   741       _level[i] = _max_level;
 
   742       if (_next[i] != INVALID) {
 
   743         _prev[_next[i]] = INVALID;
 
   744         _first[_highest_active] = _next[i];
 
   746         _first[_highest_active] = INVALID;
 
   747         _last[_highest_active] = INVALID;
 
   749       while (_highest_active >= 0 && activeFree(_highest_active))
 
   755     ///\name Active Item on Certain Level
 
   756     ///Functions for working with the active items.
 
   760     ///Return an active item on level \c l.
 
   762     ///Return an active item on level \c l or \ref INVALID if there is no such
 
   763     ///an item. (\c l must be from the range [0...\c max_level].
 
   764     Item activeOn(int l) const
 
   766       return _active[_first[l]] ? _first[l] : INVALID;
 
   769     ///Lift the active item returned by \c activeOn(l) by one.
 
   771     ///Lift the active item returned by \ref activeOn() "activeOn(l)"
 
   773     Item liftActiveOn(int l)
 
   776       if (_next[i] != INVALID) {
 
   777         _prev[_next[i]] = INVALID;
 
   778         _first[l] = _next[i];
 
   784       if (_first[l] == INVALID) {
 
   785         _first[l] = _last[l] = i;
 
   789         _prev[_first[l]] = i;
 
   790         _next[i] = _first[l];
 
   793       if (_highest_active < l) {
 
   798     ///Lift the active item returned by \c activeOn(l) to the given level.
 
   800     ///Lift the active item returned by \ref activeOn() "activeOn(l)"
 
   801     ///to the given level.
 
   802     void liftActiveOn(int l, int new_level)
 
   805       if (_next[i] != INVALID) {
 
   806         _prev[_next[i]] = INVALID;
 
   807         _first[l] = _next[i];
 
   812       _level[i] = l = new_level;
 
   813       if (_first[l] == INVALID) {
 
   814         _first[l] = _last[l] = i;
 
   818         _prev[_first[l]] = i;
 
   819         _next[i] = _first[l];
 
   822       if (_highest_active < l) {
 
   827     ///Lift the active item returned by \c activeOn(l) to the top level.
 
   829     ///Lift the active item returned by \ref activeOn() "activeOn(l)"
 
   830     ///to the top level and deactivate it.
 
   831     void liftActiveToTop(int l)
 
   834       if (_next[i] != INVALID) {
 
   835         _prev[_next[i]] = INVALID;
 
   836         _first[l] = _next[i];
 
   841       _level[i] = _max_level;
 
   842       if (l == _highest_active) {
 
   843         while (_highest_active >= 0 && activeFree(_highest_active))
 
   850     /// \brief Lift an active item to a higher level.
 
   852     /// Lift an active item to a higher level.
 
   853     /// \param i The item to be lifted. It must be active.
 
   854     /// \param new_level The new level of \c i. It must be strictly higher
 
   855     /// than the current level.
 
   857     void lift(Item i, int new_level) {
 
   858       if (_next[i] != INVALID) {
 
   859         _prev[_next[i]] = _prev[i];
 
   861         _last[new_level] = _prev[i];
 
   863       if (_prev[i] != INVALID) {
 
   864         _next[_prev[i]] = _next[i];
 
   866         _first[new_level] = _next[i];
 
   868       _level[i] = new_level;
 
   869       if (_first[new_level] == INVALID) {
 
   870         _first[new_level] = _last[new_level] = i;
 
   874         _prev[_first[new_level]] = i;
 
   875         _next[i] = _first[new_level];
 
   876         _first[new_level] = i;
 
   878       if (_highest_active < new_level) {
 
   879         _highest_active = new_level;
 
   883     ///Move an inactive item to the top but one level (in a dirty way).
 
   885     ///This function moves an inactive item from the top level to the top
 
   886     ///but one level (in a dirty way).
 
   887     ///\warning It makes the underlying datastructure corrupt, so use it
 
   888     ///only if you really know what it is for.
 
   889     ///\pre The item is on the top level.
 
   890     void dirtyTopButOne(Item i) {
 
   891       _level[i] = _max_level - 1;
 
   894     ///Lift all items on and above the given level to the top level.
 
   896     ///This function lifts all items on and above level \c l to the top
 
   897     ///level and deactivates them.
 
   898     void liftToTop(int l)  {
 
   899       for (int i = l + 1; _first[i] != INVALID; ++i) {
 
   901         while (n != INVALID) {
 
   902           _level[n] = _max_level;
 
   908       if (_highest_active > l - 1) {
 
   909         _highest_active = l - 1;
 
   910         while (_highest_active >= 0 && activeFree(_highest_active))
 
   921     ///\name Initialization
 
   922     ///Using these functions you can initialize the levels of the items.
 
   924     ///The initialization must be started with calling \c initStart().
 
   925     ///Then the items should be listed level by level starting with the
 
   926     ///lowest one (level 0) using \c initAddItem() and \c initNewLevel().
 
   927     ///Finally \c initFinish() must be called.
 
   928     ///The items not listed are put on the highest level.
 
   931     ///Start the initialization process.
 
   934       for (int i = 0; i <= _max_level; ++i) {
 
   935         _first[i] = _last[i] = INVALID;
 
   938       for(typename ItemSetTraits<GR,Item>::ItemIt i(_graph);
 
   940         _level[i] = _max_level;
 
   945     ///Add an item to the current level.
 
   946     void initAddItem(Item i) {
 
   947       _level[i] = _init_level;
 
   948       if (_last[_init_level] == INVALID) {
 
   949         _first[_init_level] = i;
 
   950         _last[_init_level] = i;
 
   954         _prev[i] = _last[_init_level];
 
   956         _next[_last[_init_level]] = i;
 
   957         _last[_init_level] = i;
 
   961     ///Start a new level.
 
   963     ///Start a new level.
 
   964     ///It shouldn't be used before the items on level 0 are listed.
 
   965     void initNewLevel() {
 
   969     ///Finalize the initialization process.
 
   971       _highest_active = -1;
 
   979 } //END OF NAMESPACE LEMON