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 static_cast<int>(_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 static_cast<int>(_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 static_cast<int>(_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