[Lemon-commits] deba: r3378 - in lemon/trunk/lemon: . bits

Lemon SVN svn at lemon.cs.elte.hu
Wed Nov 14 18:44:43 CET 2007


Author: deba
Date: Wed Nov 14 18:44:42 2007
New Revision: 3378

Modified:
   lemon/trunk/lemon/bits/traits.h
   lemon/trunk/lemon/circulation.h
   lemon/trunk/lemon/elevator.h
   lemon/trunk/lemon/pr_bipartite_matching.h

Log:
Elevator: slight changes in elevator interface
LinkedElevator: based on linked lists



Modified: lemon/trunk/lemon/bits/traits.h
==============================================================================
--- lemon/trunk/lemon/bits/traits.h	(original)
+++ lemon/trunk/lemon/bits/traits.h	Wed Nov 14 18:44:42 2007
@@ -1,3 +1,4 @@
+
 /* -*- C++ -*-
  *
  * This file is a part of LEMON, a generic C++ optimization library
@@ -57,6 +58,7 @@
     class Map : public Graph::template NodeMap<_Value> {
     public:
       typedef typename Graph::template NodeMap<_Value> Parent; 
+      typedef typename Graph::template NodeMap<_Value> Type; 
       typedef typename Parent::Value Value;
 
       Map(const Graph& _graph) : Parent(_graph) {}
@@ -94,6 +96,7 @@
     class Map : public Graph::template EdgeMap<_Value> {
     public:
       typedef typename Graph::template EdgeMap<_Value> Parent; 
+      typedef typename Graph::template EdgeMap<_Value> Type; 
       typedef typename Parent::Value Value;
 
       Map(const Graph& _graph) : Parent(_graph) {}
@@ -130,6 +133,7 @@
     class Map : public Graph::template UEdgeMap<_Value> {
     public:
       typedef typename Graph::template UEdgeMap<_Value> Parent; 
+      typedef typename Graph::template UEdgeMap<_Value> Type; 
       typedef typename Parent::Value Value;
 
       Map(const Graph& _graph) : Parent(_graph) {}
@@ -166,6 +170,7 @@
     class Map : public Graph::template ANodeMap<_Value> {
     public:
       typedef typename Graph::template ANodeMap<_Value> Parent; 
+      typedef typename Graph::template ANodeMap<_Value> Type; 
       typedef typename Parent::Value Value;
 
       Map(const Graph& _graph) : Parent(_graph) {}
@@ -202,6 +207,7 @@
     class Map : public Graph::template BNodeMap<_Value> {
     public:
       typedef typename Graph::template BNodeMap<_Value> Parent; 
+      typedef typename Graph::template BNodeMap<_Value> Type; 
       typedef typename Parent::Value Value;
 
       Map(const Graph& _graph) : Parent(_graph) {}

Modified: lemon/trunk/lemon/circulation.h
==============================================================================
--- lemon/trunk/lemon/circulation.h	(original)
+++ lemon/trunk/lemon/circulation.h	Wed Nov 14 18:44:42 2007
@@ -253,14 +253,14 @@
 	_excess[act]=exc;
 	if(!_tol.positive(exc)) _levels.deactivate(act);
 	else if(mlevel==_node_num) {
-	  _levels.liftHighestActiveTo(_node_num);
+	  _levels.liftHighestActiveToTop();
 #ifdef LEMON_CIRCULATION_DEBUG
 	  std::cerr << "  Lift to level " << _node_num << std::endl;
 #endif
 	  return _levels.onLevel(_node_num-1)==0?_node_num-1:actlevel;
 	}
 	else {
-	  _levels.liftHighestActiveTo(mlevel+1);
+	  _levels.liftHighestActive(mlevel+1);
 #ifdef LEMON_CIRCULATION_DEBUG
 	  std::cerr << "  Lift to level " << mlevel+1 << std::endl;
 #endif

Modified: lemon/trunk/lemon/elevator.h
==============================================================================
--- lemon/trunk/lemon/elevator.h	(original)
+++ lemon/trunk/lemon/elevator.h	Wed Nov 14 18:44:42 2007
@@ -42,16 +42,22 @@
   ///Each item is either \em active or not, and you can also choose a
   ///highest level active item.
   ///
+  ///\sa LinkedElevator
+  ///
   ///\param Graph the underlying graph type
   ///\param Item Type of the items the data is assigned to (Graph::Node,
   ///Graph::Edge, Graph::UEdge)
   template<class Graph, class Item>
   class Elevator 
   {
-  public:
+  private:
+
+    typedef Item Key;
+    typedef int Value;
+
     typedef typename std::vector<Item>::iterator Vit;
-    typedef DefaultMap<Graph,Item,Vit> VitMap;
-    typedef DefaultMap<Graph,Item,int> IntMap;
+    typedef typename ItemSetTraits<Graph,Item>::template Map<Vit>::Type VitMap;
+    typedef typename ItemSetTraits<Graph,Item>::template Map<int>::Type IntMap;
 
     const Graph &_g;
     int _max_level;
@@ -86,28 +92,8 @@
       *j=ti;
     }
     
-    void checkDs() const
-    {
-      for(typename ItemSetTraits<Graph,Item>::ItemIt i(_g);i!=INVALID;++i)
-	{
-	  Vit w=_where[i];
-	  int l=_level[i];
-	  check(*w==i,"GEBASZ: CORRUPT DS");
-	  check(_first[l]<=w,"GEBASZ: CORRUPT DS");
-	  check(_first[l+1]>w,"GEBASZ: CORRUPT DS");
-	}
-      for(int l=0;l<=_max_level;++l) 
-	{
-	  check(_first[l]<=_last_active[l]+1,"GEBASZ: CORRUPT DS");
-	  check(_last_active[l]<_first[l+1],"GEBASZ: CORRUPT DS");
-	  check(_first[l]<=_first[l+1],"GEBASZ: CORRUPT DS");
-	}
-      check(_highest_active<0 ||
-	    _first[_highest_active]<=_last_active[_highest_active],
-	    "GEBASZ: CORRUPT DS");
-    }
-
   public:
+        
     ///Constructor with given maximum level.
 
     ///Constructor with given maximum level.
@@ -144,7 +130,7 @@
       _highest_active(-1)
     {
     }
-  
+    
     ///Activate item \c i.
 
     ///Activate item \c i.
@@ -174,22 +160,16 @@
     ///Return the level of item \c i.
     int operator[](Item i) const { return _level[i]; }
 
-    ///Returns an active item on level \c l.
-
-    ///Returns an active item on level \c l.
-    ///
-    ///Returns an active item on level \c l or \ref INVALID if there is no such
-    ///an item. (\c l must be from the range [0...\c max_level].
-    Item operator[](int l) const
-    { 
-      return _last_active[l]>=_first[l]?*_last_active[l]:INVALID;
-    }
-
     ///Return the number of items on level \c l.
     int onLevel(int l) const
     {
       return _first[l+1]-_first[l];
     }
+    ///Return true if the level is empty.
+    bool emptyLevel(int l) const
+    {
+      return _first[l+1]-_first[l]==0;
+    }
     ///Return the number of items above level \c l.
     int aboveLevel(int l) const
     {
@@ -200,6 +180,11 @@
     {
       return _last_active[l]-_first[l]+1;
     }
+    ///Return true if there is not active item on level \c l.
+    bool activeFree(int l) const
+    {
+      return _last_active[l]<_first[l];
+    }
     ///Return the maximum allowed level.
     int maxLevel() const 
     {
@@ -252,7 +237,7 @@
     ///\warning \c new_level must be strictly higher
     ///than the current level.
     ///
-    void liftHighestActiveTo(int new_level) 
+    void liftHighestActive(int new_level) 
     {
       const Item li = *_last_active[_highest_active];
       
@@ -266,7 +251,107 @@
       _level[li]=new_level;
       _highest_active=new_level;
     }
+
+    ///Lift the highest active item.
+
+    ///Lift the item returned by highestActive() to the top level and
+    ///deactivates it.
+    ///
+    ///\warning \c new_level must be strictly higher
+    ///than the current level.
+    ///
+    void liftHighestActiveToTop() 
+    {
+      const Item li = *_last_active[_highest_active];
+      
+      copy(--_first[_highest_active+1],_last_active[_highest_active]--);
+      for(int l=_highest_active+1;l<_max_level;l++)
+	{
+	  copy(--_first[l+1],_first[l]);
+	  --_last_active[l];
+	}
+      copy(li,_first[_max_level]);
+      --_last_active[_max_level];
+      _level[li]=_max_level;
+
+      while(_highest_active>=0 &&
+	    _last_active[_highest_active]<_first[_highest_active])
+	_highest_active--;
+    }
+    
+    ///@}
+    
+    ///\name Active Item on Certain Level 
+    ///Functions for working with the active items.
+
+    ///@{
+
+    ///Returns an active item on level \c l.
+    
+    ///Returns an active item on level \c l.
+    ///
+    ///Returns an active item on level \c l or \ref INVALID if there is no such
+    ///an item. (\c l must be from the range [0...\c max_level].
+    Item activeOn(int l) const
+    { 
+      return _last_active[l]>=_first[l]?*_last_active[l]:INVALID;
+    }
+
+    ///Lifts the active item returned by \c activeOn() member function.
+    
+    ///Lifts the active item returned by \c activeOn() member function
+    ///by one.
+    Item liftActiveOn(int level)
+    { 
+      ++_level[*_last_active[level]];
+      swap(_last_active[level]--, --_first[level+1]);
+      if (level+1>_highest_active) ++_highest_active;
+    }
+
+    ///Lifts the active item returned by \c activeOn() member function.
+    
+    ///Lifts the active item returned by \c activeOn() member function
+    ///to the given level.
+    void liftActiveOn(int level, int new_level)
+    { 
+      const Item ai = *_last_active[level];
+      
+      copy(--_first[level+1], _last_active[level]--);
+      for(int l=level+1;l<new_level;l++)
+	{
+	  copy(_last_active[l],_first[l]);
+	  copy(--_first[l+1], _last_active[l]--);
+	}
+      copy(ai,_first[new_level]);
+      _level[ai]=new_level;
+      if (new_level>_highest_active) _highest_active=new_level;
+    }
+
+    ///Lifts the active item returned by \c activeOn() member function.
     
+    ///Lifts the active item returned by \c activeOn() member function
+    ///to the top level.
+    void liftActiveToTop(int level)
+    {
+      const Item ai = *_last_active[level];
+      
+      copy(--_first[level+1],_last_active[level]--);
+      for(int l=level+1;l<_max_level;l++)
+	{
+	  copy(_last_active[l],_first[l]);
+	  copy(--_first[l+1], _last_active[l]--);
+	}
+      copy(ai,_first[_max_level]);
+      --_last_active[_max_level];
+      _level[ai]=_max_level;
+
+      if (_highest_active==level) {
+	while(_highest_active>=0 && 
+	      _last_active[_highest_active]<_first[_highest_active]) 
+	  _highest_active--;
+      }
+    }
+
     ///@}
     
     ///Lift an active item to a higher level.
@@ -276,7 +361,7 @@
     ///\param new_level The new level of \c i. It must be strictly higher
     ///than the current level.
     ///
-    void liftTo(Item i, int new_level) 
+    void lift(Item i, int new_level) 
     {
       const int lo = _level[i];
       const Vit w = _where[i];
@@ -292,28 +377,11 @@
       _level[i]=new_level;
       if(new_level>_highest_active) _highest_active=new_level;
     }
-
-//     void liftToTop(int l) 
-//     {
-//       const Vit f=_first[l];
-//       for(int i=l;i<=_max_level;i++)
-// 	{
-// 	  _first[i]=f;
-// 	  _last_active[i]=f-1;
-// 	}
-//       for(Vit i=f;i!=_items.end();++i)
-// 	_level[*i]=_max_level;
-//       for(_highest_active=l-1;
-// 	  _highest_active>=0 &&
-// 	    _last_active[_highest_active]<_first[_highest_active];
-// 	  _highest_active--) ;
-//     }
     
     ///Lift all nodes on and above a level to the top (and deactivate them).
 
-    ///This function lifts all nodes on and above level \c l to \c maxLevel(),
-    ///and
-    ///also deactivates them.
+    ///This function lifts all nodes on and above level \c l to \c
+    ///maxLevel(), and also deactivates them.
     void liftToTop(int l) 
     {
       const Vit f=_first[l];
@@ -397,12 +465,511 @@
 	}
       _first[_max_level+1]=_items.begin()+_item_num;
       _last_active[_max_level+1]=_items.begin()+_item_num-1;
+      _highest_active = -1;
+    }
+
+    ///@}
+
+  };
+
+  ///Class for handling "labels" in push-relabel type algorithms.
+  
+  ///A class for handling "labels" in push-relabel type algorithms.
+  ///
+  ///\ingroup auxdat
+  ///Using this class you can assign "labels" (nonnegative integer numbers)
+  ///to the edges or nodes of a graph, manipulate and query them through
+  ///operations typically arising in "push-relabel" type algorithms.
+  ///
+  ///Each item is either \em active or not, and you can also choose a
+  ///highest level active item.
+  ///
+  ///\sa Elevator
+  ///
+  ///\param Graph the underlying graph type
+  ///\param Item Type of the items the data is assigned to (Graph::Node,
+  ///Graph::Edge, Graph::UEdge)
+  template <class Graph, class Item>
+  class LinkedElevator {
+  private:
+
+    typedef Item Key;
+    typedef int Value;
+
+    typedef typename ItemSetTraits<Graph,Item>::
+    template Map<Item>::Type ItemMap;
+    typedef typename ItemSetTraits<Graph,Item>::
+    template Map<int>::Type IntMap;
+    typedef typename ItemSetTraits<Graph,Item>::
+    template Map<bool>::Type BoolMap;
+
+    const Graph &_graph;
+    int _max_level;
+    int _item_num;
+    std::vector<Item> _first, _last;
+    ItemMap _prev, _next;    
+    int _highest_active;
+    IntMap _level;
+    BoolMap _active;
+    
+  public:
+    ///Constructor with given maximum level.
+
+    ///Constructor with given maximum level.
+    ///
+    ///\param g The underlying graph
+    ///\param max_level Set the range of the possible labels to
+    ///[0...\c max_level]
+    LinkedElevator(const Graph& graph, int max_level) 
+      : _graph(graph), _max_level(max_level), _item_num(_max_level), 
+	_first(_max_level + 1), _last(_max_level + 1),
+	_prev(graph), _next(graph),      
+	_highest_active(-1), _level(graph), _active(graph) {}
+
+    ///Constructor.
+
+    ///Constructor.
+    ///
+    ///\param g The underlying graph
+    ///The range of the possible labels is [0...\c max_level],
+    ///where \c max_level is equal to the number of labeled items in the graph.
+    LinkedElevator(const Graph& graph) 
+      : _graph(graph), _max_level(countItems<Graph, Item>(graph)), 
+	_item_num(_max_level), 
+	_first(_max_level + 1), _last(_max_level + 1),
+	_prev(graph, INVALID), _next(graph, INVALID),      
+	_highest_active(-1), _level(graph), _active(graph) {}
+  
+
+    ///Activate item \c i.
+
+    ///Activate item \c i.
+    ///\pre Item \c i shouldn't be active before.
+    void activate(Item i) {
+      _active.set(i, true);
+
+      int level = _level[i];
+      if (level > _highest_active) {
+	_highest_active = level;
+      }
+
+      if (_prev[i] == INVALID || _active[_prev[i]]) return;	    
+      //unlace
+      _next.set(_prev[i], _next[i]);
+      if (_next[i] != INVALID) {
+	_prev.set(_next[i], _prev[i]);
+      } else {
+	_last[level] = _prev[i];
+      }
+      //lace
+      _next.set(i, _first[level]);
+      _prev.set(_first[level], i);
+      _prev.set(i, INVALID);
+      _first[level] = i;
+
+    }
+  
+    ///Deactivate item \c i.
+
+    ///Deactivate item \c i.
+    ///\pre Item \c i must be active before.
+    void deactivate(Item i) {
+      _active.set(i, false);
+      int level = _level[i];
+
+      if (_next[i] == INVALID || !_active[_next[i]])
+	goto find_highest_level;
+
+      //unlace
+      _prev.set(_next[i], _prev[i]);
+      if (_prev[i] != INVALID) {
+	_next.set(_prev[i], _next[i]);
+      } else {
+	_first[_level[i]] = _next[i];
+      }
+      //lace
+      _prev.set(i, _last[level]);
+      _next.set(_last[level], i);
+      _next.set(i, INVALID);
+      _last[level] = i;
+      
+    find_highest_level:
+      if (level == _highest_active) {
+	while (_highest_active >= 0 && activeFree(_highest_active)) 
+	  --_highest_active;
+      }
+    }
+
+    ///Query whether item \c i is active
+    bool active(Item i) const { return _active[i]; }
+    
+    ///Return the level of item \c i.
+    int operator[](Item i) const { return _level[i]; }
+    
+    ///Return the number of items on level \c l.
+    int onLevel(int l) const {
+      int num = 0;
+      Item n = _first[l];
+      while (n != INVALID) {
+	++num;
+	n = _next[n];
+      }
+      return num;
+    }
+
+    ///Return true if the level is empty.
+    bool emptyLevel(int l) const {
+      return _first[l] == INVALID;
+    }
+
+    ///Return the number of items above level \c l.
+    int aboveLevel(int l) const {
+      int num = 0;
+      for (int level = l + 1; level < _max_level; ++level)
+	num += onLevel(level);
+      return num;
+    }
+
+    ///Return the number of active items on level \c l.
+    int activesOnLevel(int l) const {
+      int num = 0;
+      Item n = _first[l];
+      while (n != INVALID && _active[n]) {
+	++num;
+	n = _next[n];
+      }
+      return num;
+    }
+
+    ///Return true if there is not active item on level \c l.
+    bool activeFree(int l) const {
+      return _first[l] == INVALID || !_active[_first[l]];
+    }
+
+    ///Return the maximum allowed level.
+    int maxLevel() const {
+      return _max_level;
+    }    
+
+    ///\name Highest Active Item
+    ///Functions for working with the highest level
+    ///active item.
+
+    ///@{
+
+    ///Return a highest level active item.
+  
+    ///Return a highest level active item.
+    ///
+    ///\return the highest level active item or INVALID if there is no
+    ///active item.
+    Item highestActive() const {
+      return _highest_active >= 0 ? _first[_highest_active] : INVALID;
+    }
+
+    ///Return a highest active level.
+
+    ///Return a highest active level.
+    ///
+    ///\return the level of the highest active item or -1 if there is
+    ///no active item.
+    int highestActiveLevel() const {
+      return _highest_active;
+    }
+
+    ///Lift the highest active item by one.
+
+    ///Lift the item returned by highestActive() by one.
+    ///
+    void liftHighestActive() {
+      Item i = _first[_highest_active];
+      if (_next[i] != INVALID) {
+	_prev.set(_next[i], INVALID);
+	_first[_highest_active] = _next[i]; 
+      } else {
+	_first[_highest_active] = INVALID;
+	_last[_highest_active] = INVALID;
+      }
+      _level.set(i, ++_highest_active);
+      if (_first[_highest_active] == INVALID) {
+	_first[_highest_active] = i;
+	_last[_highest_active] = i;
+	_prev.set(i, INVALID);
+	_next.set(i, INVALID);
+      } else {
+	_prev.set(_first[_highest_active], i);
+	_next.set(i, _first[_highest_active]);
+	_first[_highest_active] = i;
+      }
+    }
+
+    ///Lift the highest active item.
+
+    ///Lift the item returned by highestActive() to level \c new_level.
+    ///
+    ///\warning \c new_level must be strictly higher
+    ///than the current level.
+    ///
+    void liftHighestActive(int new_level) {
+      Item i = _first[_highest_active];
+      if (_next[i] != INVALID) {
+	_prev.set(_next[i], INVALID);
+	_first[_highest_active] = _next[i]; 
+      } else {
+	_first[_highest_active] = INVALID;
+	_last[_highest_active] = INVALID;
+      }
+      _level.set(i, _highest_active = new_level);
+      if (_first[_highest_active] == INVALID) {
+	_first[_highest_active] = _last[_highest_active] = i;
+	_prev.set(i, INVALID);
+	_next.set(i, INVALID);
+      } else {
+	_prev.set(_first[_highest_active], i);
+	_next.set(i, _first[_highest_active]);
+	_first[_highest_active] = i;
+      }
+    }
+
+    ///Lift the highest active to top.
+
+    ///Lift the item returned by highestActive() to the top level and
+    ///deactivates the node.
+    ///
+    void liftHighestActiveToTop() {
+      Item i = _first[_highest_active];
+      _level.set(i, _max_level);
+      if (_next[i] != INVALID) {
+	_prev.set(_next[i], INVALID);
+	_first[_highest_active] = _next[i]; 
+      } else {
+	_first[_highest_active] = INVALID;
+	_last[_highest_active] = INVALID;
+      }
+      while (_highest_active >= 0 && activeFree(_highest_active)) 
+	--_highest_active;
+    }
+    
+    ///@}
+
+    ///\name Active Item on Certain Level 
+    ///Functions for working with the active items.
+
+    ///@{
+
+    ///Returns an active item on level \c l.
+    
+    ///Returns an active item on level \c l.
+    ///
+    ///Returns an active item on level \c l or \ref INVALID if there is no such
+    ///an item. (\c l must be from the range [0...\c max_level].
+    Item activeOn(int l) const
+    { 
+      return _active[_first[l]] ? _first[l] : INVALID;
+    }
+
+    ///Lifts the active item returned by \c activeOn() member function.
+    
+    ///Lifts the active item returned by \c activeOn() member function
+    ///by one.
+    Item liftActiveOn(int l)
+    { 
+      Item i = _first[l];
+      if (_next[i] != INVALID) {
+	_prev.set(_next[i], INVALID);
+	_first[l] = _next[i]; 
+      } else {
+	_first[l] = INVALID;
+	_last[l] = INVALID;
+      }
+      _level.set(i, ++l);
+      if (_first[l] == INVALID) {
+	_first[l] = _last[l] = i;
+	_prev.set(i, INVALID);
+	_next.set(i, INVALID);
+      } else {
+	_prev.set(_first[l], i);
+	_next.set(i, _first[l]);
+	_first[l] = i;
+      }
+      if (_highest_active < l) {
+	_highest_active = l;
+      }
+    }
+
+    /// \brief Lifts the active item returned by \c activeOn() member function.
+    ///    
+    /// Lifts the active item returned by \c activeOn() member function
+    /// to the given level.
+    void liftActiveOn(int l, int new_level)
+    { 
+      Item i = _first[l];
+      if (_next[i] != INVALID) {
+	_prev.set(_next[i], INVALID);
+	_first[l] = _next[i]; 
+      } else {
+	_first[l] = INVALID;
+	_last[l] = INVALID;
+      }
+      _level.set(i, l = new_level);
+      if (_first[l] == INVALID) {
+	_first[l] = _last[l] = i;
+	_prev.set(i, INVALID);
+	_next.set(i, INVALID);
+      } else {
+	_prev.set(_first[l], i);
+	_next.set(i, _first[l]);
+	_first[l] = i;
+      }
+      if (_highest_active < l) {
+	_highest_active = l;
+      }
+    }
+
+    ///Lifts the active item returned by \c activeOn() member function.
+    
+    ///Lifts the active item returned by \c activeOn() member function
+    ///to the top level.
+    void liftActiveToTop(int l)
+    { 
+      Item i = _first[l];
+      if (_next[i] != INVALID) {
+	_prev.set(_next[i], INVALID);
+	_first[l] = _next[i]; 
+      } else {
+	_first[l] = INVALID;
+	_last[l] = INVALID;
+      }
+      _level.set(i, _max_level);
+      if (l == _highest_active) {
+	while (_highest_active >= 0 && activeFree(_highest_active)) 
+	  --_highest_active;
+      }
+    }
+
+    ///@}
+    
+    /// \brief Lift an active item to a higher level.
+    ///
+    /// Lift an active item to a higher level.
+    /// \param i The item to be lifted. It must be active.
+    /// \param new_level The new level of \c i. It must be strictly higher
+    /// than the current level.
+    ///
+    void lift(Item i, int new_level) {
+      if (_next[i] != INVALID) {
+	_prev.set(_next[i], _prev[i]);
+      } else {
+	_last[new_level] = _prev[i];
+      }
+      if (_prev[i] != INVALID) {
+	_next.set(_prev[i], _next[i]);
+      } else {
+	_first[new_level] = _next[i];
+      }
+      _level.set(i, new_level);
+      if (_first[new_level] == INVALID) {
+	_first[new_level] = _last[new_level] = i;
+	_prev.set(i, INVALID);
+	_next.set(i, INVALID);
+      } else {
+	_prev.set(_first[new_level], i);
+	_next.set(i, _first[new_level]);
+	_first[new_level] = i;
+      }
+      if (_highest_active < new_level) {
+	_highest_active = new_level;
+      }
+    }
+    
+    ///Lift all nodes on and above a level to the top (and deactivate them).
+
+    ///This function lifts all nodes on and above level \c l to \c
+    ///maxLevel(), and also deactivates them. 
+    void liftToTop(int l)  {
+      for (int i = l + 1; _first[i] != INVALID; ++i) {
+	Item n = _first[i];
+	while (n != INVALID) {
+	  _level.set(n, _max_level);
+	  n = _next[n];
+	}
+	_first[i] = INVALID;
+	_last[i] = INVALID;
+      }
+      if (_highest_active > l - 1) {
+	_highest_active = l - 1;
+	while (_highest_active >= 0 && activeFree(_highest_active)) 
+	  --_highest_active;
+      }
+    }
+    
+  private:
+
+    int _init_level;
+
+  public:
+
+    ///\name Initialization
+    ///Using this function you can initialize the levels of the item.
+    ///\n
+    ///This initializatios is started with calling \c initStart().
+    ///Then the
+    ///items should be listed levels by levels statring with the lowest one
+    ///(with level 0). This is done by using \c initAddItem()
+    ///and \c initNewLevel(). Finally \c initFinish() must be called.
+    ///The items not listed will be put on the highest level.
+    ///@{
+
+    ///Start the initialization process.
+
+    void initStart() {
+      
+      for (int i = 0; i <= _max_level; ++i) {
+	_first[i] = _last[i] = INVALID;
+      }
+      _init_level = 0;
+      for(typename ItemSetTraits<Graph,Item>::ItemIt i(_graph); 
+	  i != INVALID; ++i) {
+	_level.set(i, _max_level);
+      }
+    }
+
+    ///Add an item to the current level.
+
+    void initAddItem(Item i) {
+      _level.set(i, _init_level);
+      if (_last[_init_level] == INVALID) {
+	_first[_init_level] = i;
+	_last[_init_level] = i;
+	_prev.set(i, INVALID);
+	_next.set(i, INVALID);
+      } else {
+	_prev.set(i, _last[_init_level]);
+	_next.set(i, INVALID);
+	_next.set(_last[_init_level], i);
+	_last[_init_level] = i;
+      }
+    }
+
+    ///Start a new level.
+
+    ///Start a new level.
+    ///It shouldn't be used before the items on level 0 are listed.
+    void initNewLevel() {
+      ++_init_level;
+    }
+
+    ///Finalize the initialization process.
+
+    void initFinish() {
+      _highest_active = -1;
     }
 
     ///@}
 
   };
 
+
 } //END OF NAMESPACE LEMON
 
 #endif

Modified: lemon/trunk/lemon/pr_bipartite_matching.h
==============================================================================
--- lemon/trunk/lemon/pr_bipartite_matching.h	(original)
+++ lemon/trunk/lemon/pr_bipartite_matching.h	Wed Nov 14 18:44:42 2007
@@ -179,7 +179,7 @@
 	}
 	if(nlevel<_node_num) {
 	  if(nlevel>=actlevel)
-	    _levels.liftHighestActiveTo(nlevel+1);
+	    _levels.liftHighestActive(nlevel+1);
 	  bact=_g.bNode(_matching[_g.aNode(bedge)]);
 	  if(--_cov[bact]<1) {
 	    _levels.activate(bact);
@@ -190,12 +190,10 @@
 	  _levels.deactivate(act);
 	}
 	else {
-	  if(_node_num>actlevel) 
-	    _levels.liftHighestActiveTo(_node_num);
-	  _levels.deactivate(act); 
+	  _levels.liftHighestActiveToTop();
 	}
 
-	if(_levels.onLevel(actlevel)==0)
+	if(_levels.emptyLevel(actlevel))
 	  _levels.liftToTop(actlevel);
       }
       
@@ -246,7 +244,7 @@
 	}
 	if(nlevel<_node_num) {
 	  if(nlevel>=actlevel)
-	    _levels.liftHighestActiveTo(nlevel+1);
+	    _levels.liftHighestActive(nlevel+1);
 	  bact=_g.bNode(_matching[_g.aNode(bedge)]);
 	  if(--_cov[bact]<1) {
 	    _levels.activate(bact);
@@ -257,12 +255,10 @@
 	  _levels.deactivate(act);
 	}
 	else {
-	  if(_node_num>actlevel) 
-	    _levels.liftHighestActiveTo(_node_num);
-	  _levels.deactivate(act); 
+	  _levels.liftHighestActiveToTop();
 	}
 
-	if(_levels.onLevel(actlevel)==0)
+	if(_levels.emptyLevel(actlevel))
 	  _empty_level=actlevel;
 	  return false;
       }



More information about the Lemon-commits mailing list