[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