3 * This file is a part of LEMON, a generic C++ optimization library
5 * Copyright (C) 2003-2007
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 <test/test_tools.h>
33 ///Class for handling "labels" in push-relabel type algorithms.
35 ///A class for handling "labels" in push-relabel type algorithms.
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.
42 ///Each item is either \em active or not, and you can also choose a
43 ///highest level active item.
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>
58 typedef typename std::vector<Item>::iterator Vit;
59 typedef typename ItemSetTraits<Graph,Item>::template Map<Vit>::Type VitMap;
60 typedef typename ItemSetTraits<Graph,Item>::template Map<int>::Type IntMap;
67 std::vector<Item> _items;
68 std::vector<Vit> _first;
69 std::vector<Vit> _last_active;
73 void copy(Item i, Vit p)
77 void copy(Vit s, Vit p)
86 void swap(Vit i, Vit j)
90 _where[ti]=_where[*i=*j];
97 ///Constructor with given maximum level.
99 ///Constructor with given maximum level.
101 ///\param g The underlying graph
102 ///\param max_level Set the range of the possible labels to
103 ///[0...\c max_level]
104 Elevator(const Graph &g,int max_level) :
106 _max_level(max_level),
107 _item_num(_max_level),
111 _first(_max_level+2),
112 _last_active(_max_level+2),
113 _highest_active(-1) {}
118 ///\param g The underlying graph
119 ///The range of the possible labels is [0...\c max_level],
120 ///where \c max_level is equal to the number of labeled items in the graph.
121 Elevator(const Graph &g) :
123 _max_level(countItems<Graph, Item>(g)),
124 _item_num(_max_level),
128 _first(_max_level+2),
129 _last_active(_max_level+2),
134 ///Activate item \c i.
136 ///Activate item \c i.
137 ///\pre Item \c i shouldn't be active before.
138 void activate(Item i)
140 const int l=_level[i];
141 swap(_where[i],++_last_active[l]);
142 if(l>_highest_active) _highest_active=l;
145 ///Deactivate item \c i.
147 ///Deactivate item \c i.
148 ///\pre Item \c i must be active before.
149 void deactivate(Item i)
151 swap(_where[i],_last_active[_level[i]]--);
152 while(_highest_active>=0 &&
153 _last_active[_highest_active]<_first[_highest_active])
157 ///Query whether item \c i is active
158 bool active(Item i) const { return _where[i]<=_last_active[_level[i]]; }
160 ///Return the level of item \c i.
161 int operator[](Item i) const { return _level[i]; }
163 ///Return the number of items on level \c l.
164 int onLevel(int l) const
166 return _first[l+1]-_first[l];
168 ///Return true if the level is empty.
169 bool emptyLevel(int l) const
171 return _first[l+1]-_first[l]==0;
173 ///Return the number of items above level \c l.
174 int aboveLevel(int l) const
176 return _first[_max_level+1]-_first[l+1];
178 ///Return the number of active items on level \c l.
179 int activesOnLevel(int l) const
181 return _last_active[l]-_first[l]+1;
183 ///Return true if there is not active item on level \c l.
184 bool activeFree(int l) const
186 return _last_active[l]<_first[l];
188 ///Return the maximum allowed level.
194 ///\name Highest Active Item
195 ///Functions for working with the highest level
200 ///Return a highest level active item.
202 ///Return a highest level active item.
204 ///\return the highest level active item or INVALID if there is no active
206 Item highestActive() const
208 return _highest_active>=0?*_last_active[_highest_active]:INVALID;
211 ///Return a highest active level.
213 ///Return a 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 ++_level[*_last_active[_highest_active]];
229 swap(_last_active[_highest_active]--,_last_active[_highest_active+1]);
230 --_first[++_highest_active];
233 ///Lift the highest active item.
235 ///Lift the item returned by highestActive() to level \c new_level.
237 ///\warning \c new_level must be strictly higher
238 ///than the current level.
240 void liftHighestActive(int new_level)
242 const Item li = *_last_active[_highest_active];
244 copy(--_first[_highest_active+1],_last_active[_highest_active]--);
245 for(int l=_highest_active+1;l<new_level;l++)
247 copy(--_first[l+1],_first[l]);
250 copy(li,_first[new_level]);
251 _level[li]=new_level;
252 _highest_active=new_level;
255 ///Lift the highest active item.
257 ///Lift the item returned by highestActive() to the top level and
260 ///\warning \c new_level must be strictly higher
261 ///than the current level.
263 void liftHighestActiveToTop()
265 const Item li = *_last_active[_highest_active];
267 copy(--_first[_highest_active+1],_last_active[_highest_active]--);
268 for(int l=_highest_active+1;l<_max_level;l++)
270 copy(--_first[l+1],_first[l]);
273 copy(li,_first[_max_level]);
274 --_last_active[_max_level];
275 _level[li]=_max_level;
277 while(_highest_active>=0 &&
278 _last_active[_highest_active]<_first[_highest_active])
284 ///\name Active Item on Certain Level
285 ///Functions for working with the active items.
289 ///Returns an active item on level \c l.
291 ///Returns an active item on level \c l.
293 ///Returns an active item on level \c l or \ref INVALID if there is no such
294 ///an item. (\c l must be from the range [0...\c max_level].
295 Item activeOn(int l) const
297 return _last_active[l]>=_first[l]?*_last_active[l]:INVALID;
300 ///Lifts the active item returned by \c activeOn() member function.
302 ///Lifts the active item returned by \c activeOn() member function
304 Item liftActiveOn(int level)
306 ++_level[*_last_active[level]];
307 swap(_last_active[level]--, --_first[level+1]);
308 if (level+1>_highest_active) ++_highest_active;
311 ///Lifts the active item returned by \c activeOn() member function.
313 ///Lifts the active item returned by \c activeOn() member function
314 ///to the given level.
315 void liftActiveOn(int level, int new_level)
317 const Item ai = *_last_active[level];
319 copy(--_first[level+1], _last_active[level]--);
320 for(int l=level+1;l<new_level;l++)
322 copy(_last_active[l],_first[l]);
323 copy(--_first[l+1], _last_active[l]--);
325 copy(ai,_first[new_level]);
326 _level[ai]=new_level;
327 if (new_level>_highest_active) _highest_active=new_level;
330 ///Lifts the active item returned by \c activeOn() member function.
332 ///Lifts the active item returned by \c activeOn() member function
334 void liftActiveToTop(int level)
336 const Item ai = *_last_active[level];
338 copy(--_first[level+1],_last_active[level]--);
339 for(int l=level+1;l<_max_level;l++)
341 copy(_last_active[l],_first[l]);
342 copy(--_first[l+1], _last_active[l]--);
344 copy(ai,_first[_max_level]);
345 --_last_active[_max_level];
346 _level[ai]=_max_level;
348 if (_highest_active==level) {
349 while(_highest_active>=0 &&
350 _last_active[_highest_active]<_first[_highest_active])
357 ///Lift an active item to a higher level.
359 ///Lift an active item to a higher level.
360 ///\param i The item to be lifted. It must be active.
361 ///\param new_level The new level of \c i. It must be strictly higher
362 ///than the current level.
364 void lift(Item i, int new_level)
366 const int lo = _level[i];
367 const Vit w = _where[i];
369 copy(_last_active[lo],w);
370 copy(--_first[lo+1],_last_active[lo]--);
371 for(int l=lo+1;l<new_level;l++)
373 copy(_last_active[l],_first[l]);
374 copy(--_first[l+1],_last_active[l]--);
376 copy(i,_first[new_level]);
378 if(new_level>_highest_active) _highest_active=new_level;
381 ///Lift all nodes on and above a level to the top (and deactivate them).
383 ///This function lifts all nodes on and above level \c l to \c
384 ///maxLevel(), and also deactivates them.
385 void liftToTop(int l)
387 const Vit f=_first[l];
388 const Vit tl=_first[_max_level];
389 for(Vit i=f;i!=tl;++i)
390 _level[*i]=_max_level;
391 for(int i=l;i<=_max_level;i++)
396 for(_highest_active=l-1;
397 _highest_active>=0 &&
398 _last_active[_highest_active]<_first[_highest_active];
408 ///\name Initialization
409 ///Using this function you can initialize the levels of the item.
411 ///This initializatios is started with calling \c initStart().
413 ///items should be listed levels by levels statring with the lowest one
414 ///(with level 0). This is done by using \c initAddItem()
415 ///and \c initNewLevel(). Finally \c initFinish() must be called.
416 ///The items not listed will be put on the highest level.
419 ///Start the initialization process.
424 _init_num=_items.begin();
425 _first[0]=_items.begin();
426 _last_active[0]=_items.begin()-1;
427 Vit n=_items.begin();
428 for(typename ItemSetTraits<Graph,Item>::ItemIt i(_g);i!=INVALID;++i)
432 _level[i]=_max_level;
437 ///Add an item to the current level.
439 void initAddItem(Item i)
441 swap(_where[i],_init_num);
446 ///Start a new level.
448 ///Start a new level.
449 ///It shouldn't be used before the items on level 0 are listed.
453 _first[_init_lev]=_init_num;
454 _last_active[_init_lev]=_init_num-1;
457 ///Finalize the initialization process.
461 for(_init_lev++;_init_lev<=_max_level;_init_lev++)
463 _first[_init_lev]=_init_num;
464 _last_active[_init_lev]=_init_num-1;
466 _first[_max_level+1]=_items.begin()+_item_num;
467 _last_active[_max_level+1]=_items.begin()+_item_num-1;
468 _highest_active = -1;
475 ///Class for handling "labels" in push-relabel type algorithms.
477 ///A class for handling "labels" in push-relabel type algorithms.
480 ///Using this class you can assign "labels" (nonnegative integer numbers)
481 ///to the edges or nodes of a graph, manipulate and query them through
482 ///operations typically arising in "push-relabel" type algorithms.
484 ///Each item is either \em active or not, and you can also choose a
485 ///highest level active item.
489 ///\param Graph the underlying graph type
490 ///\param Item Type of the items the data is assigned to (Graph::Node,
491 ///Graph::Edge, Graph::UEdge)
492 template <class Graph, class Item>
493 class LinkedElevator {
499 typedef typename ItemSetTraits<Graph,Item>::
500 template Map<Item>::Type ItemMap;
501 typedef typename ItemSetTraits<Graph,Item>::
502 template Map<int>::Type IntMap;
503 typedef typename ItemSetTraits<Graph,Item>::
504 template Map<bool>::Type BoolMap;
509 std::vector<Item> _first, _last;
510 ItemMap _prev, _next;
516 ///Constructor with given maximum level.
518 ///Constructor with given maximum level.
520 ///\param g The underlying graph
521 ///\param max_level Set the range of the possible labels to
522 ///[0...\c max_level]
523 LinkedElevator(const Graph& graph, int max_level)
524 : _graph(graph), _max_level(max_level), _item_num(_max_level),
525 _first(_max_level + 1), _last(_max_level + 1),
526 _prev(graph), _next(graph),
527 _highest_active(-1), _level(graph), _active(graph) {}
533 ///\param g The underlying graph
534 ///The range of the possible labels is [0...\c max_level],
535 ///where \c max_level is equal to the number of labeled items in the graph.
536 LinkedElevator(const Graph& graph)
537 : _graph(graph), _max_level(countItems<Graph, Item>(graph)),
538 _item_num(_max_level),
539 _first(_max_level + 1), _last(_max_level + 1),
540 _prev(graph, INVALID), _next(graph, INVALID),
541 _highest_active(-1), _level(graph), _active(graph) {}
544 ///Activate item \c i.
546 ///Activate item \c i.
547 ///\pre Item \c i shouldn't be active before.
548 void activate(Item i) {
549 _active.set(i, true);
551 int level = _level[i];
552 if (level > _highest_active) {
553 _highest_active = level;
556 if (_prev[i] == INVALID || _active[_prev[i]]) return;
558 _next.set(_prev[i], _next[i]);
559 if (_next[i] != INVALID) {
560 _prev.set(_next[i], _prev[i]);
562 _last[level] = _prev[i];
565 _next.set(i, _first[level]);
566 _prev.set(_first[level], i);
567 _prev.set(i, INVALID);
572 ///Deactivate item \c i.
574 ///Deactivate item \c i.
575 ///\pre Item \c i must be active before.
576 void deactivate(Item i) {
577 _active.set(i, false);
578 int level = _level[i];
580 if (_next[i] == INVALID || !_active[_next[i]])
581 goto find_highest_level;
584 _prev.set(_next[i], _prev[i]);
585 if (_prev[i] != INVALID) {
586 _next.set(_prev[i], _next[i]);
588 _first[_level[i]] = _next[i];
591 _prev.set(i, _last[level]);
592 _next.set(_last[level], i);
593 _next.set(i, INVALID);
597 if (level == _highest_active) {
598 while (_highest_active >= 0 && activeFree(_highest_active))
603 ///Query whether item \c i is active
604 bool active(Item i) const { return _active[i]; }
606 ///Return the level of item \c i.
607 int operator[](Item i) const { return _level[i]; }
609 ///Return the number of items on level \c l.
610 int onLevel(int l) const {
613 while (n != INVALID) {
620 ///Return true if the level is empty.
621 bool emptyLevel(int l) const {
622 return _first[l] == INVALID;
625 ///Return the number of items above level \c l.
626 int aboveLevel(int l) const {
628 for (int level = l + 1; level < _max_level; ++level)
629 num += onLevel(level);
633 ///Return the number of active items on level \c l.
634 int activesOnLevel(int l) const {
637 while (n != INVALID && _active[n]) {
644 ///Return true if there is not active item on level \c l.
645 bool activeFree(int l) const {
646 return _first[l] == INVALID || !_active[_first[l]];
649 ///Return the maximum allowed level.
650 int maxLevel() const {
654 ///\name Highest Active Item
655 ///Functions for working with the highest level
660 ///Return a highest level active item.
662 ///Return a highest level active item.
664 ///\return the highest level active item or INVALID if there is no
666 Item highestActive() const {
667 return _highest_active >= 0 ? _first[_highest_active] : INVALID;
670 ///Return a highest active level.
672 ///Return a highest active level.
674 ///\return the level of the highest active item or -1 if there is
676 int highestActiveLevel() const {
677 return _highest_active;
680 ///Lift the highest active item by one.
682 ///Lift the item returned by highestActive() by one.
684 void liftHighestActive() {
685 Item i = _first[_highest_active];
686 if (_next[i] != INVALID) {
687 _prev.set(_next[i], INVALID);
688 _first[_highest_active] = _next[i];
690 _first[_highest_active] = INVALID;
691 _last[_highest_active] = INVALID;
693 _level.set(i, ++_highest_active);
694 if (_first[_highest_active] == INVALID) {
695 _first[_highest_active] = i;
696 _last[_highest_active] = i;
697 _prev.set(i, INVALID);
698 _next.set(i, INVALID);
700 _prev.set(_first[_highest_active], i);
701 _next.set(i, _first[_highest_active]);
702 _first[_highest_active] = i;
706 ///Lift the highest active item.
708 ///Lift the item returned by highestActive() to level \c new_level.
710 ///\warning \c new_level must be strictly higher
711 ///than the current level.
713 void liftHighestActive(int new_level) {
714 Item i = _first[_highest_active];
715 if (_next[i] != INVALID) {
716 _prev.set(_next[i], INVALID);
717 _first[_highest_active] = _next[i];
719 _first[_highest_active] = INVALID;
720 _last[_highest_active] = INVALID;
722 _level.set(i, _highest_active = new_level);
723 if (_first[_highest_active] == INVALID) {
724 _first[_highest_active] = _last[_highest_active] = i;
725 _prev.set(i, INVALID);
726 _next.set(i, INVALID);
728 _prev.set(_first[_highest_active], i);
729 _next.set(i, _first[_highest_active]);
730 _first[_highest_active] = i;
734 ///Lift the highest active to top.
736 ///Lift the item returned by highestActive() to the top level and
737 ///deactivates the node.
739 void liftHighestActiveToTop() {
740 Item i = _first[_highest_active];
741 _level.set(i, _max_level);
742 if (_next[i] != INVALID) {
743 _prev.set(_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 ///Returns an active item on level \c l.
762 ///Returns an active item on level \c l.
764 ///Returns an active item on level \c l or \ref INVALID if there is no such
765 ///an item. (\c l must be from the range [0...\c max_level].
766 Item activeOn(int l) const
768 return _active[_first[l]] ? _first[l] : INVALID;
771 ///Lifts the active item returned by \c activeOn() member function.
773 ///Lifts the active item returned by \c activeOn() member function
775 Item liftActiveOn(int l)
778 if (_next[i] != INVALID) {
779 _prev.set(_next[i], INVALID);
780 _first[l] = _next[i];
786 if (_first[l] == INVALID) {
787 _first[l] = _last[l] = i;
788 _prev.set(i, INVALID);
789 _next.set(i, INVALID);
791 _prev.set(_first[l], i);
792 _next.set(i, _first[l]);
795 if (_highest_active < l) {
800 /// \brief Lifts the active item returned by \c activeOn() member function.
802 /// Lifts the active item returned by \c activeOn() member function
803 /// to the given level.
804 void liftActiveOn(int l, int new_level)
807 if (_next[i] != INVALID) {
808 _prev.set(_next[i], INVALID);
809 _first[l] = _next[i];
814 _level.set(i, l = new_level);
815 if (_first[l] == INVALID) {
816 _first[l] = _last[l] = i;
817 _prev.set(i, INVALID);
818 _next.set(i, INVALID);
820 _prev.set(_first[l], i);
821 _next.set(i, _first[l]);
824 if (_highest_active < l) {
829 ///Lifts the active item returned by \c activeOn() member function.
831 ///Lifts the active item returned by \c activeOn() member function
833 void liftActiveToTop(int l)
836 if (_next[i] != INVALID) {
837 _prev.set(_next[i], INVALID);
838 _first[l] = _next[i];
843 _level.set(i, _max_level);
844 if (l == _highest_active) {
845 while (_highest_active >= 0 && activeFree(_highest_active))
852 /// \brief Lift an active item to a higher level.
854 /// Lift an active item to a higher level.
855 /// \param i The item to be lifted. It must be active.
856 /// \param new_level The new level of \c i. It must be strictly higher
857 /// than the current level.
859 void lift(Item i, int new_level) {
860 if (_next[i] != INVALID) {
861 _prev.set(_next[i], _prev[i]);
863 _last[new_level] = _prev[i];
865 if (_prev[i] != INVALID) {
866 _next.set(_prev[i], _next[i]);
868 _first[new_level] = _next[i];
870 _level.set(i, new_level);
871 if (_first[new_level] == INVALID) {
872 _first[new_level] = _last[new_level] = i;
873 _prev.set(i, INVALID);
874 _next.set(i, INVALID);
876 _prev.set(_first[new_level], i);
877 _next.set(i, _first[new_level]);
878 _first[new_level] = i;
880 if (_highest_active < new_level) {
881 _highest_active = new_level;
885 ///Lift all nodes on and above a level to the top (and deactivate them).
887 ///This function lifts all nodes on and above level \c l to \c
888 ///maxLevel(), and also deactivates them.
889 void liftToTop(int l) {
890 for (int i = l + 1; _first[i] != INVALID; ++i) {
892 while (n != INVALID) {
893 _level.set(n, _max_level);
899 if (_highest_active > l - 1) {
900 _highest_active = l - 1;
901 while (_highest_active >= 0 && activeFree(_highest_active))
912 ///\name Initialization
913 ///Using this function you can initialize the levels of the item.
915 ///This initializatios is started with calling \c initStart().
917 ///items should be listed levels by levels statring with the lowest one
918 ///(with level 0). This is done by using \c initAddItem()
919 ///and \c initNewLevel(). Finally \c initFinish() must be called.
920 ///The items not listed will be put on the highest level.
923 ///Start the initialization process.
927 for (int i = 0; i <= _max_level; ++i) {
928 _first[i] = _last[i] = INVALID;
931 for(typename ItemSetTraits<Graph,Item>::ItemIt i(_graph);
933 _level.set(i, _max_level);
937 ///Add an item to the current level.
939 void initAddItem(Item i) {
940 _level.set(i, _init_level);
941 if (_last[_init_level] == INVALID) {
942 _first[_init_level] = i;
943 _last[_init_level] = i;
944 _prev.set(i, INVALID);
945 _next.set(i, INVALID);
947 _prev.set(i, _last[_init_level]);
948 _next.set(i, INVALID);
949 _next.set(_last[_init_level], i);
950 _last[_init_level] = i;
954 ///Start a new level.
956 ///Start a new level.
957 ///It shouldn't be used before the items on level 0 are listed.
958 void initNewLevel() {
962 ///Finalize the initialization process.
965 _highest_active = -1;
973 } //END OF NAMESPACE LEMON