1 /* -*- mode: C++; indent-tabs-mode: nil; -*-
3 * This file is a part of LEMON, a generic C++ optimization library.
5 * Copyright (C) 2003-2008
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/bits/traits.h>
34 ///Class for handling "labels" in push-relabel type algorithms.
36 ///A class for handling "labels" in push-relabel type algorithms.
39 ///Using this class you can assign "labels" (nonnegative integer numbers)
40 ///to the edges or nodes of a graph, manipulate and query them through
41 ///operations typically arising in "push-relabel" type algorithms.
43 ///Each item is either \em active or not, and you can also choose a
44 ///highest level active item.
48 ///\param Graph Type of the underlying graph.
49 ///\param Item Type of the items the data is assigned to (Graph::Node,
50 ///Graph::Arc, Graph::Edge).
51 template<class Graph, class Item>
62 typedef typename ItemSetTraits<Graph,Item>::template Map<Vit>::Type VitMap;
63 typedef typename ItemSetTraits<Graph,Item>::template Map<int>::Type IntMap;
70 std::vector<Item> _items;
71 std::vector<Vit> _first;
72 std::vector<Vit> _last_active;
76 void copy(Item i, Vit p)
80 void copy(Vit s, Vit p)
89 void swap(Vit i, Vit j)
93 _where.set(ti,_where[*i=*j]);
100 ///Constructor with given maximum level.
102 ///Constructor with given maximum level.
104 ///\param graph The underlying graph.
105 ///\param max_level The maximum allowed level.
106 ///Set the range of the possible labels to <tt>[0..max_level]</tt>.
107 Elevator(const Graph &graph,int max_level) :
109 _max_level(max_level),
110 _item_num(_max_level),
114 _first(_max_level+2),
115 _last_active(_max_level+2),
116 _highest_active(-1) {}
121 ///\param graph The underlying graph.
122 ///Set the range of the possible labels to <tt>[0..max_level]</tt>,
123 ///where \c max_level is equal to the number of labeled items in the graph.
124 Elevator(const Graph &graph) :
126 _max_level(countItems<Graph, Item>(graph)),
127 _item_num(_max_level),
131 _first(_max_level+2),
132 _last_active(_max_level+2),
137 ///Activate item \c i.
139 ///Activate item \c i.
140 ///\pre Item \c i shouldn't be active before.
141 void activate(Item i)
143 const int l=_level[i];
144 swap(_where[i],++_last_active[l]);
145 if(l>_highest_active) _highest_active=l;
148 ///Deactivate item \c i.
150 ///Deactivate item \c i.
151 ///\pre Item \c i must be active before.
152 void deactivate(Item i)
154 swap(_where[i],_last_active[_level[i]]--);
155 while(_highest_active>=0 &&
156 _last_active[_highest_active]<_first[_highest_active])
160 ///Query whether item \c i is active
161 bool active(Item i) const { return _where[i]<=_last_active[_level[i]]; }
163 ///Return the level of item \c i.
164 int operator[](Item i) const { return _level[i]; }
166 ///Return the number of items on level \c l.
167 int onLevel(int l) const
169 return _first[l+1]-_first[l];
171 ///Return true if level \c l is empty.
172 bool emptyLevel(int l) const
174 return _first[l+1]-_first[l]==0;
176 ///Return the number of items above level \c l.
177 int aboveLevel(int l) const
179 return _first[_max_level+1]-_first[l+1];
181 ///Return the number of active items on level \c l.
182 int activesOnLevel(int l) const
184 return _last_active[l]-_first[l]+1;
186 ///Return true if there is no active item on level \c l.
187 bool activeFree(int l) const
189 return _last_active[l]<_first[l];
191 ///Return the maximum allowed level.
197 ///\name Highest Active Item
198 ///Functions for working with the highest level
203 ///Return a highest level active item.
205 ///Return a highest level active item or INVALID if there is no active
207 Item highestActive() const
209 return _highest_active>=0?*_last_active[_highest_active]:INVALID;
212 ///Return the highest active level.
214 ///Return the level of the highest active item or -1 if there is no active
216 int highestActiveLevel() const
218 return _highest_active;
221 ///Lift the highest active item by one.
223 ///Lift the item returned by highestActive() by one.
225 void liftHighestActive()
227 Item it = *_last_active[_highest_active];
228 _level.set(it,_level[it]+1);
229 swap(_last_active[_highest_active]--,_last_active[_highest_active+1]);
230 --_first[++_highest_active];
233 ///Lift the highest active item to the given level.
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.set(li,new_level);
252 _highest_active=new_level;
255 ///Lift the highest active item to the top level.
257 ///Lift the item returned by highestActive() to the top level and
259 void liftHighestActiveToTop()
261 const Item li = *_last_active[_highest_active];
263 copy(--_first[_highest_active+1],_last_active[_highest_active]--);
264 for(int l=_highest_active+1;l<_max_level;l++)
266 copy(--_first[l+1],_first[l]);
269 copy(li,_first[_max_level]);
270 --_last_active[_max_level];
271 _level.set(li,_max_level);
273 while(_highest_active>=0 &&
274 _last_active[_highest_active]<_first[_highest_active])
280 ///\name Active Item on Certain Level
281 ///Functions for working with the active items.
285 ///Return an active item on level \c l.
287 ///Return an active item on level \c l or \ref INVALID if there is no such
288 ///an item. (\c l must be from the range [0...\c max_level].
289 Item activeOn(int l) const
291 return _last_active[l]>=_first[l]?*_last_active[l]:INVALID;
294 ///Lift the active item returned by \c activeOn(level) by one.
296 ///Lift the active item returned by \ref activeOn() "activeOn(level)"
298 Item liftActiveOn(int level)
300 Item it =*_last_active[level];
301 _level.set(it,_level[it]+1);
302 swap(_last_active[level]--, --_first[level+1]);
303 if (level+1>_highest_active) ++_highest_active;
306 ///Lift the active item returned by \c activeOn(level) to the given level.
308 ///Lift the active item returned by \ref activeOn() "activeOn(level)"
309 ///to the given level.
310 void liftActiveOn(int level, int new_level)
312 const Item ai = *_last_active[level];
314 copy(--_first[level+1], _last_active[level]--);
315 for(int l=level+1;l<new_level;l++)
317 copy(_last_active[l],_first[l]);
318 copy(--_first[l+1], _last_active[l]--);
320 copy(ai,_first[new_level]);
321 _level.set(ai,new_level);
322 if (new_level>_highest_active) _highest_active=new_level;
325 ///Lift the active item returned by \c activeOn(level) to the top level.
327 ///Lift the active item returned by \ref activeOn() "activeOn(level)"
328 ///to the top level and deactivate it.
329 void liftActiveToTop(int level)
331 const Item ai = *_last_active[level];
333 copy(--_first[level+1],_last_active[level]--);
334 for(int l=level+1;l<_max_level;l++)
336 copy(_last_active[l],_first[l]);
337 copy(--_first[l+1], _last_active[l]--);
339 copy(ai,_first[_max_level]);
340 --_last_active[_max_level];
341 _level.set(ai,_max_level);
343 if (_highest_active==level) {
344 while(_highest_active>=0 &&
345 _last_active[_highest_active]<_first[_highest_active])
352 ///Lift an active item to a higher level.
354 ///Lift an active item to a higher level.
355 ///\param i The item to be lifted. It must be active.
356 ///\param new_level The new level of \c i. It must be strictly higher
357 ///than the current level.
359 void lift(Item i, int new_level)
361 const int lo = _level[i];
362 const Vit w = _where[i];
364 copy(_last_active[lo],w);
365 copy(--_first[lo+1],_last_active[lo]--);
366 for(int l=lo+1;l<new_level;l++)
368 copy(_last_active[l],_first[l]);
369 copy(--_first[l+1],_last_active[l]--);
371 copy(i,_first[new_level]);
372 _level.set(i,new_level);
373 if(new_level>_highest_active) _highest_active=new_level;
376 ///Move an inactive item to the top but one level (in a dirty way).
378 ///This function moves an inactive item from the top level to the top
379 ///but one level (in a dirty way).
380 ///\warning It makes the underlying datastructure corrupt, so use it
381 ///only if you really know what it is for.
382 ///\pre The item is on the top level.
383 void dirtyTopButOne(Item i) {
384 _level.set(i,_max_level - 1);
387 ///Lift all items on and above the given level to the top level.
389 ///This function lifts all items on and above level \c l to the top
390 ///level and deactivates them.
391 void liftToTop(int l)
393 const Vit f=_first[l];
394 const Vit tl=_first[_max_level];
395 for(Vit i=f;i!=tl;++i)
396 _level.set(*i,_max_level);
397 for(int i=l;i<=_max_level;i++)
402 for(_highest_active=l-1;
403 _highest_active>=0 &&
404 _last_active[_highest_active]<_first[_highest_active];
414 ///\name Initialization
415 ///Using these functions you can initialize the levels of the items.
417 ///The initialization must be started with calling \c initStart().
418 ///Then the items should be listed level by level starting with the
419 ///lowest one (level 0) using \c initAddItem() and \c initNewLevel().
420 ///Finally \c initFinish() must be called.
421 ///The items not listed are put on the highest level.
424 ///Start the initialization process.
428 _init_num=&_items[0];
429 _first[0]=&_items[0];
430 _last_active[0]=&_items[0]-1;
432 for(typename ItemSetTraits<Graph,Item>::ItemIt i(_g);i!=INVALID;++i)
436 _level.set(i,_max_level);
441 ///Add an item to the current level.
442 void initAddItem(Item i)
444 swap(_where[i],_init_num);
445 _level.set(i,_init_lev);
449 ///Start a new level.
451 ///Start a new level.
452 ///It shouldn't be used before the items on level 0 are listed.
456 _first[_init_lev]=_init_num;
457 _last_active[_init_lev]=_init_num-1;
460 ///Finalize the initialization process.
463 for(_init_lev++;_init_lev<=_max_level;_init_lev++)
465 _first[_init_lev]=_init_num;
466 _last_active[_init_lev]=_init_num-1;
468 _first[_max_level+1]=&_items[0]+_item_num;
469 _last_active[_max_level+1]=&_items[0]+_item_num-1;
470 _highest_active = -1;
477 ///Class for handling "labels" in push-relabel type algorithms.
479 ///A class for handling "labels" in push-relabel type algorithms.
482 ///Using this class you can assign "labels" (nonnegative integer numbers)
483 ///to the edges or nodes of a graph, manipulate and query them through
484 ///operations typically arising in "push-relabel" type algorithms.
486 ///Each item is either \em active or not, and you can also choose a
487 ///highest level active item.
491 ///\param Graph Type of the underlying graph.
492 ///\param Item Type of the items the data is assigned to (Graph::Node,
493 ///Graph::Arc, Graph::Edge).
494 template <class Graph, class Item>
495 class LinkedElevator {
503 typedef typename ItemSetTraits<Graph,Item>::
504 template Map<Item>::Type ItemMap;
505 typedef typename ItemSetTraits<Graph,Item>::
506 template Map<int>::Type IntMap;
507 typedef typename ItemSetTraits<Graph,Item>::
508 template Map<bool>::Type BoolMap;
513 std::vector<Item> _first, _last;
514 ItemMap _prev, _next;
520 ///Constructor with given maximum level.
522 ///Constructor with given maximum level.
524 ///\param graph The underlying graph.
525 ///\param max_level The maximum allowed level.
526 ///Set the range of the possible labels to <tt>[0..max_level]</tt>.
527 LinkedElevator(const Graph& graph, int max_level)
528 : _graph(graph), _max_level(max_level), _item_num(_max_level),
529 _first(_max_level + 1), _last(_max_level + 1),
530 _prev(graph), _next(graph),
531 _highest_active(-1), _level(graph), _active(graph) {}
537 ///\param graph The underlying graph.
538 ///Set the range of the possible labels to <tt>[0..max_level]</tt>,
539 ///where \c max_level is equal to the number of labeled items in the graph.
540 LinkedElevator(const Graph& graph)
541 : _graph(graph), _max_level(countItems<Graph, Item>(graph)),
542 _item_num(_max_level),
543 _first(_max_level + 1), _last(_max_level + 1),
544 _prev(graph, INVALID), _next(graph, INVALID),
545 _highest_active(-1), _level(graph), _active(graph) {}
548 ///Activate item \c i.
550 ///Activate item \c i.
551 ///\pre Item \c i shouldn't be active before.
552 void activate(Item i) {
553 _active.set(i, true);
555 int level = _level[i];
556 if (level > _highest_active) {
557 _highest_active = level;
560 if (_prev[i] == INVALID || _active[_prev[i]]) return;
562 _next.set(_prev[i], _next[i]);
563 if (_next[i] != INVALID) {
564 _prev.set(_next[i], _prev[i]);
566 _last[level] = _prev[i];
569 _next.set(i, _first[level]);
570 _prev.set(_first[level], i);
571 _prev.set(i, INVALID);
576 ///Deactivate item \c i.
578 ///Deactivate item \c i.
579 ///\pre Item \c i must be active before.
580 void deactivate(Item i) {
581 _active.set(i, false);
582 int level = _level[i];
584 if (_next[i] == INVALID || !_active[_next[i]])
585 goto find_highest_level;
588 _prev.set(_next[i], _prev[i]);
589 if (_prev[i] != INVALID) {
590 _next.set(_prev[i], _next[i]);
592 _first[_level[i]] = _next[i];
595 _prev.set(i, _last[level]);
596 _next.set(_last[level], i);
597 _next.set(i, INVALID);
601 if (level == _highest_active) {
602 while (_highest_active >= 0 && activeFree(_highest_active))
607 ///Query whether item \c i is active
608 bool active(Item i) const { return _active[i]; }
610 ///Return the level of item \c i.
611 int operator[](Item i) const { return _level[i]; }
613 ///Return the number of items on level \c l.
614 int onLevel(int l) const {
617 while (n != INVALID) {
624 ///Return true if the level is empty.
625 bool emptyLevel(int l) const {
626 return _first[l] == INVALID;
629 ///Return the number of items above level \c l.
630 int aboveLevel(int l) const {
632 for (int level = l + 1; level < _max_level; ++level)
633 num += onLevel(level);
637 ///Return the number of active items on level \c l.
638 int activesOnLevel(int l) const {
641 while (n != INVALID && _active[n]) {
648 ///Return true if there is no active item on level \c l.
649 bool activeFree(int l) const {
650 return _first[l] == INVALID || !_active[_first[l]];
653 ///Return the maximum allowed level.
654 int maxLevel() const {
658 ///\name Highest Active Item
659 ///Functions for working with the highest level
664 ///Return a highest level active item.
666 ///Return a highest level active item or INVALID if there is no active
668 Item highestActive() const {
669 return _highest_active >= 0 ? _first[_highest_active] : INVALID;
672 ///Return the highest active level.
674 ///Return the level of the highest active item or -1 if there is no active
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 to the given level.
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 item to the top level.
736 ///Lift the item returned by highestActive() to the top level and
738 void liftHighestActiveToTop() {
739 Item i = _first[_highest_active];
740 _level.set(i, _max_level);
741 if (_next[i] != INVALID) {
742 _prev.set(_next[i], INVALID);
743 _first[_highest_active] = _next[i];
745 _first[_highest_active] = INVALID;
746 _last[_highest_active] = INVALID;
748 while (_highest_active >= 0 && activeFree(_highest_active))
754 ///\name Active Item on Certain Level
755 ///Functions for working with the active items.
759 ///Return an active item on level \c l.
761 ///Return an active item on level \c l or \ref INVALID if there is no such
762 ///an item. (\c l must be from the range [0...\c max_level].
763 Item activeOn(int l) const
765 return _active[_first[l]] ? _first[l] : INVALID;
768 ///Lift the active item returned by \c activeOn(l) by one.
770 ///Lift the active item returned by \ref activeOn() "activeOn(l)"
772 Item liftActiveOn(int l)
775 if (_next[i] != INVALID) {
776 _prev.set(_next[i], INVALID);
777 _first[l] = _next[i];
783 if (_first[l] == INVALID) {
784 _first[l] = _last[l] = i;
785 _prev.set(i, INVALID);
786 _next.set(i, INVALID);
788 _prev.set(_first[l], i);
789 _next.set(i, _first[l]);
792 if (_highest_active < l) {
797 ///Lift the active item returned by \c activeOn(l) to the given level.
799 ///Lift the active item returned by \ref activeOn() "activeOn(l)"
800 ///to the given level.
801 void liftActiveOn(int l, int new_level)
804 if (_next[i] != INVALID) {
805 _prev.set(_next[i], INVALID);
806 _first[l] = _next[i];
811 _level.set(i, l = new_level);
812 if (_first[l] == INVALID) {
813 _first[l] = _last[l] = i;
814 _prev.set(i, INVALID);
815 _next.set(i, INVALID);
817 _prev.set(_first[l], i);
818 _next.set(i, _first[l]);
821 if (_highest_active < l) {
826 ///Lift the active item returned by \c activeOn(l) to the top level.
828 ///Lift the active item returned by \ref activeOn() "activeOn(l)"
829 ///to the top level and deactivate it.
830 void liftActiveToTop(int l)
833 if (_next[i] != INVALID) {
834 _prev.set(_next[i], INVALID);
835 _first[l] = _next[i];
840 _level.set(i, _max_level);
841 if (l == _highest_active) {
842 while (_highest_active >= 0 && activeFree(_highest_active))
849 /// \brief Lift an active item to a higher level.
851 /// Lift an active item to a higher level.
852 /// \param i The item to be lifted. It must be active.
853 /// \param new_level The new level of \c i. It must be strictly higher
854 /// than the current level.
856 void lift(Item i, int new_level) {
857 if (_next[i] != INVALID) {
858 _prev.set(_next[i], _prev[i]);
860 _last[new_level] = _prev[i];
862 if (_prev[i] != INVALID) {
863 _next.set(_prev[i], _next[i]);
865 _first[new_level] = _next[i];
867 _level.set(i, new_level);
868 if (_first[new_level] == INVALID) {
869 _first[new_level] = _last[new_level] = i;
870 _prev.set(i, INVALID);
871 _next.set(i, INVALID);
873 _prev.set(_first[new_level], i);
874 _next.set(i, _first[new_level]);
875 _first[new_level] = i;
877 if (_highest_active < new_level) {
878 _highest_active = new_level;
882 ///Move an inactive item to the top but one level (in a dirty way).
884 ///This function moves an inactive item from the top level to the top
885 ///but one level (in a dirty way).
886 ///\warning It makes the underlying datastructure corrupt, so use it
887 ///only if you really know what it is for.
888 ///\pre The item is on the top level.
889 void dirtyTopButOne(Item i) {
890 _level.set(i, _max_level - 1);
893 ///Lift all items on and above the given level to the top level.
895 ///This function lifts all items on and above level \c l to the top
896 ///level and deactivates them.
897 void liftToTop(int l) {
898 for (int i = l + 1; _first[i] != INVALID; ++i) {
900 while (n != INVALID) {
901 _level.set(n, _max_level);
907 if (_highest_active > l - 1) {
908 _highest_active = l - 1;
909 while (_highest_active >= 0 && activeFree(_highest_active))
920 ///\name Initialization
921 ///Using these functions you can initialize the levels of the items.
923 ///The initialization must be started with calling \c initStart().
924 ///Then the items should be listed level by level starting with the
925 ///lowest one (level 0) using \c initAddItem() and \c initNewLevel().
926 ///Finally \c initFinish() must be called.
927 ///The items not listed are put on the highest level.
930 ///Start the initialization process.
933 for (int i = 0; i <= _max_level; ++i) {
934 _first[i] = _last[i] = INVALID;
937 for(typename ItemSetTraits<Graph,Item>::ItemIt i(_graph);
939 _level.set(i, _max_level);
940 _active.set(i, false);
944 ///Add an item to the current level.
945 void initAddItem(Item i) {
946 _level.set(i, _init_level);
947 if (_last[_init_level] == INVALID) {
948 _first[_init_level] = i;
949 _last[_init_level] = i;
950 _prev.set(i, INVALID);
951 _next.set(i, INVALID);
953 _prev.set(i, _last[_init_level]);
954 _next.set(i, INVALID);
955 _next.set(_last[_init_level], i);
956 _last[_init_level] = i;
960 ///Start a new level.
962 ///Start a new level.
963 ///It shouldn't be used before the items on level 0 are listed.
964 void initNewLevel() {
968 ///Finalize the initialization process.
970 _highest_active = -1;
978 } //END OF NAMESPACE LEMON