0
                         5
                         3
                     
                 
                    468
903
7
| 1 | 
		/* -*- mode: C++; indent-tabs-mode: nil; -*-  | 
|
| 2 | 
		*  | 
|
| 3 | 
		* This file is a part of LEMON, a generic C++ optimization library.  | 
|
| 4 | 
		*  | 
|
| 5 | 
		* Copyright (C) 2003-2009  | 
|
| 6 | 
		* Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport  | 
|
| 7 | 
		* (Egervary Research Group on Combinatorial Optimization, EGRES).  | 
|
| 8 | 
		*  | 
|
| 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.  | 
|
| 12 | 
		*  | 
|
| 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  | 
|
| 15 | 
		* purpose.  | 
|
| 16 | 
		*  | 
|
| 17 | 
		*/  | 
|
| 18 | 
		 | 
|
| 19 | 
		#ifndef LEMON_BUCKET_HEAP_H  | 
|
| 20 | 
		#define LEMON_BUCKET_HEAP_H  | 
|
| 21 | 
		 | 
|
| 22 | 
		///\ingroup auxdat  | 
|
| 23 | 
		///\file  | 
|
| 24 | 
		///\brief Bucket Heap implementation.  | 
|
| 25 | 
		 | 
|
| 26 | 
		#include <vector>  | 
|
| 27 | 
		#include <utility>  | 
|
| 28 | 
		#include <functional>  | 
|
| 29 | 
		 | 
|
| 30 | 
		namespace lemon {
	 | 
|
| 31 | 
		 | 
|
| 32 | 
		  namespace _bucket_heap_bits {
	 | 
|
| 33 | 
		 | 
|
| 34 | 
		template <bool MIN>  | 
|
| 35 | 
		    struct DirectionTraits {
	 | 
|
| 36 | 
		      static bool less(int left, int right) {
	 | 
|
| 37 | 
		return left < right;  | 
|
| 38 | 
		}  | 
|
| 39 | 
		      static void increase(int& value) {
	 | 
|
| 40 | 
		++value;  | 
|
| 41 | 
		}  | 
|
| 42 | 
		};  | 
|
| 43 | 
		 | 
|
| 44 | 
		template <>  | 
|
| 45 | 
		    struct DirectionTraits<false> {
	 | 
|
| 46 | 
		      static bool less(int left, int right) {
	 | 
|
| 47 | 
		return left > right;  | 
|
| 48 | 
		}  | 
|
| 49 | 
		      static void increase(int& value) {
	 | 
|
| 50 | 
		--value;  | 
|
| 51 | 
		}  | 
|
| 52 | 
		};  | 
|
| 53 | 
		 | 
|
| 54 | 
		}  | 
|
| 55 | 
		 | 
|
| 56 | 
		/// \ingroup auxdat  | 
|
| 57 | 
		///  | 
|
| 58 | 
		/// \brief A Bucket Heap implementation.  | 
|
| 59 | 
		///  | 
|
| 60 | 
		/// This class implements the \e bucket \e heap data structure. A \e heap  | 
|
| 61 | 
		/// is a data structure for storing items with specified values called \e  | 
|
| 62 | 
		/// priorities in such a way that finding the item with minimum priority is  | 
|
| 63 | 
		/// efficient. The bucket heap is very simple implementation, it can store  | 
|
| 64 | 
		/// only integer priorities and it stores for each priority in the  | 
|
| 65 | 
		/// \f$ [0..C) \f$ range a list of items. So it should be used only when  | 
|
| 66 | 
		/// the priorities are small. It is not intended to use as dijkstra heap.  | 
|
| 67 | 
		///  | 
|
| 68 | 
		/// \param IM A read and write Item int map, used internally  | 
|
| 69 | 
		/// to handle the cross references.  | 
|
| 70 | 
		/// \param MIN If the given parameter is false then instead of the  | 
|
| 71 | 
		/// minimum value the maximum can be retrivied with the top() and  | 
|
| 72 | 
		/// prio() member functions.  | 
|
| 73 | 
		template <typename IM, bool MIN = true>  | 
|
| 74 | 
		  class BucketHeap {
	 | 
|
| 75 | 
		 | 
|
| 76 | 
		public:  | 
|
| 77 | 
		/// \e  | 
|
| 78 | 
		typedef typename IM::Key Item;  | 
|
| 79 | 
		/// \e  | 
|
| 80 | 
		typedef int Prio;  | 
|
| 81 | 
		/// \e  | 
|
| 82 | 
		typedef std::pair<Item, Prio> Pair;  | 
|
| 83 | 
		/// \e  | 
|
| 84 | 
		typedef IM ItemIntMap;  | 
|
| 85 | 
		 | 
|
| 86 | 
		private:  | 
|
| 87 | 
		 | 
|
| 88 | 
		typedef _bucket_heap_bits::DirectionTraits<MIN> Direction;  | 
|
| 89 | 
		 | 
|
| 90 | 
		public:  | 
|
| 91 | 
		 | 
|
| 92 | 
		/// \brief Type to represent the items states.  | 
|
| 93 | 
		///  | 
|
| 94 | 
		/// Each Item element have a state associated to it. It may be "in heap",  | 
|
| 95 | 
		/// "pre heap" or "post heap". The latter two are indifferent from the  | 
|
| 96 | 
		/// heap's point of view, but may be useful to the user.  | 
|
| 97 | 
		///  | 
|
| 98 | 
		/// The item-int map must be initialized in such way that it assigns  | 
|
| 99 | 
		/// \c PRE_HEAP (<tt>-1</tt>) to any element to be put in the heap.  | 
|
| 100 | 
		    enum State {
	 | 
|
| 101 | 
		IN_HEAP = 0, ///< = 0.  | 
|
| 102 | 
		PRE_HEAP = -1, ///< = -1.  | 
|
| 103 | 
		POST_HEAP = -2 ///< = -2.  | 
|
| 104 | 
		};  | 
|
| 105 | 
		 | 
|
| 106 | 
		public:  | 
|
| 107 | 
		/// \brief The constructor.  | 
|
| 108 | 
		///  | 
|
| 109 | 
		/// The constructor.  | 
|
| 110 | 
		/// \param map should be given to the constructor, since it is used  | 
|
| 111 | 
		/// internally to handle the cross references. The value of the map  | 
|
| 112 | 
		/// should be PRE_HEAP (-1) for each element.  | 
|
| 113 | 
		    explicit BucketHeap(ItemIntMap &map) : _iim(map), _minimum(0) {}
	 | 
|
| 114 | 
		 | 
|
| 115 | 
		/// The number of items stored in the heap.  | 
|
| 116 | 
		///  | 
|
| 117 | 
		/// \brief Returns the number of items stored in the heap.  | 
|
| 118 | 
		    int size() const { return _data.size(); }
	 | 
|
| 119 | 
		 | 
|
| 120 | 
		/// \brief Checks if the heap stores no items.  | 
|
| 121 | 
		///  | 
|
| 122 | 
		/// Returns \c true if and only if the heap stores no items.  | 
|
| 123 | 
		    bool empty() const { return _data.empty(); }
	 | 
|
| 124 | 
		 | 
|
| 125 | 
		/// \brief Make empty this heap.  | 
|
| 126 | 
		///  | 
|
| 127 | 
		/// Make empty this heap. It does not change the cross reference  | 
|
| 128 | 
		/// map. If you want to reuse a heap what is not surely empty you  | 
|
| 129 | 
		/// should first clear the heap and after that you should set the  | 
|
| 130 | 
		/// cross reference map for each item to \c PRE_HEAP.  | 
|
| 131 | 
		    void clear() {
	 | 
|
| 132 | 
		_data.clear(); _first.clear(); _minimum = 0;  | 
|
| 133 | 
		}  | 
|
| 134 | 
		 | 
|
| 135 | 
		private:  | 
|
| 136 | 
		 | 
|
| 137 | 
		    void relocate_last(int idx) {
	 | 
|
| 138 | 
		      if (idx + 1 < int(_data.size())) {
	 | 
|
| 139 | 
		_data[idx] = _data.back();  | 
|
| 140 | 
		        if (_data[idx].prev != -1) {
	 | 
|
| 141 | 
		_data[_data[idx].prev].next = idx;  | 
|
| 142 | 
		        } else {
	 | 
|
| 143 | 
		_first[_data[idx].value] = idx;  | 
|
| 144 | 
		}  | 
|
| 145 | 
		        if (_data[idx].next != -1) {
	 | 
|
| 146 | 
		_data[_data[idx].next].prev = idx;  | 
|
| 147 | 
		}  | 
|
| 148 | 
		_iim[_data[idx].item] = idx;  | 
|
| 149 | 
		}  | 
|
| 150 | 
		_data.pop_back();  | 
|
| 151 | 
		}  | 
|
| 152 | 
		 | 
|
| 153 | 
		    void unlace(int idx) {
	 | 
|
| 154 | 
		      if (_data[idx].prev != -1) {
	 | 
|
| 155 | 
		_data[_data[idx].prev].next = _data[idx].next;  | 
|
| 156 | 
		      } else {
	 | 
|
| 157 | 
		_first[_data[idx].value] = _data[idx].next;  | 
|
| 158 | 
		}  | 
|
| 159 | 
		      if (_data[idx].next != -1) {
	 | 
|
| 160 | 
		_data[_data[idx].next].prev = _data[idx].prev;  | 
|
| 161 | 
		}  | 
|
| 162 | 
		}  | 
|
| 163 | 
		 | 
|
| 164 | 
		    void lace(int idx) {
	 | 
|
| 165 | 
		      if (int(_first.size()) <= _data[idx].value) {
	 | 
|
| 166 | 
		_first.resize(_data[idx].value + 1, -1);  | 
|
| 167 | 
		}  | 
|
| 168 | 
		_data[idx].next = _first[_data[idx].value];  | 
|
| 169 | 
		      if (_data[idx].next != -1) {
	 | 
|
| 170 | 
		_data[_data[idx].next].prev = idx;  | 
|
| 171 | 
		}  | 
|
| 172 | 
		_first[_data[idx].value] = idx;  | 
|
| 173 | 
		_data[idx].prev = -1;  | 
|
| 174 | 
		}  | 
|
| 175 | 
		 | 
|
| 176 | 
		public:  | 
|
| 177 | 
		/// \brief Insert a pair of item and priority into the heap.  | 
|
| 178 | 
		///  | 
|
| 179 | 
		/// Adds \c p.first to the heap with priority \c p.second.  | 
|
| 180 | 
		/// \param p The pair to insert.  | 
|
| 181 | 
		    void push(const Pair& p) {
	 | 
|
| 182 | 
		push(p.first, p.second);  | 
|
| 183 | 
		}  | 
|
| 184 | 
		 | 
|
| 185 | 
		/// \brief Insert an item into the heap with the given priority.  | 
|
| 186 | 
		///  | 
|
| 187 | 
		/// Adds \c i to the heap with priority \c p.  | 
|
| 188 | 
		/// \param i The item to insert.  | 
|
| 189 | 
		/// \param p The priority of the item.  | 
|
| 190 | 
		    void push(const Item &i, const Prio &p) {
	 | 
|
| 191 | 
		int idx = _data.size();  | 
|
| 192 | 
		_iim[i] = idx;  | 
|
| 193 | 
		_data.push_back(BucketItem(i, p));  | 
|
| 194 | 
		lace(idx);  | 
|
| 195 | 
		      if (Direction::less(p, _minimum)) {
	 | 
|
| 196 | 
		_minimum = p;  | 
|
| 197 | 
		}  | 
|
| 198 | 
		}  | 
|
| 199 | 
		 | 
|
| 200 | 
		/// \brief Returns the item with minimum priority.  | 
|
| 201 | 
		///  | 
|
| 202 | 
		/// This method returns the item with minimum priority.  | 
|
| 203 | 
		/// \pre The heap must be nonempty.  | 
|
| 204 | 
		    Item top() const {
	 | 
|
| 205 | 
		      while (_first[_minimum] == -1) {
	 | 
|
| 206 | 
		Direction::increase(_minimum);  | 
|
| 207 | 
		}  | 
|
| 208 | 
		return _data[_first[_minimum]].item;  | 
|
| 209 | 
		}  | 
|
| 210 | 
		 | 
|
| 211 | 
		/// \brief Returns the minimum priority.  | 
|
| 212 | 
		///  | 
|
| 213 | 
		/// It returns the minimum priority.  | 
|
| 214 | 
		/// \pre The heap must be nonempty.  | 
|
| 215 | 
		    Prio prio() const {
	 | 
|
| 216 | 
		      while (_first[_minimum] == -1) {
	 | 
|
| 217 | 
		Direction::increase(_minimum);  | 
|
| 218 | 
		}  | 
|
| 219 | 
		return _minimum;  | 
|
| 220 | 
		}  | 
|
| 221 | 
		 | 
|
| 222 | 
		/// \brief Deletes the item with minimum priority.  | 
|
| 223 | 
		///  | 
|
| 224 | 
		/// This method deletes the item with minimum priority from the heap.  | 
|
| 225 | 
		/// \pre The heap must be non-empty.  | 
|
| 226 | 
		    void pop() {
	 | 
|
| 227 | 
		      while (_first[_minimum] == -1) {
	 | 
|
| 228 | 
		Direction::increase(_minimum);  | 
|
| 229 | 
		}  | 
|
| 230 | 
		int idx = _first[_minimum];  | 
|
| 231 | 
		_iim[_data[idx].item] = -2;  | 
|
| 232 | 
		unlace(idx);  | 
|
| 233 | 
		relocate_last(idx);  | 
|
| 234 | 
		}  | 
|
| 235 | 
		 | 
|
| 236 | 
		/// \brief Deletes \c i from the heap.  | 
|
| 237 | 
		///  | 
|
| 238 | 
		/// This method deletes item \c i from the heap, if \c i was  | 
|
| 239 | 
		/// already stored in the heap.  | 
|
| 240 | 
		/// \param i The item to erase.  | 
|
| 241 | 
		    void erase(const Item &i) {
	 | 
|
| 242 | 
		int idx = _iim[i];  | 
|
| 243 | 
		_iim[_data[idx].item] = -2;  | 
|
| 244 | 
		unlace(idx);  | 
|
| 245 | 
		relocate_last(idx);  | 
|
| 246 | 
		}  | 
|
| 247 | 
		 | 
|
| 248 | 
		 | 
|
| 249 | 
		/// \brief Returns the priority of \c i.  | 
|
| 250 | 
		///  | 
|
| 251 | 
		/// This function returns the priority of item \c i.  | 
|
| 252 | 
		/// \pre \c i must be in the heap.  | 
|
| 253 | 
		/// \param i The item.  | 
|
| 254 | 
		    Prio operator[](const Item &i) const {
	 | 
|
| 255 | 
		int idx = _iim[i];  | 
|
| 256 | 
		return _data[idx].value;  | 
|
| 257 | 
		}  | 
|
| 258 | 
		 | 
|
| 259 | 
		/// \brief \c i gets to the heap with priority \c p independently  | 
|
| 260 | 
		/// if \c i was already there.  | 
|
| 261 | 
		///  | 
|
| 262 | 
		/// This method calls \ref push(\c i, \c p) if \c i is not stored  | 
|
| 263 | 
		/// in the heap and sets the priority of \c i to \c p otherwise.  | 
|
| 264 | 
		/// \param i The item.  | 
|
| 265 | 
		/// \param p The priority.  | 
|
| 266 | 
		    void set(const Item &i, const Prio &p) {
	 | 
|
| 267 | 
		int idx = _iim[i];  | 
|
| 268 | 
		      if (idx < 0) {
	 | 
|
| 269 | 
		push(i, p);  | 
|
| 270 | 
		      } else if (Direction::less(p, _data[idx].value)) {
	 | 
|
| 271 | 
		decrease(i, p);  | 
|
| 272 | 
		      } else {
	 | 
|
| 273 | 
		increase(i, p);  | 
|
| 274 | 
		}  | 
|
| 275 | 
		}  | 
|
| 276 | 
		 | 
|
| 277 | 
		/// \brief Decreases the priority of \c i to \c p.  | 
|
| 278 | 
		///  | 
|
| 279 | 
		/// This method decreases the priority of item \c i to \c p.  | 
|
| 280 | 
		/// \pre \c i must be stored in the heap with priority at least \c  | 
|
| 281 | 
		/// p relative to \c Compare.  | 
|
| 282 | 
		/// \param i The item.  | 
|
| 283 | 
		/// \param p The priority.  | 
|
| 284 | 
		    void decrease(const Item &i, const Prio &p) {
	 | 
|
| 285 | 
		int idx = _iim[i];  | 
|
| 286 | 
		unlace(idx);  | 
|
| 287 | 
		_data[idx].value = p;  | 
|
| 288 | 
		      if (Direction::less(p, _minimum)) {
	 | 
|
| 289 | 
		_minimum = p;  | 
|
| 290 | 
		}  | 
|
| 291 | 
		lace(idx);  | 
|
| 292 | 
		}  | 
|
| 293 | 
		 | 
|
| 294 | 
		/// \brief Increases the priority of \c i to \c p.  | 
|
| 295 | 
		///  | 
|
| 296 | 
		/// This method sets the priority of item \c i to \c p.  | 
|
| 297 | 
		/// \pre \c i must be stored in the heap with priority at most \c  | 
|
| 298 | 
		/// p relative to \c Compare.  | 
|
| 299 | 
		/// \param i The item.  | 
|
| 300 | 
		/// \param p The priority.  | 
|
| 301 | 
		    void increase(const Item &i, const Prio &p) {
	 | 
|
| 302 | 
		int idx = _iim[i];  | 
|
| 303 | 
		unlace(idx);  | 
|
| 304 | 
		_data[idx].value = p;  | 
|
| 305 | 
		lace(idx);  | 
|
| 306 | 
		}  | 
|
| 307 | 
		 | 
|
| 308 | 
		/// \brief Returns if \c item is in, has already been in, or has  | 
|
| 309 | 
		/// never been in the heap.  | 
|
| 310 | 
		///  | 
|
| 311 | 
		/// This method returns PRE_HEAP if \c item has never been in the  | 
|
| 312 | 
		/// heap, IN_HEAP if it is in the heap at the moment, and POST_HEAP  | 
|
| 313 | 
		/// otherwise. In the latter case it is possible that \c item will  | 
|
| 314 | 
		/// get back to the heap again.  | 
|
| 315 | 
		/// \param i The item.  | 
|
| 316 | 
		    State state(const Item &i) const {
	 | 
|
| 317 | 
		int idx = _iim[i];  | 
|
| 318 | 
		if (idx >= 0) idx = 0;  | 
|
| 319 | 
		return State(idx);  | 
|
| 320 | 
		}  | 
|
| 321 | 
		 | 
|
| 322 | 
		/// \brief Sets the state of the \c item in the heap.  | 
|
| 323 | 
		///  | 
|
| 324 | 
		/// Sets the state of the \c item in the heap. It can be used to  | 
|
| 325 | 
		/// manually clear the heap when it is important to achive the  | 
|
| 326 | 
		/// better time complexity.  | 
|
| 327 | 
		/// \param i The item.  | 
|
| 328 | 
		/// \param st The state. It should not be \c IN_HEAP.  | 
|
| 329 | 
		    void state(const Item& i, State st) {
	 | 
|
| 330 | 
		      switch (st) {
	 | 
|
| 331 | 
		case POST_HEAP:  | 
|
| 332 | 
		case PRE_HEAP:  | 
|
| 333 | 
		        if (state(i) == IN_HEAP) {
	 | 
|
| 334 | 
		erase(i);  | 
|
| 335 | 
		}  | 
|
| 336 | 
		_iim[i] = st;  | 
|
| 337 | 
		break;  | 
|
| 338 | 
		case IN_HEAP:  | 
|
| 339 | 
		break;  | 
|
| 340 | 
		}  | 
|
| 341 | 
		}  | 
|
| 342 | 
		 | 
|
| 343 | 
		private:  | 
|
| 344 | 
		 | 
|
| 345 | 
		    struct BucketItem {
	 | 
|
| 346 | 
		BucketItem(const Item& _item, int _value)  | 
|
| 347 | 
		        : item(_item), value(_value) {}
	 | 
|
| 348 | 
		 | 
|
| 349 | 
		Item item;  | 
|
| 350 | 
		int value;  | 
|
| 351 | 
		 | 
|
| 352 | 
		int prev, next;  | 
|
| 353 | 
		};  | 
|
| 354 | 
		 | 
|
| 355 | 
		ItemIntMap& _iim;  | 
|
| 356 | 
		std::vector<int> _first;  | 
|
| 357 | 
		std::vector<BucketItem> _data;  | 
|
| 358 | 
		mutable int _minimum;  | 
|
| 359 | 
		 | 
|
| 360 | 
		}; // class BucketHeap  | 
|
| 361 | 
		 | 
|
| 362 | 
		/// \ingroup auxdat  | 
|
| 363 | 
		///  | 
|
| 364 | 
		/// \brief A Simplified Bucket Heap implementation.  | 
|
| 365 | 
		///  | 
|
| 366 | 
		/// This class implements a simplified \e bucket \e heap data  | 
|
| 367 | 
		/// structure. It does not provide some functionality but it faster  | 
|
| 368 | 
		/// and simplier data structure than the BucketHeap. The main  | 
|
| 369 | 
		/// difference is that the BucketHeap stores for every key a double  | 
|
| 370 | 
		/// linked list while this class stores just simple lists. In the  | 
|
| 371 | 
		/// other way it does not support erasing each elements just the  | 
|
| 372 | 
		/// minimal and it does not supports key increasing, decreasing.  | 
|
| 373 | 
		///  | 
|
| 374 | 
		/// \param IM A read and write Item int map, used internally  | 
|
| 375 | 
		/// to handle the cross references.  | 
|
| 376 | 
		/// \param MIN If the given parameter is false then instead of the  | 
|
| 377 | 
		/// minimum value the maximum can be retrivied with the top() and  | 
|
| 378 | 
		/// prio() member functions.  | 
|
| 379 | 
		///  | 
|
| 380 | 
		/// \sa BucketHeap  | 
|
| 381 | 
		template <typename IM, bool MIN = true >  | 
|
| 382 | 
		  class SimpleBucketHeap {
	 | 
|
| 383 | 
		 | 
|
| 384 | 
		public:  | 
|
| 385 | 
		typedef typename IM::Key Item;  | 
|
| 386 | 
		typedef int Prio;  | 
|
| 387 | 
		typedef std::pair<Item, Prio> Pair;  | 
|
| 388 | 
		typedef IM ItemIntMap;  | 
|
| 389 | 
		 | 
|
| 390 | 
		private:  | 
|
| 391 | 
		 | 
|
| 392 | 
		typedef _bucket_heap_bits::DirectionTraits<MIN> Direction;  | 
|
| 393 | 
		 | 
|
| 394 | 
		public:  | 
|
| 395 | 
		 | 
|
| 396 | 
		/// \brief Type to represent the items states.  | 
|
| 397 | 
		///  | 
|
| 398 | 
		/// Each Item element have a state associated to it. It may be "in heap",  | 
|
| 399 | 
		/// "pre heap" or "post heap". The latter two are indifferent from the  | 
|
| 400 | 
		/// heap's point of view, but may be useful to the user.  | 
|
| 401 | 
		///  | 
|
| 402 | 
		/// The item-int map must be initialized in such way that it assigns  | 
|
| 403 | 
		/// \c PRE_HEAP (<tt>-1</tt>) to any element to be put in the heap.  | 
|
| 404 | 
		    enum State {
	 | 
|
| 405 | 
		IN_HEAP = 0, ///< = 0.  | 
|
| 406 | 
		PRE_HEAP = -1, ///< = -1.  | 
|
| 407 | 
		POST_HEAP = -2 ///< = -2.  | 
|
| 408 | 
		};  | 
|
| 409 | 
		 | 
|
| 410 | 
		public:  | 
|
| 411 | 
		 | 
|
| 412 | 
		/// \brief The constructor.  | 
|
| 413 | 
		///  | 
|
| 414 | 
		/// The constructor.  | 
|
| 415 | 
		/// \param map should be given to the constructor, since it is used  | 
|
| 416 | 
		/// internally to handle the cross references. The value of the map  | 
|
| 417 | 
		/// should be PRE_HEAP (-1) for each element.  | 
|
| 418 | 
		explicit SimpleBucketHeap(ItemIntMap &map)  | 
|
| 419 | 
		      : _iim(map), _free(-1), _num(0), _minimum(0) {}
	 | 
|
| 420 | 
		 | 
|
| 421 | 
		/// \brief Returns the number of items stored in the heap.  | 
|
| 422 | 
		///  | 
|
| 423 | 
		/// The number of items stored in the heap.  | 
|
| 424 | 
		    int size() const { return _num; }
	 | 
|
| 425 | 
		 | 
|
| 426 | 
		/// \brief Checks if the heap stores no items.  | 
|
| 427 | 
		///  | 
|
| 428 | 
		/// Returns \c true if and only if the heap stores no items.  | 
|
| 429 | 
		    bool empty() const { return _num == 0; }
	 | 
|
| 430 | 
		 | 
|
| 431 | 
		/// \brief Make empty this heap.  | 
|
| 432 | 
		///  | 
|
| 433 | 
		/// Make empty this heap. It does not change the cross reference  | 
|
| 434 | 
		/// map. If you want to reuse a heap what is not surely empty you  | 
|
| 435 | 
		/// should first clear the heap and after that you should set the  | 
|
| 436 | 
		/// cross reference map for each item to \c PRE_HEAP.  | 
|
| 437 | 
		    void clear() {
	 | 
|
| 438 | 
		_data.clear(); _first.clear(); _free = -1; _num = 0; _minimum = 0;  | 
|
| 439 | 
		}  | 
|
| 440 | 
		 | 
|
| 441 | 
		/// \brief Insert a pair of item and priority into the heap.  | 
|
| 442 | 
		///  | 
|
| 443 | 
		/// Adds \c p.first to the heap with priority \c p.second.  | 
|
| 444 | 
		/// \param p The pair to insert.  | 
|
| 445 | 
		    void push(const Pair& p) {
	 | 
|
| 446 | 
		push(p.first, p.second);  | 
|
| 447 | 
		}  | 
|
| 448 | 
		 | 
|
| 449 | 
		/// \brief Insert an item into the heap with the given priority.  | 
|
| 450 | 
		///  | 
|
| 451 | 
		/// Adds \c i to the heap with priority \c p.  | 
|
| 452 | 
		/// \param i The item to insert.  | 
|
| 453 | 
		/// \param p The priority of the item.  | 
|
| 454 | 
		    void push(const Item &i, const Prio &p) {
	 | 
|
| 455 | 
		int idx;  | 
|
| 456 | 
		      if (_free == -1) {
	 | 
|
| 457 | 
		idx = _data.size();  | 
|
| 458 | 
		_data.push_back(BucketItem(i));  | 
|
| 459 | 
		      } else {
	 | 
|
| 460 | 
		idx = _free;  | 
|
| 461 | 
		_free = _data[idx].next;  | 
|
| 462 | 
		_data[idx].item = i;  | 
|
| 463 | 
		}  | 
|
| 464 | 
		_iim[i] = idx;  | 
|
| 465 | 
		if (p >= int(_first.size())) _first.resize(p + 1, -1);  | 
|
| 466 | 
		_data[idx].next = _first[p];  | 
|
| 467 | 
		_first[p] = idx;  | 
|
| 468 | 
		      if (Direction::less(p, _minimum)) {
	 | 
|
| 469 | 
		_minimum = p;  | 
|
| 470 | 
		}  | 
|
| 471 | 
		++_num;  | 
|
| 472 | 
		}  | 
|
| 473 | 
		 | 
|
| 474 | 
		/// \brief Returns the item with minimum priority.  | 
|
| 475 | 
		///  | 
|
| 476 | 
		/// This method returns the item with minimum priority.  | 
|
| 477 | 
		/// \pre The heap must be nonempty.  | 
|
| 478 | 
		    Item top() const {
	 | 
|
| 479 | 
		      while (_first[_minimum] == -1) {
	 | 
|
| 480 | 
		Direction::increase(_minimum);  | 
|
| 481 | 
		}  | 
|
| 482 | 
		return _data[_first[_minimum]].item;  | 
|
| 483 | 
		}  | 
|
| 484 | 
		 | 
|
| 485 | 
		/// \brief Returns the minimum priority.  | 
|
| 486 | 
		///  | 
|
| 487 | 
		/// It returns the minimum priority.  | 
|
| 488 | 
		/// \pre The heap must be nonempty.  | 
|
| 489 | 
		    Prio prio() const {
	 | 
|
| 490 | 
		      while (_first[_minimum] == -1) {
	 | 
|
| 491 | 
		Direction::increase(_minimum);  | 
|
| 492 | 
		}  | 
|
| 493 | 
		return _minimum;  | 
|
| 494 | 
		}  | 
|
| 495 | 
		 | 
|
| 496 | 
		/// \brief Deletes the item with minimum priority.  | 
|
| 497 | 
		///  | 
|
| 498 | 
		/// This method deletes the item with minimum priority from the heap.  | 
|
| 499 | 
		/// \pre The heap must be non-empty.  | 
|
| 500 | 
		    void pop() {
	 | 
|
| 501 | 
		      while (_first[_minimum] == -1) {
	 | 
|
| 502 | 
		Direction::increase(_minimum);  | 
|
| 503 | 
		}  | 
|
| 504 | 
		int idx = _first[_minimum];  | 
|
| 505 | 
		_iim[_data[idx].item] = -2;  | 
|
| 506 | 
		_first[_minimum] = _data[idx].next;  | 
|
| 507 | 
		_data[idx].next = _free;  | 
|
| 508 | 
		_free = idx;  | 
|
| 509 | 
		--_num;  | 
|
| 510 | 
		}  | 
|
| 511 | 
		 | 
|
| 512 | 
		/// \brief Returns the priority of \c i.  | 
|
| 513 | 
		///  | 
|
| 514 | 
		/// This function returns the priority of item \c i.  | 
|
| 515 | 
		/// \warning This operator is not a constant time function  | 
|
| 516 | 
		/// because it scans the whole data structure to find the proper  | 
|
| 517 | 
		/// value.  | 
|
| 518 | 
		/// \pre \c i must be in the heap.  | 
|
| 519 | 
		/// \param i The item.  | 
|
| 520 | 
		    Prio operator[](const Item &i) const {
	 | 
|
| 521 | 
		      for (int k = 0; k < _first.size(); ++k) {
	 | 
|
| 522 | 
		int idx = _first[k];  | 
|
| 523 | 
		        while (idx != -1) {
	 | 
|
| 524 | 
		          if (_data[idx].item == i) {
	 | 
|
| 525 | 
		return k;  | 
|
| 526 | 
		}  | 
|
| 527 | 
		idx = _data[idx].next;  | 
|
| 528 | 
		}  | 
|
| 529 | 
		}  | 
|
| 530 | 
		return -1;  | 
|
| 531 | 
		}  | 
|
| 532 | 
		 | 
|
| 533 | 
		/// \brief Returns if \c item is in, has already been in, or has  | 
|
| 534 | 
		/// never been in the heap.  | 
|
| 535 | 
		///  | 
|
| 536 | 
		/// This method returns PRE_HEAP if \c item has never been in the  | 
|
| 537 | 
		/// heap, IN_HEAP if it is in the heap at the moment, and POST_HEAP  | 
|
| 538 | 
		/// otherwise. In the latter case it is possible that \c item will  | 
|
| 539 | 
		/// get back to the heap again.  | 
|
| 540 | 
		/// \param i The item.  | 
|
| 541 | 
		    State state(const Item &i) const {
	 | 
|
| 542 | 
		int idx = _iim[i];  | 
|
| 543 | 
		if (idx >= 0) idx = 0;  | 
|
| 544 | 
		return State(idx);  | 
|
| 545 | 
		}  | 
|
| 546 | 
		 | 
|
| 547 | 
		private:  | 
|
| 548 | 
		 | 
|
| 549 | 
		    struct BucketItem {
	 | 
|
| 550 | 
		BucketItem(const Item& _item)  | 
|
| 551 | 
		        : item(_item) {}
	 | 
|
| 552 | 
		 | 
|
| 553 | 
		Item item;  | 
|
| 554 | 
		int next;  | 
|
| 555 | 
		};  | 
|
| 556 | 
		 | 
|
| 557 | 
		ItemIntMap& _iim;  | 
|
| 558 | 
		std::vector<int> _first;  | 
|
| 559 | 
		std::vector<BucketItem> _data;  | 
|
| 560 | 
		int _free, _num;  | 
|
| 561 | 
		mutable int _minimum;  | 
|
| 562 | 
		 | 
|
| 563 | 
		}; // class SimpleBucketHeap  | 
|
| 564 | 
		 | 
|
| 565 | 
		}  | 
|
| 566 | 
		 | 
|
| 567 | 
		#endif  | 
| 1 | 
		/* -*- mode: C++; indent-tabs-mode: nil; -*-  | 
|
| 2 | 
		*  | 
|
| 3 | 
		* This file is a part of LEMON, a generic C++ optimization library.  | 
|
| 4 | 
		*  | 
|
| 5 | 
		* Copyright (C) 2003-2009  | 
|
| 6 | 
		* Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport  | 
|
| 7 | 
		* (Egervary Research Group on Combinatorial Optimization, EGRES).  | 
|
| 8 | 
		*  | 
|
| 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.  | 
|
| 12 | 
		*  | 
|
| 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  | 
|
| 15 | 
		* purpose.  | 
|
| 16 | 
		*  | 
|
| 17 | 
		*/  | 
|
| 18 | 
		 | 
|
| 19 | 
		#ifndef LEMON_FIB_HEAP_H  | 
|
| 20 | 
		#define LEMON_FIB_HEAP_H  | 
|
| 21 | 
		 | 
|
| 22 | 
		///\file  | 
|
| 23 | 
		///\ingroup auxdat  | 
|
| 24 | 
		///\brief Fibonacci Heap implementation.  | 
|
| 25 | 
		 | 
|
| 26 | 
		#include <vector>  | 
|
| 27 | 
		#include <functional>  | 
|
| 28 | 
		#include <lemon/math.h>  | 
|
| 29 | 
		 | 
|
| 30 | 
		namespace lemon {
	 | 
|
| 31 | 
		 | 
|
| 32 | 
		/// \ingroup auxdat  | 
|
| 33 | 
		///  | 
|
| 34 | 
		///\brief Fibonacci Heap.  | 
|
| 35 | 
		///  | 
|
| 36 | 
		///This class implements the \e Fibonacci \e heap data structure. A \e heap  | 
|
| 37 | 
		///is a data structure for storing items with specified values called \e  | 
|
| 38 | 
		///priorities in such a way that finding the item with minimum priority is  | 
|
| 39 | 
		///efficient. \c CMP specifies the ordering of the priorities. In a heap  | 
|
| 40 | 
		///one can change the priority of an item, add or erase an item, etc.  | 
|
| 41 | 
		///  | 
|
| 42 | 
		///The methods \ref increase and \ref erase are not efficient in a Fibonacci  | 
|
| 43 | 
		///heap. In case of many calls to these operations, it is better to use a  | 
|
| 44 | 
		///\ref BinHeap "binary heap".  | 
|
| 45 | 
		///  | 
|
| 46 | 
		///\param PRIO Type of the priority of the items.  | 
|
| 47 | 
		///\param IM A read and writable Item int map, used internally  | 
|
| 48 | 
		///to handle the cross references.  | 
|
| 49 | 
		///\param CMP A class for the ordering of the priorities. The  | 
|
| 50 | 
		///default is \c std::less<PRIO>.  | 
|
| 51 | 
		///  | 
|
| 52 | 
		///\sa BinHeap  | 
|
| 53 | 
		///\sa Dijkstra  | 
|
| 54 | 
		#ifdef DOXYGEN  | 
|
| 55 | 
		template <typename PRIO, typename IM, typename CMP>  | 
|
| 56 | 
		#else  | 
|
| 57 | 
		template <typename PRIO, typename IM, typename CMP = std::less<PRIO> >  | 
|
| 58 | 
		#endif  | 
|
| 59 | 
		  class FibHeap {
	 | 
|
| 60 | 
		public:  | 
|
| 61 | 
		///\e  | 
|
| 62 | 
		typedef IM ItemIntMap;  | 
|
| 63 | 
		///\e  | 
|
| 64 | 
		typedef PRIO Prio;  | 
|
| 65 | 
		///\e  | 
|
| 66 | 
		typedef typename ItemIntMap::Key Item;  | 
|
| 67 | 
		///\e  | 
|
| 68 | 
		typedef std::pair<Item,Prio> Pair;  | 
|
| 69 | 
		///\e  | 
|
| 70 | 
		typedef CMP Compare;  | 
|
| 71 | 
		 | 
|
| 72 | 
		private:  | 
|
| 73 | 
		class Store;  | 
|
| 74 | 
		 | 
|
| 75 | 
		std::vector<Store> _data;  | 
|
| 76 | 
		int _minimum;  | 
|
| 77 | 
		ItemIntMap &_iim;  | 
|
| 78 | 
		Compare _comp;  | 
|
| 79 | 
		int _num;  | 
|
| 80 | 
		 | 
|
| 81 | 
		public:  | 
|
| 82 | 
		 | 
|
| 83 | 
		/// \brief Type to represent the items states.  | 
|
| 84 | 
		///  | 
|
| 85 | 
		/// Each Item element have a state associated to it. It may be "in heap",  | 
|
| 86 | 
		/// "pre heap" or "post heap". The latter two are indifferent from the  | 
|
| 87 | 
		/// heap's point of view, but may be useful to the user.  | 
|
| 88 | 
		///  | 
|
| 89 | 
		/// The item-int map must be initialized in such way that it assigns  | 
|
| 90 | 
		/// \c PRE_HEAP (<tt>-1</tt>) to any element to be put in the heap.  | 
|
| 91 | 
		    enum State {
	 | 
|
| 92 | 
		IN_HEAP = 0, ///< = 0.  | 
|
| 93 | 
		PRE_HEAP = -1, ///< = -1.  | 
|
| 94 | 
		POST_HEAP = -2 ///< = -2.  | 
|
| 95 | 
		};  | 
|
| 96 | 
		 | 
|
| 97 | 
		/// \brief The constructor  | 
|
| 98 | 
		///  | 
|
| 99 | 
		/// \c map should be given to the constructor, since it is  | 
|
| 100 | 
		/// used internally to handle the cross references.  | 
|
| 101 | 
		explicit FibHeap(ItemIntMap &map)  | 
|
| 102 | 
		      : _minimum(0), _iim(map), _num() {}
	 | 
|
| 103 | 
		 | 
|
| 104 | 
		/// \brief The constructor  | 
|
| 105 | 
		///  | 
|
| 106 | 
		/// \c map should be given to the constructor, since it is used  | 
|
| 107 | 
		/// internally to handle the cross references. \c comp is an  | 
|
| 108 | 
		/// object for ordering of the priorities.  | 
|
| 109 | 
		FibHeap(ItemIntMap &map, const Compare &comp)  | 
|
| 110 | 
		      : _minimum(0), _iim(map), _comp(comp), _num() {}
	 | 
|
| 111 | 
		 | 
|
| 112 | 
		/// \brief The number of items stored in the heap.  | 
|
| 113 | 
		///  | 
|
| 114 | 
		/// Returns the number of items stored in the heap.  | 
|
| 115 | 
		    int size() const { return _num; }
	 | 
|
| 116 | 
		 | 
|
| 117 | 
		/// \brief Checks if the heap stores no items.  | 
|
| 118 | 
		///  | 
|
| 119 | 
		/// Returns \c true if and only if the heap stores no items.  | 
|
| 120 | 
		    bool empty() const { return _num==0; }
	 | 
|
| 121 | 
		 | 
|
| 122 | 
		/// \brief Make empty this heap.  | 
|
| 123 | 
		///  | 
|
| 124 | 
		/// Make empty this heap. It does not change the cross reference  | 
|
| 125 | 
		/// map. If you want to reuse a heap what is not surely empty you  | 
|
| 126 | 
		/// should first clear the heap and after that you should set the  | 
|
| 127 | 
		/// cross reference map for each item to \c PRE_HEAP.  | 
|
| 128 | 
		    void clear() {
	 | 
|
| 129 | 
		_data.clear(); _minimum = 0; _num = 0;  | 
|
| 130 | 
		}  | 
|
| 131 | 
		 | 
|
| 132 | 
		/// \brief \c item gets to the heap with priority \c value independently  | 
|
| 133 | 
		/// if \c item was already there.  | 
|
| 134 | 
		///  | 
|
| 135 | 
		/// This method calls \ref push(\c item, \c value) if \c item is not  | 
|
| 136 | 
		/// stored in the heap and it calls \ref decrease(\c item, \c value) or  | 
|
| 137 | 
		/// \ref increase(\c item, \c value) otherwise.  | 
|
| 138 | 
		    void set (const Item& item, const Prio& value) {
	 | 
|
| 139 | 
		int i=_iim[item];  | 
|
| 140 | 
		      if ( i >= 0 && _data[i].in ) {
	 | 
|
| 141 | 
		if ( _comp(value, _data[i].prio) ) decrease(item, value);  | 
|
| 142 | 
		if ( _comp(_data[i].prio, value) ) increase(item, value);  | 
|
| 143 | 
		} else push(item, value);  | 
|
| 144 | 
		}  | 
|
| 145 | 
		 | 
|
| 146 | 
		/// \brief Adds \c item to the heap with priority \c value.  | 
|
| 147 | 
		///  | 
|
| 148 | 
		/// Adds \c item to the heap with priority \c value.  | 
|
| 149 | 
		/// \pre \c item must not be stored in the heap.  | 
|
| 150 | 
		    void push (const Item& item, const Prio& value) {
	 | 
|
| 151 | 
		int i=_iim[item];  | 
|
| 152 | 
		      if ( i < 0 ) {
	 | 
|
| 153 | 
		int s=_data.size();  | 
|
| 154 | 
		_iim.set( item, s );  | 
|
| 155 | 
		Store st;  | 
|
| 156 | 
		st.name=item;  | 
|
| 157 | 
		_data.push_back(st);  | 
|
| 158 | 
		i=s;  | 
|
| 159 | 
		      } else {
	 | 
|
| 160 | 
		_data[i].parent=_data[i].child=-1;  | 
|
| 161 | 
		_data[i].degree=0;  | 
|
| 162 | 
		_data[i].in=true;  | 
|
| 163 | 
		_data[i].marked=false;  | 
|
| 164 | 
		}  | 
|
| 165 | 
		 | 
|
| 166 | 
		      if ( _num ) {
	 | 
|
| 167 | 
		_data[_data[_minimum].right_neighbor].left_neighbor=i;  | 
|
| 168 | 
		_data[i].right_neighbor=_data[_minimum].right_neighbor;  | 
|
| 169 | 
		_data[_minimum].right_neighbor=i;  | 
|
| 170 | 
		_data[i].left_neighbor=_minimum;  | 
|
| 171 | 
		if ( _comp( value, _data[_minimum].prio) ) _minimum=i;  | 
|
| 172 | 
		      } else {
	 | 
|
| 173 | 
		_data[i].right_neighbor=_data[i].left_neighbor=i;  | 
|
| 174 | 
		_minimum=i;  | 
|
| 175 | 
		}  | 
|
| 176 | 
		_data[i].prio=value;  | 
|
| 177 | 
		++_num;  | 
|
| 178 | 
		}  | 
|
| 179 | 
		 | 
|
| 180 | 
		/// \brief Returns the item with minimum priority relative to \c Compare.  | 
|
| 181 | 
		///  | 
|
| 182 | 
		/// This method returns the item with minimum priority relative to \c  | 
|
| 183 | 
		/// Compare.  | 
|
| 184 | 
		/// \pre The heap must be nonempty.  | 
|
| 185 | 
		    Item top() const { return _data[_minimum].name; }
	 | 
|
| 186 | 
		 | 
|
| 187 | 
		/// \brief Returns the minimum priority relative to \c Compare.  | 
|
| 188 | 
		///  | 
|
| 189 | 
		/// It returns the minimum priority relative to \c Compare.  | 
|
| 190 | 
		/// \pre The heap must be nonempty.  | 
|
| 191 | 
		    const Prio& prio() const { return _data[_minimum].prio; }
	 | 
|
| 192 | 
		 | 
|
| 193 | 
		/// \brief Returns the priority of \c item.  | 
|
| 194 | 
		///  | 
|
| 195 | 
		/// It returns the priority of \c item.  | 
|
| 196 | 
		/// \pre \c item must be in the heap.  | 
|
| 197 | 
		    const Prio& operator[](const Item& item) const {
	 | 
|
| 198 | 
		return _data[_iim[item]].prio;  | 
|
| 199 | 
		}  | 
|
| 200 | 
		 | 
|
| 201 | 
		/// \brief Deletes the item with minimum priority relative to \c Compare.  | 
|
| 202 | 
		///  | 
|
| 203 | 
		/// This method deletes the item with minimum priority relative to \c  | 
|
| 204 | 
		/// Compare from the heap.  | 
|
| 205 | 
		/// \pre The heap must be non-empty.  | 
|
| 206 | 
		    void pop() {
	 | 
|
| 207 | 
		/*The first case is that there are only one root.*/  | 
|
| 208 | 
		      if ( _data[_minimum].left_neighbor==_minimum ) {
	 | 
|
| 209 | 
		_data[_minimum].in=false;  | 
|
| 210 | 
		        if ( _data[_minimum].degree!=0 ) {
	 | 
|
| 211 | 
		makeroot(_data[_minimum].child);  | 
|
| 212 | 
		_minimum=_data[_minimum].child;  | 
|
| 213 | 
		balance();  | 
|
| 214 | 
		}  | 
|
| 215 | 
		      } else {
	 | 
|
| 216 | 
		int right=_data[_minimum].right_neighbor;  | 
|
| 217 | 
		unlace(_minimum);  | 
|
| 218 | 
		_data[_minimum].in=false;  | 
|
| 219 | 
		        if ( _data[_minimum].degree > 0 ) {
	 | 
|
| 220 | 
		int left=_data[_minimum].left_neighbor;  | 
|
| 221 | 
		int child=_data[_minimum].child;  | 
|
| 222 | 
		int last_child=_data[child].left_neighbor;  | 
|
| 223 | 
		 | 
|
| 224 | 
		makeroot(child);  | 
|
| 225 | 
		 | 
|
| 226 | 
		_data[left].right_neighbor=child;  | 
|
| 227 | 
		_data[child].left_neighbor=left;  | 
|
| 228 | 
		_data[right].left_neighbor=last_child;  | 
|
| 229 | 
		_data[last_child].right_neighbor=right;  | 
|
| 230 | 
		}  | 
|
| 231 | 
		_minimum=right;  | 
|
| 232 | 
		balance();  | 
|
| 233 | 
		} // the case where there are more roots  | 
|
| 234 | 
		--_num;  | 
|
| 235 | 
		}  | 
|
| 236 | 
		 | 
|
| 237 | 
		/// \brief Deletes \c item from the heap.  | 
|
| 238 | 
		///  | 
|
| 239 | 
		/// This method deletes \c item from the heap, if \c item was already  | 
|
| 240 | 
		/// stored in the heap. It is quite inefficient in Fibonacci heaps.  | 
|
| 241 | 
		    void erase (const Item& item) {
	 | 
|
| 242 | 
		int i=_iim[item];  | 
|
| 243 | 
		 | 
|
| 244 | 
		      if ( i >= 0 && _data[i].in ) {
	 | 
|
| 245 | 
		        if ( _data[i].parent!=-1 ) {
	 | 
|
| 246 | 
		int p=_data[i].parent;  | 
|
| 247 | 
		cut(i,p);  | 
|
| 248 | 
		cascade(p);  | 
|
| 249 | 
		}  | 
|
| 250 | 
		_minimum=i; //As if its prio would be -infinity  | 
|
| 251 | 
		pop();  | 
|
| 252 | 
		}  | 
|
| 253 | 
		}  | 
|
| 254 | 
		 | 
|
| 255 | 
		/// \brief Decreases the priority of \c item to \c value.  | 
|
| 256 | 
		///  | 
|
| 257 | 
		/// This method decreases the priority of \c item to \c value.  | 
|
| 258 | 
		/// \pre \c item must be stored in the heap with priority at least \c  | 
|
| 259 | 
		/// value relative to \c Compare.  | 
|
| 260 | 
		    void decrease (Item item, const Prio& value) {
	 | 
|
| 261 | 
		int i=_iim[item];  | 
|
| 262 | 
		_data[i].prio=value;  | 
|
| 263 | 
		int p=_data[i].parent;  | 
|
| 264 | 
		 | 
|
| 265 | 
		      if ( p!=-1 && _comp(value, _data[p].prio) ) {
	 | 
|
| 266 | 
		cut(i,p);  | 
|
| 267 | 
		cascade(p);  | 
|
| 268 | 
		}  | 
|
| 269 | 
		if ( _comp(value, _data[_minimum].prio) ) _minimum=i;  | 
|
| 270 | 
		}  | 
|
| 271 | 
		 | 
|
| 272 | 
		/// \brief Increases the priority of \c item to \c value.  | 
|
| 273 | 
		///  | 
|
| 274 | 
		/// This method sets the priority of \c item to \c value. Though  | 
|
| 275 | 
		/// there is no precondition on the priority of \c item, this  | 
|
| 276 | 
		/// method should be used only if it is indeed necessary to increase  | 
|
| 277 | 
		/// (relative to \c Compare) the priority of \c item, because this  | 
|
| 278 | 
		/// method is inefficient.  | 
|
| 279 | 
		    void increase (Item item, const Prio& value) {
	 | 
|
| 280 | 
		erase(item);  | 
|
| 281 | 
		push(item, value);  | 
|
| 282 | 
		}  | 
|
| 283 | 
		 | 
|
| 284 | 
		 | 
|
| 285 | 
		/// \brief Returns if \c item is in, has already been in, or has never  | 
|
| 286 | 
		/// been in the heap.  | 
|
| 287 | 
		///  | 
|
| 288 | 
		/// This method returns PRE_HEAP if \c item has never been in the  | 
|
| 289 | 
		/// heap, IN_HEAP if it is in the heap at the moment, and POST_HEAP  | 
|
| 290 | 
		/// otherwise. In the latter case it is possible that \c item will  | 
|
| 291 | 
		/// get back to the heap again.  | 
|
| 292 | 
		    State state(const Item &item) const {
	 | 
|
| 293 | 
		int i=_iim[item];  | 
|
| 294 | 
		      if( i>=0 ) {
	 | 
|
| 295 | 
		if ( _data[i].in ) i=0;  | 
|
| 296 | 
		else i=-2;  | 
|
| 297 | 
		}  | 
|
| 298 | 
		return State(i);  | 
|
| 299 | 
		}  | 
|
| 300 | 
		 | 
|
| 301 | 
		/// \brief Sets the state of the \c item in the heap.  | 
|
| 302 | 
		///  | 
|
| 303 | 
		/// Sets the state of the \c item in the heap. It can be used to  | 
|
| 304 | 
		/// manually clear the heap when it is important to achive the  | 
|
| 305 | 
		/// better time _complexity.  | 
|
| 306 | 
		/// \param i The item.  | 
|
| 307 | 
		/// \param st The state. It should not be \c IN_HEAP.  | 
|
| 308 | 
		    void state(const Item& i, State st) {
	 | 
|
| 309 | 
		      switch (st) {
	 | 
|
| 310 | 
		case POST_HEAP:  | 
|
| 311 | 
		case PRE_HEAP:  | 
|
| 312 | 
		        if (state(i) == IN_HEAP) {
	 | 
|
| 313 | 
		erase(i);  | 
|
| 314 | 
		}  | 
|
| 315 | 
		_iim[i] = st;  | 
|
| 316 | 
		break;  | 
|
| 317 | 
		case IN_HEAP:  | 
|
| 318 | 
		break;  | 
|
| 319 | 
		}  | 
|
| 320 | 
		}  | 
|
| 321 | 
		 | 
|
| 322 | 
		private:  | 
|
| 323 | 
		 | 
|
| 324 | 
		    void balance() {
	 | 
|
| 325 | 
		 | 
|
| 326 | 
		int maxdeg=int( std::floor( 2.08*log(double(_data.size()))))+1;  | 
|
| 327 | 
		 | 
|
| 328 | 
		std::vector<int> A(maxdeg,-1);  | 
|
| 329 | 
		 | 
|
| 330 | 
		/*  | 
|
| 331 | 
		*Recall that now minimum does not point to the minimum prio element.  | 
|
| 332 | 
		*We set minimum to this during balance().  | 
|
| 333 | 
		*/  | 
|
| 334 | 
		int anchor=_data[_minimum].left_neighbor;  | 
|
| 335 | 
		int next=_minimum;  | 
|
| 336 | 
		bool end=false;  | 
|
| 337 | 
		 | 
|
| 338 | 
		      do {
	 | 
|
| 339 | 
		int active=next;  | 
|
| 340 | 
		if ( anchor==active ) end=true;  | 
|
| 341 | 
		int d=_data[active].degree;  | 
|
| 342 | 
		next=_data[active].right_neighbor;  | 
|
| 343 | 
		 | 
|
| 344 | 
		        while (A[d]!=-1) {
	 | 
|
| 345 | 
		          if( _comp(_data[active].prio, _data[A[d]].prio) ) {
	 | 
|
| 346 | 
		fuse(active,A[d]);  | 
|
| 347 | 
		          } else {
	 | 
|
| 348 | 
		fuse(A[d],active);  | 
|
| 349 | 
		active=A[d];  | 
|
| 350 | 
		}  | 
|
| 351 | 
		A[d]=-1;  | 
|
| 352 | 
		++d;  | 
|
| 353 | 
		}  | 
|
| 354 | 
		A[d]=active;  | 
|
| 355 | 
		} while ( !end );  | 
|
| 356 | 
		 | 
|
| 357 | 
		 | 
|
| 358 | 
		while ( _data[_minimum].parent >=0 )  | 
|
| 359 | 
		_minimum=_data[_minimum].parent;  | 
|
| 360 | 
		int s=_minimum;  | 
|
| 361 | 
		int m=_minimum;  | 
|
| 362 | 
		      do {
	 | 
|
| 363 | 
		if ( _comp(_data[s].prio, _data[_minimum].prio) ) _minimum=s;  | 
|
| 364 | 
		s=_data[s].right_neighbor;  | 
|
| 365 | 
		} while ( s != m );  | 
|
| 366 | 
		}  | 
|
| 367 | 
		 | 
|
| 368 | 
		    void makeroot(int c) {
	 | 
|
| 369 | 
		int s=c;  | 
|
| 370 | 
		      do {
	 | 
|
| 371 | 
		_data[s].parent=-1;  | 
|
| 372 | 
		s=_data[s].right_neighbor;  | 
|
| 373 | 
		} while ( s != c );  | 
|
| 374 | 
		}  | 
|
| 375 | 
		 | 
|
| 376 | 
		    void cut(int a, int b) {
	 | 
|
| 377 | 
		/*  | 
|
| 378 | 
		*Replacing a from the children of b.  | 
|
| 379 | 
		*/  | 
|
| 380 | 
		--_data[b].degree;  | 
|
| 381 | 
		 | 
|
| 382 | 
		      if ( _data[b].degree !=0 ) {
	 | 
|
| 383 | 
		int child=_data[b].child;  | 
|
| 384 | 
		if ( child==a )  | 
|
| 385 | 
		_data[b].child=_data[child].right_neighbor;  | 
|
| 386 | 
		unlace(a);  | 
|
| 387 | 
		}  | 
|
| 388 | 
		 | 
|
| 389 | 
		 | 
|
| 390 | 
		/*Lacing a to the roots.*/  | 
|
| 391 | 
		int right=_data[_minimum].right_neighbor;  | 
|
| 392 | 
		_data[_minimum].right_neighbor=a;  | 
|
| 393 | 
		_data[a].left_neighbor=_minimum;  | 
|
| 394 | 
		_data[a].right_neighbor=right;  | 
|
| 395 | 
		_data[right].left_neighbor=a;  | 
|
| 396 | 
		 | 
|
| 397 | 
		_data[a].parent=-1;  | 
|
| 398 | 
		_data[a].marked=false;  | 
|
| 399 | 
		}  | 
|
| 400 | 
		 | 
|
| 401 | 
		    void cascade(int a) {
	 | 
|
| 402 | 
		      if ( _data[a].parent!=-1 ) {
	 | 
|
| 403 | 
		int p=_data[a].parent;  | 
|
| 404 | 
		 | 
|
| 405 | 
		if ( _data[a].marked==false ) _data[a].marked=true;  | 
|
| 406 | 
		        else {
	 | 
|
| 407 | 
		cut(a,p);  | 
|
| 408 | 
		cascade(p);  | 
|
| 409 | 
		}  | 
|
| 410 | 
		}  | 
|
| 411 | 
		}  | 
|
| 412 | 
		 | 
|
| 413 | 
		    void fuse(int a, int b) {
	 | 
|
| 414 | 
		unlace(b);  | 
|
| 415 | 
		 | 
|
| 416 | 
		/*Lacing b under a.*/  | 
|
| 417 | 
		_data[b].parent=a;  | 
|
| 418 | 
		 | 
|
| 419 | 
		      if (_data[a].degree==0) {
	 | 
|
| 420 | 
		_data[b].left_neighbor=b;  | 
|
| 421 | 
		_data[b].right_neighbor=b;  | 
|
| 422 | 
		_data[a].child=b;  | 
|
| 423 | 
		      } else {
	 | 
|
| 424 | 
		int child=_data[a].child;  | 
|
| 425 | 
		int last_child=_data[child].left_neighbor;  | 
|
| 426 | 
		_data[child].left_neighbor=b;  | 
|
| 427 | 
		_data[b].right_neighbor=child;  | 
|
| 428 | 
		_data[last_child].right_neighbor=b;  | 
|
| 429 | 
		_data[b].left_neighbor=last_child;  | 
|
| 430 | 
		}  | 
|
| 431 | 
		 | 
|
| 432 | 
		++_data[a].degree;  | 
|
| 433 | 
		 | 
|
| 434 | 
		_data[b].marked=false;  | 
|
| 435 | 
		}  | 
|
| 436 | 
		 | 
|
| 437 | 
		/*  | 
|
| 438 | 
		*It is invoked only if a has siblings.  | 
|
| 439 | 
		*/  | 
|
| 440 | 
		    void unlace(int a) {
	 | 
|
| 441 | 
		int leftn=_data[a].left_neighbor;  | 
|
| 442 | 
		int rightn=_data[a].right_neighbor;  | 
|
| 443 | 
		_data[leftn].right_neighbor=rightn;  | 
|
| 444 | 
		_data[rightn].left_neighbor=leftn;  | 
|
| 445 | 
		}  | 
|
| 446 | 
		 | 
|
| 447 | 
		 | 
|
| 448 | 
		    class Store {
	 | 
|
| 449 | 
		friend class FibHeap;  | 
|
| 450 | 
		 | 
|
| 451 | 
		Item name;  | 
|
| 452 | 
		int parent;  | 
|
| 453 | 
		int left_neighbor;  | 
|
| 454 | 
		int right_neighbor;  | 
|
| 455 | 
		int child;  | 
|
| 456 | 
		int degree;  | 
|
| 457 | 
		bool marked;  | 
|
| 458 | 
		bool in;  | 
|
| 459 | 
		Prio prio;  | 
|
| 460 | 
		 | 
|
| 461 | 
		      Store() : parent(-1), child(-1), degree(), marked(false), in(true) {}
	 | 
|
| 462 | 
		};  | 
|
| 463 | 
		};  | 
|
| 464 | 
		 | 
|
| 465 | 
		} //namespace lemon  | 
|
| 466 | 
		 | 
|
| 467 | 
		#endif //LEMON_FIB_HEAP_H  | 
|
| 468 | 
| 1 | 
		/* -*- mode: C++; indent-tabs-mode: nil; -*-  | 
|
| 2 | 
		*  | 
|
| 3 | 
		* This file is a part of LEMON, a generic C++ optimization library.  | 
|
| 4 | 
		*  | 
|
| 5 | 
		* Copyright (C) 2003-2009  | 
|
| 6 | 
		* Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport  | 
|
| 7 | 
		* (Egervary Research Group on Combinatorial Optimization, EGRES).  | 
|
| 8 | 
		*  | 
|
| 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.  | 
|
| 12 | 
		*  | 
|
| 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  | 
|
| 15 | 
		* purpose.  | 
|
| 16 | 
		*  | 
|
| 17 | 
		*/  | 
|
| 18 | 
		 | 
|
| 19 | 
		#ifndef LEMON_RADIX_HEAP_H  | 
|
| 20 | 
		#define LEMON_RADIX_HEAP_H  | 
|
| 21 | 
		 | 
|
| 22 | 
		///\ingroup auxdat  | 
|
| 23 | 
		///\file  | 
|
| 24 | 
		///\brief Radix Heap implementation.  | 
|
| 25 | 
		 | 
|
| 26 | 
		#include <vector>  | 
|
| 27 | 
		#include <lemon/error.h>  | 
|
| 28 | 
		 | 
|
| 29 | 
		namespace lemon {
	 | 
|
| 30 | 
		 | 
|
| 31 | 
		 | 
|
| 32 | 
		/// \ingroup auxdata  | 
|
| 33 | 
		///  | 
|
| 34 | 
		/// \brief A Radix Heap implementation.  | 
|
| 35 | 
		///  | 
|
| 36 | 
		/// This class implements the \e radix \e heap data structure. A \e heap  | 
|
| 37 | 
		/// is a data structure for storing items with specified values called \e  | 
|
| 38 | 
		/// priorities in such a way that finding the item with minimum priority is  | 
|
| 39 | 
		/// efficient. This heap type can store only items with \e int priority.  | 
|
| 40 | 
		/// In a heap one can change the priority of an item, add or erase an  | 
|
| 41 | 
		/// item, but the priority cannot be decreased under the last removed  | 
|
| 42 | 
		/// item's priority.  | 
|
| 43 | 
		///  | 
|
| 44 | 
		/// \param IM A read and writable Item int map, used internally  | 
|
| 45 | 
		/// to handle the cross references.  | 
|
| 46 | 
		///  | 
|
| 47 | 
		/// \see BinHeap  | 
|
| 48 | 
		/// \see Dijkstra  | 
|
| 49 | 
		template <typename IM>  | 
|
| 50 | 
		  class RadixHeap {
	 | 
|
| 51 | 
		 | 
|
| 52 | 
		public:  | 
|
| 53 | 
		typedef typename IM::Key Item;  | 
|
| 54 | 
		typedef int Prio;  | 
|
| 55 | 
		typedef IM ItemIntMap;  | 
|
| 56 | 
		 | 
|
| 57 | 
		/// \brief Exception thrown by RadixHeap.  | 
|
| 58 | 
		///  | 
|
| 59 | 
		/// This Exception is thrown when a smaller priority  | 
|
| 60 | 
		/// is inserted into the \e RadixHeap then the last time erased.  | 
|
| 61 | 
		/// \see RadixHeap  | 
|
| 62 | 
		 | 
|
| 63 | 
		    class UnderFlowPriorityError : public Exception {
	 | 
|
| 64 | 
		public:  | 
|
| 65 | 
		      virtual const char* what() const throw() {
	 | 
|
| 66 | 
		return "lemon::RadixHeap::UnderFlowPriorityError";  | 
|
| 67 | 
		}  | 
|
| 68 | 
		};  | 
|
| 69 | 
		 | 
|
| 70 | 
		/// \brief Type to represent the items states.  | 
|
| 71 | 
		///  | 
|
| 72 | 
		/// Each Item element have a state associated to it. It may be "in heap",  | 
|
| 73 | 
		/// "pre heap" or "post heap". The latter two are indifferent from the  | 
|
| 74 | 
		/// heap's point of view, but may be useful to the user.  | 
|
| 75 | 
		///  | 
|
| 76 | 
		/// The ItemIntMap \e should be initialized in such way that it maps  | 
|
| 77 | 
		/// PRE_HEAP (-1) to any element to be put in the heap...  | 
|
| 78 | 
		    enum State {
	 | 
|
| 79 | 
		IN_HEAP = 0,  | 
|
| 80 | 
		PRE_HEAP = -1,  | 
|
| 81 | 
		POST_HEAP = -2  | 
|
| 82 | 
		};  | 
|
| 83 | 
		 | 
|
| 84 | 
		private:  | 
|
| 85 | 
		 | 
|
| 86 | 
		    struct RadixItem {
	 | 
|
| 87 | 
		int prev, next, box;  | 
|
| 88 | 
		Item item;  | 
|
| 89 | 
		int prio;  | 
|
| 90 | 
		      RadixItem(Item _item, int _prio) : item(_item), prio(_prio) {}
	 | 
|
| 91 | 
		};  | 
|
| 92 | 
		 | 
|
| 93 | 
		    struct RadixBox {
	 | 
|
| 94 | 
		int first;  | 
|
| 95 | 
		int min, size;  | 
|
| 96 | 
		      RadixBox(int _min, int _size) : first(-1), min(_min), size(_size) {}
	 | 
|
| 97 | 
		};  | 
|
| 98 | 
		 | 
|
| 99 | 
		std::vector<RadixItem> data;  | 
|
| 100 | 
		std::vector<RadixBox> boxes;  | 
|
| 101 | 
		 | 
|
| 102 | 
		ItemIntMap &_iim;  | 
|
| 103 | 
		 | 
|
| 104 | 
		 | 
|
| 105 | 
		public:  | 
|
| 106 | 
		/// \brief The constructor.  | 
|
| 107 | 
		///  | 
|
| 108 | 
		/// The constructor.  | 
|
| 109 | 
		///  | 
|
| 110 | 
		/// \param map It should be given to the constructor, since it is used  | 
|
| 111 | 
		/// internally to handle the cross references. The value of the map  | 
|
| 112 | 
		/// should be PRE_HEAP (-1) for each element.  | 
|
| 113 | 
		///  | 
|
| 114 | 
		/// \param minimal The initial minimal value of the heap.  | 
|
| 115 | 
		/// \param capacity It determines the initial capacity of the heap.  | 
|
| 116 | 
		RadixHeap(ItemIntMap &map, int minimal = 0, int capacity = 0)  | 
|
| 117 | 
		      : _iim(map) {
	 | 
|
| 118 | 
		boxes.push_back(RadixBox(minimal, 1));  | 
|
| 119 | 
		boxes.push_back(RadixBox(minimal + 1, 1));  | 
|
| 120 | 
		      while (lower(boxes.size() - 1, capacity + minimal - 1)) {
	 | 
|
| 121 | 
		extend();  | 
|
| 122 | 
		}  | 
|
| 123 | 
		}  | 
|
| 124 | 
		 | 
|
| 125 | 
		/// The number of items stored in the heap.  | 
|
| 126 | 
		///  | 
|
| 127 | 
		/// \brief Returns the number of items stored in the heap.  | 
|
| 128 | 
		    int size() const { return data.size(); }
	 | 
|
| 129 | 
		/// \brief Checks if the heap stores no items.  | 
|
| 130 | 
		///  | 
|
| 131 | 
		/// Returns \c true if and only if the heap stores no items.  | 
|
| 132 | 
		    bool empty() const { return data.empty(); }
	 | 
|
| 133 | 
		 | 
|
| 134 | 
		/// \brief Make empty this heap.  | 
|
| 135 | 
		///  | 
|
| 136 | 
		/// Make empty this heap. It does not change the cross reference  | 
|
| 137 | 
		/// map. If you want to reuse a heap what is not surely empty you  | 
|
| 138 | 
		/// should first clear the heap and after that you should set the  | 
|
| 139 | 
		/// cross reference map for each item to \c PRE_HEAP.  | 
|
| 140 | 
		    void clear(int minimal = 0, int capacity = 0) {
	 | 
|
| 141 | 
		data.clear(); boxes.clear();  | 
|
| 142 | 
		boxes.push_back(RadixBox(minimal, 1));  | 
|
| 143 | 
		boxes.push_back(RadixBox(minimal + 1, 1));  | 
|
| 144 | 
		      while (lower(boxes.size() - 1, capacity + minimal - 1)) {
	 | 
|
| 145 | 
		extend();  | 
|
| 146 | 
		}  | 
|
| 147 | 
		}  | 
|
| 148 | 
		 | 
|
| 149 | 
		private:  | 
|
| 150 | 
		 | 
|
| 151 | 
		    bool upper(int box, Prio pr) {
	 | 
|
| 152 | 
		return pr < boxes[box].min;  | 
|
| 153 | 
		}  | 
|
| 154 | 
		 | 
|
| 155 | 
		    bool lower(int box, Prio pr) {
	 | 
|
| 156 | 
		return pr >= boxes[box].min + boxes[box].size;  | 
|
| 157 | 
		}  | 
|
| 158 | 
		 | 
|
| 159 | 
		/// \brief Remove item from the box list.  | 
|
| 160 | 
		    void remove(int index) {
	 | 
|
| 161 | 
		      if (data[index].prev >= 0) {
	 | 
|
| 162 | 
		data[data[index].prev].next = data[index].next;  | 
|
| 163 | 
		      } else {
	 | 
|
| 164 | 
		boxes[data[index].box].first = data[index].next;  | 
|
| 165 | 
		}  | 
|
| 166 | 
		      if (data[index].next >= 0) {
	 | 
|
| 167 | 
		data[data[index].next].prev = data[index].prev;  | 
|
| 168 | 
		}  | 
|
| 169 | 
		}  | 
|
| 170 | 
		 | 
|
| 171 | 
		/// \brief Insert item into the box list.  | 
|
| 172 | 
		    void insert(int box, int index) {
	 | 
|
| 173 | 
		      if (boxes[box].first == -1) {
	 | 
|
| 174 | 
		boxes[box].first = index;  | 
|
| 175 | 
		data[index].next = data[index].prev = -1;  | 
|
| 176 | 
		      } else {
	 | 
|
| 177 | 
		data[index].next = boxes[box].first;  | 
|
| 178 | 
		data[boxes[box].first].prev = index;  | 
|
| 179 | 
		data[index].prev = -1;  | 
|
| 180 | 
		boxes[box].first = index;  | 
|
| 181 | 
		}  | 
|
| 182 | 
		data[index].box = box;  | 
|
| 183 | 
		}  | 
|
| 184 | 
		 | 
|
| 185 | 
		/// \brief Add a new box to the box list.  | 
|
| 186 | 
		    void extend() {
	 | 
|
| 187 | 
		int min = boxes.back().min + boxes.back().size;  | 
|
| 188 | 
		int bs = 2 * boxes.back().size;  | 
|
| 189 | 
		boxes.push_back(RadixBox(min, bs));  | 
|
| 190 | 
		}  | 
|
| 191 | 
		 | 
|
| 192 | 
		/// \brief Move an item up into the proper box.  | 
|
| 193 | 
		    void bubble_up(int index) {
	 | 
|
| 194 | 
		if (!lower(data[index].box, data[index].prio)) return;  | 
|
| 195 | 
		remove(index);  | 
|
| 196 | 
		int box = findUp(data[index].box, data[index].prio);  | 
|
| 197 | 
		insert(box, index);  | 
|
| 198 | 
		}  | 
|
| 199 | 
		 | 
|
| 200 | 
		/// \brief Find up the proper box for the item with the given prio.  | 
|
| 201 | 
		    int findUp(int start, int pr) {
	 | 
|
| 202 | 
		      while (lower(start, pr)) {
	 | 
|
| 203 | 
		        if (++start == int(boxes.size())) {
	 | 
|
| 204 | 
		extend();  | 
|
| 205 | 
		}  | 
|
| 206 | 
		}  | 
|
| 207 | 
		return start;  | 
|
| 208 | 
		}  | 
|
| 209 | 
		 | 
|
| 210 | 
		/// \brief Move an item down into the proper box.  | 
|
| 211 | 
		    void bubble_down(int index) {
	 | 
|
| 212 | 
		if (!upper(data[index].box, data[index].prio)) return;  | 
|
| 213 | 
		remove(index);  | 
|
| 214 | 
		int box = findDown(data[index].box, data[index].prio);  | 
|
| 215 | 
		insert(box, index);  | 
|
| 216 | 
		}  | 
|
| 217 | 
		 | 
|
| 218 | 
		/// \brief Find up the proper box for the item with the given prio.  | 
|
| 219 | 
		    int findDown(int start, int pr) {
	 | 
|
| 220 | 
		      while (upper(start, pr)) {
	 | 
|
| 221 | 
		if (--start < 0) throw UnderFlowPriorityError();  | 
|
| 222 | 
		}  | 
|
| 223 | 
		return start;  | 
|
| 224 | 
		}  | 
|
| 225 | 
		 | 
|
| 226 | 
		/// \brief Find the first not empty box.  | 
|
| 227 | 
		    int findFirst() {
	 | 
|
| 228 | 
		int first = 0;  | 
|
| 229 | 
		while (boxes[first].first == -1) ++first;  | 
|
| 230 | 
		return first;  | 
|
| 231 | 
		}  | 
|
| 232 | 
		 | 
|
| 233 | 
		/// \brief Gives back the minimal prio of the box.  | 
|
| 234 | 
		    int minValue(int box) {
	 | 
|
| 235 | 
		int min = data[boxes[box].first].prio;  | 
|
| 236 | 
		      for (int k = boxes[box].first; k != -1; k = data[k].next) {
	 | 
|
| 237 | 
		if (data[k].prio < min) min = data[k].prio;  | 
|
| 238 | 
		}  | 
|
| 239 | 
		return min;  | 
|
| 240 | 
		}  | 
|
| 241 | 
		 | 
|
| 242 | 
		/// \brief Rearrange the items of the heap and makes the  | 
|
| 243 | 
		/// first box not empty.  | 
|
| 244 | 
		    void moveDown() {
	 | 
|
| 245 | 
		int box = findFirst();  | 
|
| 246 | 
		if (box == 0) return;  | 
|
| 247 | 
		int min = minValue(box);  | 
|
| 248 | 
		      for (int i = 0; i <= box; ++i) {
	 | 
|
| 249 | 
		boxes[i].min = min;  | 
|
| 250 | 
		min += boxes[i].size;  | 
|
| 251 | 
		}  | 
|
| 252 | 
		int curr = boxes[box].first, next;  | 
|
| 253 | 
		      while (curr != -1) {
	 | 
|
| 254 | 
		next = data[curr].next;  | 
|
| 255 | 
		bubble_down(curr);  | 
|
| 256 | 
		curr = next;  | 
|
| 257 | 
		}  | 
|
| 258 | 
		}  | 
|
| 259 | 
		 | 
|
| 260 | 
		    void relocate_last(int index) {
	 | 
|
| 261 | 
		      if (index != int(data.size()) - 1) {
	 | 
|
| 262 | 
		data[index] = data.back();  | 
|
| 263 | 
		        if (data[index].prev != -1) {
	 | 
|
| 264 | 
		data[data[index].prev].next = index;  | 
|
| 265 | 
		        } else {
	 | 
|
| 266 | 
		boxes[data[index].box].first = index;  | 
|
| 267 | 
		}  | 
|
| 268 | 
		        if (data[index].next != -1) {
	 | 
|
| 269 | 
		data[data[index].next].prev = index;  | 
|
| 270 | 
		}  | 
|
| 271 | 
		_iim[data[index].item] = index;  | 
|
| 272 | 
		}  | 
|
| 273 | 
		data.pop_back();  | 
|
| 274 | 
		}  | 
|
| 275 | 
		 | 
|
| 276 | 
		public:  | 
|
| 277 | 
		 | 
|
| 278 | 
		/// \brief Insert an item into the heap with the given priority.  | 
|
| 279 | 
		///  | 
|
| 280 | 
		/// Adds \c i to the heap with priority \c p.  | 
|
| 281 | 
		/// \param i The item to insert.  | 
|
| 282 | 
		/// \param p The priority of the item.  | 
|
| 283 | 
		    void push(const Item &i, const Prio &p) {
	 | 
|
| 284 | 
		int n = data.size();  | 
|
| 285 | 
		_iim.set(i, n);  | 
|
| 286 | 
		data.push_back(RadixItem(i, p));  | 
|
| 287 | 
		      while (lower(boxes.size() - 1, p)) {
	 | 
|
| 288 | 
		extend();  | 
|
| 289 | 
		}  | 
|
| 290 | 
		int box = findDown(boxes.size() - 1, p);  | 
|
| 291 | 
		insert(box, n);  | 
|
| 292 | 
		}  | 
|
| 293 | 
		 | 
|
| 294 | 
		/// \brief Returns the item with minimum priority.  | 
|
| 295 | 
		///  | 
|
| 296 | 
		/// This method returns the item with minimum priority.  | 
|
| 297 | 
		/// \pre The heap must be nonempty.  | 
|
| 298 | 
		    Item top() const {
	 | 
|
| 299 | 
		const_cast<RadixHeap<ItemIntMap>&>(*this).moveDown();  | 
|
| 300 | 
		return data[boxes[0].first].item;  | 
|
| 301 | 
		}  | 
|
| 302 | 
		 | 
|
| 303 | 
		/// \brief Returns the minimum priority.  | 
|
| 304 | 
		///  | 
|
| 305 | 
		/// It returns the minimum priority.  | 
|
| 306 | 
		/// \pre The heap must be nonempty.  | 
|
| 307 | 
		    Prio prio() const {
	 | 
|
| 308 | 
		const_cast<RadixHeap<ItemIntMap>&>(*this).moveDown();  | 
|
| 309 | 
		return data[boxes[0].first].prio;  | 
|
| 310 | 
		}  | 
|
| 311 | 
		 | 
|
| 312 | 
		/// \brief Deletes the item with minimum priority.  | 
|
| 313 | 
		///  | 
|
| 314 | 
		/// This method deletes the item with minimum priority.  | 
|
| 315 | 
		/// \pre The heap must be non-empty.  | 
|
| 316 | 
		    void pop() {
	 | 
|
| 317 | 
		moveDown();  | 
|
| 318 | 
		int index = boxes[0].first;  | 
|
| 319 | 
		_iim[data[index].item] = POST_HEAP;  | 
|
| 320 | 
		remove(index);  | 
|
| 321 | 
		relocate_last(index);  | 
|
| 322 | 
		}  | 
|
| 323 | 
		 | 
|
| 324 | 
		/// \brief Deletes \c i from the heap.  | 
|
| 325 | 
		///  | 
|
| 326 | 
		/// This method deletes item \c i from the heap, if \c i was  | 
|
| 327 | 
		/// already stored in the heap.  | 
|
| 328 | 
		/// \param i The item to erase.  | 
|
| 329 | 
		    void erase(const Item &i) {
	 | 
|
| 330 | 
		int index = _iim[i];  | 
|
| 331 | 
		_iim[i] = POST_HEAP;  | 
|
| 332 | 
		remove(index);  | 
|
| 333 | 
		relocate_last(index);  | 
|
| 334 | 
		}  | 
|
| 335 | 
		 | 
|
| 336 | 
		/// \brief Returns the priority of \c i.  | 
|
| 337 | 
		///  | 
|
| 338 | 
		/// This function returns the priority of item \c i.  | 
|
| 339 | 
		/// \pre \c i must be in the heap.  | 
|
| 340 | 
		/// \param i The item.  | 
|
| 341 | 
		    Prio operator[](const Item &i) const {
	 | 
|
| 342 | 
		int idx = _iim[i];  | 
|
| 343 | 
		return data[idx].prio;  | 
|
| 344 | 
		}  | 
|
| 345 | 
		 | 
|
| 346 | 
		/// \brief \c i gets to the heap with priority \c p independently  | 
|
| 347 | 
		/// if \c i was already there.  | 
|
| 348 | 
		///  | 
|
| 349 | 
		/// This method calls \ref push(\c i, \c p) if \c i is not stored  | 
|
| 350 | 
		/// in the heap and sets the priority of \c i to \c p otherwise.  | 
|
| 351 | 
		/// It may throw an \e UnderFlowPriorityException.  | 
|
| 352 | 
		/// \param i The item.  | 
|
| 353 | 
		/// \param p The priority.  | 
|
| 354 | 
		    void set(const Item &i, const Prio &p) {
	 | 
|
| 355 | 
		int idx = _iim[i];  | 
|
| 356 | 
		      if( idx < 0 ) {
	 | 
|
| 357 | 
		push(i, p);  | 
|
| 358 | 
		}  | 
|
| 359 | 
		      else if( p >= data[idx].prio ) {
	 | 
|
| 360 | 
		data[idx].prio = p;  | 
|
| 361 | 
		bubble_up(idx);  | 
|
| 362 | 
		      } else {
	 | 
|
| 363 | 
		data[idx].prio = p;  | 
|
| 364 | 
		bubble_down(idx);  | 
|
| 365 | 
		}  | 
|
| 366 | 
		}  | 
|
| 367 | 
		 | 
|
| 368 | 
		 | 
|
| 369 | 
		/// \brief Decreases the priority of \c i to \c p.  | 
|
| 370 | 
		///  | 
|
| 371 | 
		/// This method decreases the priority of item \c i to \c p.  | 
|
| 372 | 
		/// \pre \c i must be stored in the heap with priority at least \c p, and  | 
|
| 373 | 
		/// \c should be greater or equal to the last removed item's priority.  | 
|
| 374 | 
		/// \param i The item.  | 
|
| 375 | 
		/// \param p The priority.  | 
|
| 376 | 
		    void decrease(const Item &i, const Prio &p) {
	 | 
|
| 377 | 
		int idx = _iim[i];  | 
|
| 378 | 
		data[idx].prio = p;  | 
|
| 379 | 
		bubble_down(idx);  | 
|
| 380 | 
		}  | 
|
| 381 | 
		 | 
|
| 382 | 
		/// \brief Increases the priority of \c i to \c p.  | 
|
| 383 | 
		///  | 
|
| 384 | 
		/// This method sets the priority of item \c i to \c p.  | 
|
| 385 | 
		/// \pre \c i must be stored in the heap with priority at most \c p  | 
|
| 386 | 
		/// \param i The item.  | 
|
| 387 | 
		/// \param p The priority.  | 
|
| 388 | 
		    void increase(const Item &i, const Prio &p) {
	 | 
|
| 389 | 
		int idx = _iim[i];  | 
|
| 390 | 
		data[idx].prio = p;  | 
|
| 391 | 
		bubble_up(idx);  | 
|
| 392 | 
		}  | 
|
| 393 | 
		 | 
|
| 394 | 
		/// \brief Returns if \c item is in, has already been in, or has  | 
|
| 395 | 
		/// never been in the heap.  | 
|
| 396 | 
		///  | 
|
| 397 | 
		/// This method returns PRE_HEAP if \c item has never been in the  | 
|
| 398 | 
		/// heap, IN_HEAP if it is in the heap at the moment, and POST_HEAP  | 
|
| 399 | 
		/// otherwise. In the latter case it is possible that \c item will  | 
|
| 400 | 
		/// get back to the heap again.  | 
|
| 401 | 
		/// \param i The item.  | 
|
| 402 | 
		    State state(const Item &i) const {
	 | 
|
| 403 | 
		int s = _iim[i];  | 
|
| 404 | 
		if( s >= 0 ) s = 0;  | 
|
| 405 | 
		return State(s);  | 
|
| 406 | 
		}  | 
|
| 407 | 
		 | 
|
| 408 | 
		/// \brief Sets the state of the \c item in the heap.  | 
|
| 409 | 
		///  | 
|
| 410 | 
		/// Sets the state of the \c item in the heap. It can be used to  | 
|
| 411 | 
		/// manually clear the heap when it is important to achive the  | 
|
| 412 | 
		/// better time complexity.  | 
|
| 413 | 
		/// \param i The item.  | 
|
| 414 | 
		/// \param st The state. It should not be \c IN_HEAP.  | 
|
| 415 | 
		    void state(const Item& i, State st) {
	 | 
|
| 416 | 
		      switch (st) {
	 | 
|
| 417 | 
		case POST_HEAP:  | 
|
| 418 | 
		case PRE_HEAP:  | 
|
| 419 | 
		        if (state(i) == IN_HEAP) {
	 | 
|
| 420 | 
		erase(i);  | 
|
| 421 | 
		}  | 
|
| 422 | 
		_iim[i] = st;  | 
|
| 423 | 
		break;  | 
|
| 424 | 
		case IN_HEAP:  | 
|
| 425 | 
		break;  | 
|
| 426 | 
		}  | 
|
| 427 | 
		}  | 
|
| 428 | 
		 | 
|
| 429 | 
		}; // class RadixHeap  | 
|
| 430 | 
		 | 
|
| 431 | 
		} // namespace lemon  | 
|
| 432 | 
		 | 
|
| 433 | 
		#endif // LEMON_RADIX_HEAP_H  | 
| ... | ... | 
		@@ -59,6 +59,7 @@  | 
| 59 | 59 | 
		lemon/assert.h \  | 
| 60 | 60 | 
		lemon/bfs.h \  | 
| 61 | 61 | 
		lemon/bin_heap.h \  | 
| 62 | 
		lemon/bucket_heap.h \  | 
|
| 62 | 63 | 
		lemon/cbc.h \  | 
| 63 | 64 | 
		lemon/circulation.h \  | 
| 64 | 65 | 
		lemon/clp.h \  | 
| ... | ... | 
		@@ -76,6 +77,7 @@  | 
| 76 | 77 | 
		lemon/elevator.h \  | 
| 77 | 78 | 
		lemon/error.h \  | 
| 78 | 79 | 
		lemon/euler.h \  | 
| 80 | 
		lemon/fib_heap.h \  | 
|
| 79 | 81 | 
		lemon/full_graph.h \  | 
| 80 | 82 | 
		lemon/glpk.h \  | 
| 81 | 83 | 
		lemon/gomory_hu.h \  | 
| ... | ... | 
		@@ -99,6 +101,7 @@  | 
| 99 | 101 | 
		lemon/network_simplex.h \  | 
| 100 | 102 | 
		lemon/path.h \  | 
| 101 | 103 | 
		lemon/preflow.h \  | 
| 104 | 
		lemon/radix_heap.h \  | 
|
| 102 | 105 | 
		lemon/radix_sort.h \  | 
| 103 | 106 | 
		lemon/random.h \  | 
| 104 | 107 | 
		lemon/smart_graph.h \  | 
| ... | ... | 
		@@ -33,23 +33,23 @@  | 
| 33 | 33 | 
		///  | 
| 34 | 34 | 
		///\brief A Binary Heap implementation.  | 
| 35 | 35 | 
		///  | 
| 36 | 
		///This class implements the \e binary \e heap data structure.  | 
|
| 37 | 
		///  | 
|
| 36 | 
		///This class implements the \e binary \e heap data structure.  | 
|
| 37 | 
		///  | 
|
| 38 | 38 | 
		///A \e heap is a data structure for storing items with specified values  | 
| 39 | 39 | 
		///called \e priorities in such a way that finding the item with minimum  | 
| 40 | 
		///priority is efficient. \c  | 
|
| 40 | 
		///priority is efficient. \c CMP specifies the ordering of the priorities.  | 
|
| 41 | 41 | 
		///In a heap one can change the priority of an item, add or erase an  | 
| 42 | 42 | 
		///item, etc.  | 
| 43 | 43 | 
		///  | 
| 44 | 44 | 
		///\tparam PR Type of the priority of the items.  | 
| 45 | 45 | 
		///\tparam IM A read and writable item map with int values, used internally  | 
| 46 | 46 | 
		///to handle the cross references.  | 
| 47 | 
		///\tparam  | 
|
| 47 | 
		///\tparam CMP A functor class for the ordering of the priorities.  | 
|
| 48 | 48 | 
		///The default is \c std::less<PR>.  | 
| 49 | 49 | 
		///  | 
| 50 | 50 | 
		///\sa FibHeap  | 
| 51 | 51 | 
		///\sa Dijkstra  | 
| 52 | 
		template <typename PR, typename IM, typename  | 
|
| 52 | 
		template <typename PR, typename IM, typename CMP = std::less<PR> >  | 
|
| 53 | 53 | 
		  class BinHeap {
	 | 
| 54 | 54 | 
		 | 
| 55 | 55 | 
		public:  | 
| ... | ... | 
		@@ -62,7 +62,7 @@  | 
| 62 | 62 | 
		///\e  | 
| 63 | 63 | 
		typedef std::pair<Item,Prio> Pair;  | 
| 64 | 64 | 
		///\e  | 
| 65 | 
		typedef  | 
|
| 65 | 
		typedef CMP Compare;  | 
|
| 66 | 66 | 
		 | 
| 67 | 67 | 
		/// \brief Type to represent the items states.  | 
| 68 | 68 | 
		///  | 
| ... | ... | 
		@@ -22,6 +22,7 @@  | 
| 22 | 22 | 
		#include <iterator>  | 
| 23 | 23 | 
		#include <functional>  | 
| 24 | 24 | 
		#include <vector>  | 
| 25 | 
		#include <map>  | 
|
| 25 | 26 | 
		 | 
| 26 | 27 | 
		#include <lemon/core.h>  | 
| 27 | 28 | 
		 | 
| ... | ... | 
		@@ -29,8 +30,6 @@  | 
| 29 | 30 | 
		///\ingroup maps  | 
| 30 | 31 | 
		///\brief Miscellaneous property maps  | 
| 31 | 32 | 
		 | 
| 32 | 
		#include <map>  | 
|
| 33 | 
		 | 
|
| 34 | 33 | 
		namespace lemon {
	 | 
| 35 | 34 | 
		 | 
| 36 | 35 | 
		/// \addtogroup maps  | 
| ... | ... | 
		@@ -1818,7 +1817,7 @@  | 
| 1818 | 1817 | 
		/// \brief Provides an immutable and unique id for each item in a graph.  | 
| 1819 | 1818 | 
		///  | 
| 1820 | 1819 | 
		/// IdMap provides a unique and immutable id for each item of the  | 
| 1821 | 
		/// same type (\c Node, \c Arc or \c Edge) in a graph. This id is  | 
|
| 1820 | 
		/// same type (\c Node, \c Arc or \c Edge) in a graph. This id is  | 
|
| 1822 | 1821 | 
		/// - \b unique: different items get different ids,  | 
| 1823 | 1822 | 
		/// - \b immutable: the id of an item does not change (even if you  | 
| 1824 | 1823 | 
		/// delete other nodes).  | 
| ... | ... | 
		@@ -2281,7 +2280,7 @@  | 
| 2281 | 2280 | 
		}  | 
| 2282 | 2281 | 
		 | 
| 2283 | 2282 | 
		/// \brief Gives back the item belonging to a \e RangeId  | 
| 2284 | 
		///  | 
|
| 2283 | 
		///  | 
|
| 2285 | 2284 | 
		/// Gives back the item belonging to a \e RangeId.  | 
| 2286 | 2285 | 
		    Item operator()(int id) const {
	 | 
| 2287 | 2286 | 
		return _inv_map[id];  | 
| ... | ... | 
		@@ -2338,6 +2337,903 @@  | 
| 2338 | 2337 | 
		}  | 
| 2339 | 2338 | 
		};  | 
| 2340 | 2339 | 
		 | 
| 2340 | 
		/// \brief Dynamic iterable \c bool map.  | 
|
| 2341 | 
		///  | 
|
| 2342 | 
		/// This class provides a special graph map type which can store a  | 
|
| 2343 | 
		/// \c bool value for graph items (\c Node, \c Arc or \c Edge).  | 
|
| 2344 | 
		/// For both \c true and \c false values it is possible to iterate on  | 
|
| 2345 | 
		/// the keys.  | 
|
| 2346 | 
		///  | 
|
| 2347 | 
		/// This type is a reference map, so it can be modified with the  | 
|
| 2348 | 
		/// subscription operator.  | 
|
| 2349 | 
		///  | 
|
| 2350 | 
		/// \tparam GR The graph type.  | 
|
| 2351 | 
		/// \tparam K The key type of the map (\c GR::Node, \c GR::Arc or  | 
|
| 2352 | 
		/// \c GR::Edge).  | 
|
| 2353 | 
		///  | 
|
| 2354 | 
		/// \see IterableIntMap, IterableValueMap  | 
|
| 2355 | 
		/// \see CrossRefMap  | 
|
| 2356 | 
		template <typename GR, typename K>  | 
|
| 2357 | 
		class IterableBoolMap  | 
|
| 2358 | 
		    : protected ItemSetTraits<GR, K>::template Map<int>::Type {
	 | 
|
| 2359 | 
		private:  | 
|
| 2360 | 
		typedef GR Graph;  | 
|
| 2361 | 
		 | 
|
| 2362 | 
		typedef typename ItemSetTraits<GR, K>::ItemIt KeyIt;  | 
|
| 2363 | 
		typedef typename ItemSetTraits<GR, K>::template Map<int>::Type Parent;  | 
|
| 2364 | 
		 | 
|
| 2365 | 
		std::vector<K> _array;  | 
|
| 2366 | 
		int _sep;  | 
|
| 2367 | 
		 | 
|
| 2368 | 
		public:  | 
|
| 2369 | 
		 | 
|
| 2370 | 
		/// Indicates that the map is reference map.  | 
|
| 2371 | 
		typedef True ReferenceMapTag;  | 
|
| 2372 | 
		 | 
|
| 2373 | 
		/// The key type  | 
|
| 2374 | 
		typedef K Key;  | 
|
| 2375 | 
		/// The value type  | 
|
| 2376 | 
		typedef bool Value;  | 
|
| 2377 | 
		/// The const reference type.  | 
|
| 2378 | 
		typedef const Value& ConstReference;  | 
|
| 2379 | 
		 | 
|
| 2380 | 
		private:  | 
|
| 2381 | 
		 | 
|
| 2382 | 
		    int position(const Key& key) const {
	 | 
|
| 2383 | 
		return Parent::operator[](key);  | 
|
| 2384 | 
		}  | 
|
| 2385 | 
		 | 
|
| 2386 | 
		public:  | 
|
| 2387 | 
		 | 
|
| 2388 | 
		/// \brief Reference to the value of the map.  | 
|
| 2389 | 
		///  | 
|
| 2390 | 
		/// This class is similar to the \c bool type. It can be converted to  | 
|
| 2391 | 
		/// \c bool and it provides the same operators.  | 
|
| 2392 | 
		    class Reference {
	 | 
|
| 2393 | 
		friend class IterableBoolMap;  | 
|
| 2394 | 
		private:  | 
|
| 2395 | 
		Reference(IterableBoolMap& map, const Key& key)  | 
|
| 2396 | 
		        : _key(key), _map(map) {}
	 | 
|
| 2397 | 
		public:  | 
|
| 2398 | 
		 | 
|
| 2399 | 
		      Reference& operator=(const Reference& value) {
	 | 
|
| 2400 | 
		_map.set(_key, static_cast<bool>(value));  | 
|
| 2401 | 
		return *this;  | 
|
| 2402 | 
		}  | 
|
| 2403 | 
		 | 
|
| 2404 | 
		      operator bool() const {
	 | 
|
| 2405 | 
		return static_cast<const IterableBoolMap&>(_map)[_key];  | 
|
| 2406 | 
		}  | 
|
| 2407 | 
		 | 
|
| 2408 | 
		      Reference& operator=(bool value) {
	 | 
|
| 2409 | 
		_map.set(_key, value);  | 
|
| 2410 | 
		return *this;  | 
|
| 2411 | 
		}  | 
|
| 2412 | 
		      Reference& operator&=(bool value) {
	 | 
|
| 2413 | 
		_map.set(_key, _map[_key] & value);  | 
|
| 2414 | 
		return *this;  | 
|
| 2415 | 
		}  | 
|
| 2416 | 
		      Reference& operator|=(bool value) {
	 | 
|
| 2417 | 
		_map.set(_key, _map[_key] | value);  | 
|
| 2418 | 
		return *this;  | 
|
| 2419 | 
		}  | 
|
| 2420 | 
		      Reference& operator^=(bool value) {
	 | 
|
| 2421 | 
		_map.set(_key, _map[_key] ^ value);  | 
|
| 2422 | 
		return *this;  | 
|
| 2423 | 
		}  | 
|
| 2424 | 
		private:  | 
|
| 2425 | 
		Key _key;  | 
|
| 2426 | 
		IterableBoolMap& _map;  | 
|
| 2427 | 
		};  | 
|
| 2428 | 
		 | 
|
| 2429 | 
		/// \brief Constructor of the map with a default value.  | 
|
| 2430 | 
		///  | 
|
| 2431 | 
		/// Constructor of the map with a default value.  | 
|
| 2432 | 
		explicit IterableBoolMap(const Graph& graph, bool def = false)  | 
|
| 2433 | 
		      : Parent(graph) {
	 | 
|
| 2434 | 
		typename Parent::Notifier* nf = Parent::notifier();  | 
|
| 2435 | 
		Key it;  | 
|
| 2436 | 
		      for (nf->first(it); it != INVALID; nf->next(it)) {
	 | 
|
| 2437 | 
		Parent::set(it, _array.size());  | 
|
| 2438 | 
		_array.push_back(it);  | 
|
| 2439 | 
		}  | 
|
| 2440 | 
		_sep = (def ? _array.size() : 0);  | 
|
| 2441 | 
		}  | 
|
| 2442 | 
		 | 
|
| 2443 | 
		/// \brief Const subscript operator of the map.  | 
|
| 2444 | 
		///  | 
|
| 2445 | 
		/// Const subscript operator of the map.  | 
|
| 2446 | 
		    bool operator[](const Key& key) const {
	 | 
|
| 2447 | 
		return position(key) < _sep;  | 
|
| 2448 | 
		}  | 
|
| 2449 | 
		 | 
|
| 2450 | 
		/// \brief Subscript operator of the map.  | 
|
| 2451 | 
		///  | 
|
| 2452 | 
		/// Subscript operator of the map.  | 
|
| 2453 | 
		    Reference operator[](const Key& key) {
	 | 
|
| 2454 | 
		return Reference(*this, key);  | 
|
| 2455 | 
		}  | 
|
| 2456 | 
		 | 
|
| 2457 | 
		/// \brief Set operation of the map.  | 
|
| 2458 | 
		///  | 
|
| 2459 | 
		/// Set operation of the map.  | 
|
| 2460 | 
		    void set(const Key& key, bool value) {
	 | 
|
| 2461 | 
		int pos = position(key);  | 
|
| 2462 | 
		      if (value) {
	 | 
|
| 2463 | 
		if (pos < _sep) return;  | 
|
| 2464 | 
		Key tmp = _array[_sep];  | 
|
| 2465 | 
		_array[_sep] = key;  | 
|
| 2466 | 
		Parent::set(key, _sep);  | 
|
| 2467 | 
		_array[pos] = tmp;  | 
|
| 2468 | 
		Parent::set(tmp, pos);  | 
|
| 2469 | 
		++_sep;  | 
|
| 2470 | 
		      } else {
	 | 
|
| 2471 | 
		if (pos >= _sep) return;  | 
|
| 2472 | 
		--_sep;  | 
|
| 2473 | 
		Key tmp = _array[_sep];  | 
|
| 2474 | 
		_array[_sep] = key;  | 
|
| 2475 | 
		Parent::set(key, _sep);  | 
|
| 2476 | 
		_array[pos] = tmp;  | 
|
| 2477 | 
		Parent::set(tmp, pos);  | 
|
| 2478 | 
		}  | 
|
| 2479 | 
		}  | 
|
| 2480 | 
		 | 
|
| 2481 | 
		/// \brief Set all items.  | 
|
| 2482 | 
		///  | 
|
| 2483 | 
		/// Set all items in the map.  | 
|
| 2484 | 
		/// \note Constant time operation.  | 
|
| 2485 | 
		    void setAll(bool value) {
	 | 
|
| 2486 | 
		_sep = (value ? _array.size() : 0);  | 
|
| 2487 | 
		}  | 
|
| 2488 | 
		 | 
|
| 2489 | 
		/// \brief Returns the number of the keys mapped to \c true.  | 
|
| 2490 | 
		///  | 
|
| 2491 | 
		/// Returns the number of the keys mapped to \c true.  | 
|
| 2492 | 
		    int trueNum() const {
	 | 
|
| 2493 | 
		return _sep;  | 
|
| 2494 | 
		}  | 
|
| 2495 | 
		 | 
|
| 2496 | 
		/// \brief Returns the number of the keys mapped to \c false.  | 
|
| 2497 | 
		///  | 
|
| 2498 | 
		/// Returns the number of the keys mapped to \c false.  | 
|
| 2499 | 
		    int falseNum() const {
	 | 
|
| 2500 | 
		return _array.size() - _sep;  | 
|
| 2501 | 
		}  | 
|
| 2502 | 
		 | 
|
| 2503 | 
		/// \brief Iterator for the keys mapped to \c true.  | 
|
| 2504 | 
		///  | 
|
| 2505 | 
		/// Iterator for the keys mapped to \c true. It works  | 
|
| 2506 | 
		/// like a graph item iterator, it can be converted to  | 
|
| 2507 | 
		/// the key type of the map, incremented with \c ++ operator, and  | 
|
| 2508 | 
		/// if the iterator leaves the last valid key, it will be equal to  | 
|
| 2509 | 
		/// \c INVALID.  | 
|
| 2510 | 
		    class TrueIt : public Key {
	 | 
|
| 2511 | 
		public:  | 
|
| 2512 | 
		typedef Key Parent;  | 
|
| 2513 | 
		 | 
|
| 2514 | 
		/// \brief Creates an iterator.  | 
|
| 2515 | 
		///  | 
|
| 2516 | 
		/// Creates an iterator. It iterates on the  | 
|
| 2517 | 
		/// keys mapped to \c true.  | 
|
| 2518 | 
		/// \param map The IterableBoolMap.  | 
|
| 2519 | 
		explicit TrueIt(const IterableBoolMap& map)  | 
|
| 2520 | 
		: Parent(map._sep > 0 ? map._array[map._sep - 1] : INVALID),  | 
|
| 2521 | 
		          _map(&map) {}
	 | 
|
| 2522 | 
		 | 
|
| 2523 | 
		/// \brief Invalid constructor \& conversion.  | 
|
| 2524 | 
		///  | 
|
| 2525 | 
		/// This constructor initializes the iterator to be invalid.  | 
|
| 2526 | 
		/// \sa Invalid for more details.  | 
|
| 2527 | 
		      TrueIt(Invalid) : Parent(INVALID), _map(0) {}
	 | 
|
| 2528 | 
		 | 
|
| 2529 | 
		/// \brief Increment operator.  | 
|
| 2530 | 
		///  | 
|
| 2531 | 
		/// Increment operator.  | 
|
| 2532 | 
		      TrueIt& operator++() {
	 | 
|
| 2533 | 
		int pos = _map->position(*this);  | 
|
| 2534 | 
		Parent::operator=(pos > 0 ? _map->_array[pos - 1] : INVALID);  | 
|
| 2535 | 
		return *this;  | 
|
| 2536 | 
		}  | 
|
| 2537 | 
		 | 
|
| 2538 | 
		private:  | 
|
| 2539 | 
		const IterableBoolMap* _map;  | 
|
| 2540 | 
		};  | 
|
| 2541 | 
		 | 
|
| 2542 | 
		/// \brief Iterator for the keys mapped to \c false.  | 
|
| 2543 | 
		///  | 
|
| 2544 | 
		/// Iterator for the keys mapped to \c false. It works  | 
|
| 2545 | 
		/// like a graph item iterator, it can be converted to  | 
|
| 2546 | 
		/// the key type of the map, incremented with \c ++ operator, and  | 
|
| 2547 | 
		/// if the iterator leaves the last valid key, it will be equal to  | 
|
| 2548 | 
		/// \c INVALID.  | 
|
| 2549 | 
		    class FalseIt : public Key {
	 | 
|
| 2550 | 
		public:  | 
|
| 2551 | 
		typedef Key Parent;  | 
|
| 2552 | 
		 | 
|
| 2553 | 
		/// \brief Creates an iterator.  | 
|
| 2554 | 
		///  | 
|
| 2555 | 
		/// Creates an iterator. It iterates on the  | 
|
| 2556 | 
		/// keys mapped to \c false.  | 
|
| 2557 | 
		/// \param map The IterableBoolMap.  | 
|
| 2558 | 
		explicit FalseIt(const IterableBoolMap& map)  | 
|
| 2559 | 
		: Parent(map._sep < int(map._array.size()) ?  | 
|
| 2560 | 
		                 map._array.back() : INVALID), _map(&map) {}
	 | 
|
| 2561 | 
		 | 
|
| 2562 | 
		/// \brief Invalid constructor \& conversion.  | 
|
| 2563 | 
		///  | 
|
| 2564 | 
		/// This constructor initializes the iterator to be invalid.  | 
|
| 2565 | 
		/// \sa Invalid for more details.  | 
|
| 2566 | 
		      FalseIt(Invalid) : Parent(INVALID), _map(0) {}
	 | 
|
| 2567 | 
		 | 
|
| 2568 | 
		/// \brief Increment operator.  | 
|
| 2569 | 
		///  | 
|
| 2570 | 
		/// Increment operator.  | 
|
| 2571 | 
		      FalseIt& operator++() {
	 | 
|
| 2572 | 
		int pos = _map->position(*this);  | 
|
| 2573 | 
		Parent::operator=(pos > _map->_sep ? _map->_array[pos - 1] : INVALID);  | 
|
| 2574 | 
		return *this;  | 
|
| 2575 | 
		}  | 
|
| 2576 | 
		 | 
|
| 2577 | 
		private:  | 
|
| 2578 | 
		const IterableBoolMap* _map;  | 
|
| 2579 | 
		};  | 
|
| 2580 | 
		 | 
|
| 2581 | 
		/// \brief Iterator for the keys mapped to a given value.  | 
|
| 2582 | 
		///  | 
|
| 2583 | 
		/// Iterator for the keys mapped to a given value. It works  | 
|
| 2584 | 
		/// like a graph item iterator, it can be converted to  | 
|
| 2585 | 
		/// the key type of the map, incremented with \c ++ operator, and  | 
|
| 2586 | 
		/// if the iterator leaves the last valid key, it will be equal to  | 
|
| 2587 | 
		/// \c INVALID.  | 
|
| 2588 | 
		    class ItemIt : public Key {
	 | 
|
| 2589 | 
		public:  | 
|
| 2590 | 
		typedef Key Parent;  | 
|
| 2591 | 
		 | 
|
| 2592 | 
		/// \brief Creates an iterator with a value.  | 
|
| 2593 | 
		///  | 
|
| 2594 | 
		/// Creates an iterator with a value. It iterates on the  | 
|
| 2595 | 
		/// keys mapped to the given value.  | 
|
| 2596 | 
		/// \param map The IterableBoolMap.  | 
|
| 2597 | 
		/// \param value The value.  | 
|
| 2598 | 
		ItemIt(const IterableBoolMap& map, bool value)  | 
|
| 2599 | 
		: Parent(value ?  | 
|
| 2600 | 
		(map._sep > 0 ?  | 
|
| 2601 | 
		map._array[map._sep - 1] : INVALID) :  | 
|
| 2602 | 
		(map._sep < int(map._array.size()) ?  | 
|
| 2603 | 
		                  map._array.back() : INVALID)), _map(&map) {}
	 | 
|
| 2604 | 
		 | 
|
| 2605 | 
		/// \brief Invalid constructor \& conversion.  | 
|
| 2606 | 
		///  | 
|
| 2607 | 
		/// This constructor initializes the iterator to be invalid.  | 
|
| 2608 | 
		/// \sa Invalid for more details.  | 
|
| 2609 | 
		      ItemIt(Invalid) : Parent(INVALID), _map(0) {}
	 | 
|
| 2610 | 
		 | 
|
| 2611 | 
		/// \brief Increment operator.  | 
|
| 2612 | 
		///  | 
|
| 2613 | 
		/// Increment operator.  | 
|
| 2614 | 
		      ItemIt& operator++() {
	 | 
|
| 2615 | 
		int pos = _map->position(*this);  | 
|
| 2616 | 
		int _sep = pos >= _map->_sep ? _map->_sep : 0;  | 
|
| 2617 | 
		Parent::operator=(pos > _sep ? _map->_array[pos - 1] : INVALID);  | 
|
| 2618 | 
		return *this;  | 
|
| 2619 | 
		}  | 
|
| 2620 | 
		 | 
|
| 2621 | 
		private:  | 
|
| 2622 | 
		const IterableBoolMap* _map;  | 
|
| 2623 | 
		};  | 
|
| 2624 | 
		 | 
|
| 2625 | 
		protected:  | 
|
| 2626 | 
		 | 
|
| 2627 | 
		    virtual void add(const Key& key) {
	 | 
|
| 2628 | 
		Parent::add(key);  | 
|
| 2629 | 
		Parent::set(key, _array.size());  | 
|
| 2630 | 
		_array.push_back(key);  | 
|
| 2631 | 
		}  | 
|
| 2632 | 
		 | 
|
| 2633 | 
		    virtual void add(const std::vector<Key>& keys) {
	 | 
|
| 2634 | 
		Parent::add(keys);  | 
|
| 2635 | 
		      for (int i = 0; i < int(keys.size()); ++i) {
	 | 
|
| 2636 | 
		Parent::set(keys[i], _array.size());  | 
|
| 2637 | 
		_array.push_back(keys[i]);  | 
|
| 2638 | 
		}  | 
|
| 2639 | 
		}  | 
|
| 2640 | 
		 | 
|
| 2641 | 
		    virtual void erase(const Key& key) {
	 | 
|
| 2642 | 
		int pos = position(key);  | 
|
| 2643 | 
		      if (pos < _sep) {
	 | 
|
| 2644 | 
		--_sep;  | 
|
| 2645 | 
		Parent::set(_array[_sep], pos);  | 
|
| 2646 | 
		_array[pos] = _array[_sep];  | 
|
| 2647 | 
		Parent::set(_array.back(), _sep);  | 
|
| 2648 | 
		_array[_sep] = _array.back();  | 
|
| 2649 | 
		_array.pop_back();  | 
|
| 2650 | 
		      } else {
	 | 
|
| 2651 | 
		Parent::set(_array.back(), pos);  | 
|
| 2652 | 
		_array[pos] = _array.back();  | 
|
| 2653 | 
		_array.pop_back();  | 
|
| 2654 | 
		}  | 
|
| 2655 | 
		Parent::erase(key);  | 
|
| 2656 | 
		}  | 
|
| 2657 | 
		 | 
|
| 2658 | 
		    virtual void erase(const std::vector<Key>& keys) {
	 | 
|
| 2659 | 
		      for (int i = 0; i < int(keys.size()); ++i) {
	 | 
|
| 2660 | 
		int pos = position(keys[i]);  | 
|
| 2661 | 
		        if (pos < _sep) {
	 | 
|
| 2662 | 
		--_sep;  | 
|
| 2663 | 
		Parent::set(_array[_sep], pos);  | 
|
| 2664 | 
		_array[pos] = _array[_sep];  | 
|
| 2665 | 
		Parent::set(_array.back(), _sep);  | 
|
| 2666 | 
		_array[_sep] = _array.back();  | 
|
| 2667 | 
		_array.pop_back();  | 
|
| 2668 | 
		        } else {
	 | 
|
| 2669 | 
		Parent::set(_array.back(), pos);  | 
|
| 2670 | 
		_array[pos] = _array.back();  | 
|
| 2671 | 
		_array.pop_back();  | 
|
| 2672 | 
		}  | 
|
| 2673 | 
		}  | 
|
| 2674 | 
		Parent::erase(keys);  | 
|
| 2675 | 
		}  | 
|
| 2676 | 
		 | 
|
| 2677 | 
		    virtual void build() {
	 | 
|
| 2678 | 
		Parent::build();  | 
|
| 2679 | 
		typename Parent::Notifier* nf = Parent::notifier();  | 
|
| 2680 | 
		Key it;  | 
|
| 2681 | 
		      for (nf->first(it); it != INVALID; nf->next(it)) {
	 | 
|
| 2682 | 
		Parent::set(it, _array.size());  | 
|
| 2683 | 
		_array.push_back(it);  | 
|
| 2684 | 
		}  | 
|
| 2685 | 
		_sep = 0;  | 
|
| 2686 | 
		}  | 
|
| 2687 | 
		 | 
|
| 2688 | 
		    virtual void clear() {
	 | 
|
| 2689 | 
		_array.clear();  | 
|
| 2690 | 
		_sep = 0;  | 
|
| 2691 | 
		Parent::clear();  | 
|
| 2692 | 
		}  | 
|
| 2693 | 
		 | 
|
| 2694 | 
		};  | 
|
| 2695 | 
		 | 
|
| 2696 | 
		 | 
|
| 2697 | 
		  namespace _maps_bits {
	 | 
|
| 2698 | 
		template <typename Item>  | 
|
| 2699 | 
		    struct IterableIntMapNode {
	 | 
|
| 2700 | 
		      IterableIntMapNode() : value(-1) {}
	 | 
|
| 2701 | 
		      IterableIntMapNode(int _value) : value(_value) {}
	 | 
|
| 2702 | 
		Item prev, next;  | 
|
| 2703 | 
		int value;  | 
|
| 2704 | 
		};  | 
|
| 2705 | 
		}  | 
|
| 2706 | 
		 | 
|
| 2707 | 
		/// \brief Dynamic iterable integer map.  | 
|
| 2708 | 
		///  | 
|
| 2709 | 
		/// This class provides a special graph map type which can store an  | 
|
| 2710 | 
		/// integer value for graph items (\c Node, \c Arc or \c Edge).  | 
|
| 2711 | 
		/// For each non-negative value it is possible to iterate on the keys  | 
|
| 2712 | 
		/// mapped to the value.  | 
|
| 2713 | 
		///  | 
|
| 2714 | 
		/// This type is a reference map, so it can be modified with the  | 
|
| 2715 | 
		/// subscription operator.  | 
|
| 2716 | 
		///  | 
|
| 2717 | 
		/// \note The size of the data structure depends on the largest  | 
|
| 2718 | 
		/// value in the map.  | 
|
| 2719 | 
		///  | 
|
| 2720 | 
		/// \tparam GR The graph type.  | 
|
| 2721 | 
		/// \tparam K The key type of the map (\c GR::Node, \c GR::Arc or  | 
|
| 2722 | 
		/// \c GR::Edge).  | 
|
| 2723 | 
		///  | 
|
| 2724 | 
		/// \see IterableBoolMap, IterableValueMap  | 
|
| 2725 | 
		/// \see CrossRefMap  | 
|
| 2726 | 
		template <typename GR, typename K>  | 
|
| 2727 | 
		class IterableIntMap  | 
|
| 2728 | 
		: protected ItemSetTraits<GR, K>::  | 
|
| 2729 | 
		        template Map<_maps_bits::IterableIntMapNode<K> >::Type {
	 | 
|
| 2730 | 
		public:  | 
|
| 2731 | 
		typedef typename ItemSetTraits<GR, K>::  | 
|
| 2732 | 
		template Map<_maps_bits::IterableIntMapNode<K> >::Type Parent;  | 
|
| 2733 | 
		 | 
|
| 2734 | 
		/// The key type  | 
|
| 2735 | 
		typedef K Key;  | 
|
| 2736 | 
		/// The value type  | 
|
| 2737 | 
		typedef int Value;  | 
|
| 2738 | 
		/// The graph type  | 
|
| 2739 | 
		typedef GR Graph;  | 
|
| 2740 | 
		 | 
|
| 2741 | 
		/// \brief Constructor of the map.  | 
|
| 2742 | 
		///  | 
|
| 2743 | 
		/// Constructor of the map. It sets all values to -1.  | 
|
| 2744 | 
		explicit IterableIntMap(const Graph& graph)  | 
|
| 2745 | 
		      : Parent(graph) {}
	 | 
|
| 2746 | 
		 | 
|
| 2747 | 
		/// \brief Constructor of the map with a given value.  | 
|
| 2748 | 
		///  | 
|
| 2749 | 
		/// Constructor of the map with a given value.  | 
|
| 2750 | 
		explicit IterableIntMap(const Graph& graph, int value)  | 
|
| 2751 | 
		      : Parent(graph, _maps_bits::IterableIntMapNode<K>(value)) {
	 | 
|
| 2752 | 
		      if (value >= 0) {
	 | 
|
| 2753 | 
		        for (typename Parent::ItemIt it(*this); it != INVALID; ++it) {
	 | 
|
| 2754 | 
		lace(it);  | 
|
| 2755 | 
		}  | 
|
| 2756 | 
		}  | 
|
| 2757 | 
		}  | 
|
| 2758 | 
		 | 
|
| 2759 | 
		private:  | 
|
| 2760 | 
		 | 
|
| 2761 | 
		    void unlace(const Key& key) {
	 | 
|
| 2762 | 
		typename Parent::Value& node = Parent::operator[](key);  | 
|
| 2763 | 
		if (node.value < 0) return;  | 
|
| 2764 | 
		      if (node.prev != INVALID) {
	 | 
|
| 2765 | 
		Parent::operator[](node.prev).next = node.next;  | 
|
| 2766 | 
		      } else {
	 | 
|
| 2767 | 
		_first[node.value] = node.next;  | 
|
| 2768 | 
		}  | 
|
| 2769 | 
		      if (node.next != INVALID) {
	 | 
|
| 2770 | 
		Parent::operator[](node.next).prev = node.prev;  | 
|
| 2771 | 
		}  | 
|
| 2772 | 
		      while (!_first.empty() && _first.back() == INVALID) {
	 | 
|
| 2773 | 
		_first.pop_back();  | 
|
| 2774 | 
		}  | 
|
| 2775 | 
		}  | 
|
| 2776 | 
		 | 
|
| 2777 | 
		    void lace(const Key& key) {
	 | 
|
| 2778 | 
		typename Parent::Value& node = Parent::operator[](key);  | 
|
| 2779 | 
		if (node.value < 0) return;  | 
|
| 2780 | 
		      if (node.value >= int(_first.size())) {
	 | 
|
| 2781 | 
		_first.resize(node.value + 1, INVALID);  | 
|
| 2782 | 
		}  | 
|
| 2783 | 
		node.prev = INVALID;  | 
|
| 2784 | 
		node.next = _first[node.value];  | 
|
| 2785 | 
		      if (node.next != INVALID) {
	 | 
|
| 2786 | 
		Parent::operator[](node.next).prev = key;  | 
|
| 2787 | 
		}  | 
|
| 2788 | 
		_first[node.value] = key;  | 
|
| 2789 | 
		}  | 
|
| 2790 | 
		 | 
|
| 2791 | 
		public:  | 
|
| 2792 | 
		 | 
|
| 2793 | 
		/// Indicates that the map is reference map.  | 
|
| 2794 | 
		typedef True ReferenceMapTag;  | 
|
| 2795 | 
		 | 
|
| 2796 | 
		/// \brief Reference to the value of the map.  | 
|
| 2797 | 
		///  | 
|
| 2798 | 
		/// This class is similar to the \c int type. It can  | 
|
| 2799 | 
		/// be converted to \c int and it has the same operators.  | 
|
| 2800 | 
		    class Reference {
	 | 
|
| 2801 | 
		friend class IterableIntMap;  | 
|
| 2802 | 
		private:  | 
|
| 2803 | 
		Reference(IterableIntMap& map, const Key& key)  | 
|
| 2804 | 
		        : _key(key), _map(map) {}
	 | 
|
| 2805 | 
		public:  | 
|
| 2806 | 
		 | 
|
| 2807 | 
		      Reference& operator=(const Reference& value) {
	 | 
|
| 2808 | 
		_map.set(_key, static_cast<const int&>(value));  | 
|
| 2809 | 
		return *this;  | 
|
| 2810 | 
		}  | 
|
| 2811 | 
		 | 
|
| 2812 | 
		      operator const int&() const {
	 | 
|
| 2813 | 
		return static_cast<const IterableIntMap&>(_map)[_key];  | 
|
| 2814 | 
		}  | 
|
| 2815 | 
		 | 
|
| 2816 | 
		      Reference& operator=(int value) {
	 | 
|
| 2817 | 
		_map.set(_key, value);  | 
|
| 2818 | 
		return *this;  | 
|
| 2819 | 
		}  | 
|
| 2820 | 
		      Reference& operator++() {
	 | 
|
| 2821 | 
		_map.set(_key, _map[_key] + 1);  | 
|
| 2822 | 
		return *this;  | 
|
| 2823 | 
		}  | 
|
| 2824 | 
		      int operator++(int) {
	 | 
|
| 2825 | 
		int value = _map[_key];  | 
|
| 2826 | 
		_map.set(_key, value + 1);  | 
|
| 2827 | 
		return value;  | 
|
| 2828 | 
		}  | 
|
| 2829 | 
		      Reference& operator--() {
	 | 
|
| 2830 | 
		_map.set(_key, _map[_key] - 1);  | 
|
| 2831 | 
		return *this;  | 
|
| 2832 | 
		}  | 
|
| 2833 | 
		      int operator--(int) {
	 | 
|
| 2834 | 
		int value = _map[_key];  | 
|
| 2835 | 
		_map.set(_key, value - 1);  | 
|
| 2836 | 
		return value;  | 
|
| 2837 | 
		}  | 
|
| 2838 | 
		      Reference& operator+=(int value) {
	 | 
|
| 2839 | 
		_map.set(_key, _map[_key] + value);  | 
|
| 2840 | 
		return *this;  | 
|
| 2841 | 
		}  | 
|
| 2842 | 
		      Reference& operator-=(int value) {
	 | 
|
| 2843 | 
		_map.set(_key, _map[_key] - value);  | 
|
| 2844 | 
		return *this;  | 
|
| 2845 | 
		}  | 
|
| 2846 | 
		      Reference& operator*=(int value) {
	 | 
|
| 2847 | 
		_map.set(_key, _map[_key] * value);  | 
|
| 2848 | 
		return *this;  | 
|
| 2849 | 
		}  | 
|
| 2850 | 
		      Reference& operator/=(int value) {
	 | 
|
| 2851 | 
		_map.set(_key, _map[_key] / value);  | 
|
| 2852 | 
		return *this;  | 
|
| 2853 | 
		}  | 
|
| 2854 | 
		      Reference& operator%=(int value) {
	 | 
|
| 2855 | 
		_map.set(_key, _map[_key] % value);  | 
|
| 2856 | 
		return *this;  | 
|
| 2857 | 
		}  | 
|
| 2858 | 
		      Reference& operator&=(int value) {
	 | 
|
| 2859 | 
		_map.set(_key, _map[_key] & value);  | 
|
| 2860 | 
		return *this;  | 
|
| 2861 | 
		}  | 
|
| 2862 | 
		      Reference& operator|=(int value) {
	 | 
|
| 2863 | 
		_map.set(_key, _map[_key] | value);  | 
|
| 2864 | 
		return *this;  | 
|
| 2865 | 
		}  | 
|
| 2866 | 
		      Reference& operator^=(int value) {
	 | 
|
| 2867 | 
		_map.set(_key, _map[_key] ^ value);  | 
|
| 2868 | 
		return *this;  | 
|
| 2869 | 
		}  | 
|
| 2870 | 
		      Reference& operator<<=(int value) {
	 | 
|
| 2871 | 
		_map.set(_key, _map[_key] << value);  | 
|
| 2872 | 
		return *this;  | 
|
| 2873 | 
		}  | 
|
| 2874 | 
		      Reference& operator>>=(int value) {
	 | 
|
| 2875 | 
		_map.set(_key, _map[_key] >> value);  | 
|
| 2876 | 
		return *this;  | 
|
| 2877 | 
		}  | 
|
| 2878 | 
		 | 
|
| 2879 | 
		private:  | 
|
| 2880 | 
		Key _key;  | 
|
| 2881 | 
		IterableIntMap& _map;  | 
|
| 2882 | 
		};  | 
|
| 2883 | 
		 | 
|
| 2884 | 
		/// The const reference type.  | 
|
| 2885 | 
		typedef const Value& ConstReference;  | 
|
| 2886 | 
		 | 
|
| 2887 | 
		/// \brief Gives back the maximal value plus one.  | 
|
| 2888 | 
		///  | 
|
| 2889 | 
		/// Gives back the maximal value plus one.  | 
|
| 2890 | 
		    int size() const {
	 | 
|
| 2891 | 
		return _first.size();  | 
|
| 2892 | 
		}  | 
|
| 2893 | 
		 | 
|
| 2894 | 
		/// \brief Set operation of the map.  | 
|
| 2895 | 
		///  | 
|
| 2896 | 
		/// Set operation of the map.  | 
|
| 2897 | 
		    void set(const Key& key, const Value& value) {
	 | 
|
| 2898 | 
		unlace(key);  | 
|
| 2899 | 
		Parent::operator[](key).value = value;  | 
|
| 2900 | 
		lace(key);  | 
|
| 2901 | 
		}  | 
|
| 2902 | 
		 | 
|
| 2903 | 
		/// \brief Const subscript operator of the map.  | 
|
| 2904 | 
		///  | 
|
| 2905 | 
		/// Const subscript operator of the map.  | 
|
| 2906 | 
		    const Value& operator[](const Key& key) const {
	 | 
|
| 2907 | 
		return Parent::operator[](key).value;  | 
|
| 2908 | 
		}  | 
|
| 2909 | 
		 | 
|
| 2910 | 
		/// \brief Subscript operator of the map.  | 
|
| 2911 | 
		///  | 
|
| 2912 | 
		/// Subscript operator of the map.  | 
|
| 2913 | 
		    Reference operator[](const Key& key) {
	 | 
|
| 2914 | 
		return Reference(*this, key);  | 
|
| 2915 | 
		}  | 
|
| 2916 | 
		 | 
|
| 2917 | 
		/// \brief Iterator for the keys with the same value.  | 
|
| 2918 | 
		///  | 
|
| 2919 | 
		/// Iterator for the keys with the same value. It works  | 
|
| 2920 | 
		/// like a graph item iterator, it can be converted to  | 
|
| 2921 | 
		/// the item type of the map, incremented with \c ++ operator, and  | 
|
| 2922 | 
		/// if the iterator leaves the last valid item, it will be equal to  | 
|
| 2923 | 
		/// \c INVALID.  | 
|
| 2924 | 
		    class ItemIt : public Key {
	 | 
|
| 2925 | 
		public:  | 
|
| 2926 | 
		typedef Key Parent;  | 
|
| 2927 | 
		 | 
|
| 2928 | 
		/// \brief Invalid constructor \& conversion.  | 
|
| 2929 | 
		///  | 
|
| 2930 | 
		/// This constructor initializes the iterator to be invalid.  | 
|
| 2931 | 
		/// \sa Invalid for more details.  | 
|
| 2932 | 
		      ItemIt(Invalid) : Parent(INVALID), _map(0) {}
	 | 
|
| 2933 | 
		 | 
|
| 2934 | 
		/// \brief Creates an iterator with a value.  | 
|
| 2935 | 
		///  | 
|
| 2936 | 
		/// Creates an iterator with a value. It iterates on the  | 
|
| 2937 | 
		/// keys mapped to the given value.  | 
|
| 2938 | 
		/// \param map The IterableIntMap.  | 
|
| 2939 | 
		/// \param value The value.  | 
|
| 2940 | 
		      ItemIt(const IterableIntMap& map, int value) : _map(&map) {
	 | 
|
| 2941 | 
		        if (value < 0 || value >= int(_map->_first.size())) {
	 | 
|
| 2942 | 
		Parent::operator=(INVALID);  | 
|
| 2943 | 
		        } else {
	 | 
|
| 2944 | 
		Parent::operator=(_map->_first[value]);  | 
|
| 2945 | 
		}  | 
|
| 2946 | 
		}  | 
|
| 2947 | 
		 | 
|
| 2948 | 
		/// \brief Increment operator.  | 
|
| 2949 | 
		///  | 
|
| 2950 | 
		/// Increment operator.  | 
|
| 2951 | 
		      ItemIt& operator++() {
	 | 
|
| 2952 | 
		Parent::operator=(_map->IterableIntMap::Parent::  | 
|
| 2953 | 
		operator[](static_cast<Parent&>(*this)).next);  | 
|
| 2954 | 
		return *this;  | 
|
| 2955 | 
		}  | 
|
| 2956 | 
		 | 
|
| 2957 | 
		private:  | 
|
| 2958 | 
		const IterableIntMap* _map;  | 
|
| 2959 | 
		};  | 
|
| 2960 | 
		 | 
|
| 2961 | 
		protected:  | 
|
| 2962 | 
		 | 
|
| 2963 | 
		    virtual void erase(const Key& key) {
	 | 
|
| 2964 | 
		unlace(key);  | 
|
| 2965 | 
		Parent::erase(key);  | 
|
| 2966 | 
		}  | 
|
| 2967 | 
		 | 
|
| 2968 | 
		    virtual void erase(const std::vector<Key>& keys) {
	 | 
|
| 2969 | 
		      for (int i = 0; i < int(keys.size()); ++i) {
	 | 
|
| 2970 | 
		unlace(keys[i]);  | 
|
| 2971 | 
		}  | 
|
| 2972 | 
		Parent::erase(keys);  | 
|
| 2973 | 
		}  | 
|
| 2974 | 
		 | 
|
| 2975 | 
		    virtual void clear() {
	 | 
|
| 2976 | 
		_first.clear();  | 
|
| 2977 | 
		Parent::clear();  | 
|
| 2978 | 
		}  | 
|
| 2979 | 
		 | 
|
| 2980 | 
		private:  | 
|
| 2981 | 
		std::vector<Key> _first;  | 
|
| 2982 | 
		};  | 
|
| 2983 | 
		 | 
|
| 2984 | 
		  namespace _maps_bits {
	 | 
|
| 2985 | 
		template <typename Item, typename Value>  | 
|
| 2986 | 
		    struct IterableValueMapNode {
	 | 
|
| 2987 | 
		      IterableValueMapNode(Value _value = Value()) : value(_value) {}
	 | 
|
| 2988 | 
		Item prev, next;  | 
|
| 2989 | 
		Value value;  | 
|
| 2990 | 
		};  | 
|
| 2991 | 
		}  | 
|
| 2992 | 
		 | 
|
| 2993 | 
		/// \brief Dynamic iterable map for comparable values.  | 
|
| 2994 | 
		///  | 
|
| 2995 | 
		/// This class provides a special graph map type which can store an  | 
|
| 2996 | 
		/// comparable value for graph items (\c Node, \c Arc or \c Edge).  | 
|
| 2997 | 
		/// For each value it is possible to iterate on the keys mapped to  | 
|
| 2998 | 
		/// the value.  | 
|
| 2999 | 
		///  | 
|
| 3000 | 
		/// The map stores for each value a linked list with  | 
|
| 3001 | 
		/// the items which mapped to the value, and the values are stored  | 
|
| 3002 | 
		/// in balanced binary tree. The values of the map can be accessed  | 
|
| 3003 | 
		/// with stl compatible forward iterator.  | 
|
| 3004 | 
		///  | 
|
| 3005 | 
		/// This type is not reference map, so it cannot be modified with  | 
|
| 3006 | 
		/// the subscription operator.  | 
|
| 3007 | 
		///  | 
|
| 3008 | 
		/// \tparam GR The graph type.  | 
|
| 3009 | 
		/// \tparam K The key type of the map (\c GR::Node, \c GR::Arc or  | 
|
| 3010 | 
		/// \c GR::Edge).  | 
|
| 3011 | 
		/// \tparam V The value type of the map. It can be any comparable  | 
|
| 3012 | 
		/// value type.  | 
|
| 3013 | 
		///  | 
|
| 3014 | 
		/// \see IterableBoolMap, IterableIntMap  | 
|
| 3015 | 
		/// \see CrossRefMap  | 
|
| 3016 | 
		template <typename GR, typename K, typename V>  | 
|
| 3017 | 
		class IterableValueMap  | 
|
| 3018 | 
		: protected ItemSetTraits<GR, K>::  | 
|
| 3019 | 
		        template Map<_maps_bits::IterableValueMapNode<K, V> >::Type {
	 | 
|
| 3020 | 
		public:  | 
|
| 3021 | 
		typedef typename ItemSetTraits<GR, K>::  | 
|
| 3022 | 
		template Map<_maps_bits::IterableValueMapNode<K, V> >::Type Parent;  | 
|
| 3023 | 
		 | 
|
| 3024 | 
		/// The key type  | 
|
| 3025 | 
		typedef K Key;  | 
|
| 3026 | 
		/// The value type  | 
|
| 3027 | 
		typedef V Value;  | 
|
| 3028 | 
		/// The graph type  | 
|
| 3029 | 
		typedef GR Graph;  | 
|
| 3030 | 
		 | 
|
| 3031 | 
		public:  | 
|
| 3032 | 
		 | 
|
| 3033 | 
		/// \brief Constructor of the map with a given value.  | 
|
| 3034 | 
		///  | 
|
| 3035 | 
		/// Constructor of the map with a given value.  | 
|
| 3036 | 
		explicit IterableValueMap(const Graph& graph,  | 
|
| 3037 | 
		const Value& value = Value())  | 
|
| 3038 | 
		      : Parent(graph, _maps_bits::IterableValueMapNode<K, V>(value)) {
	 | 
|
| 3039 | 
		      for (typename Parent::ItemIt it(*this); it != INVALID; ++it) {
	 | 
|
| 3040 | 
		lace(it);  | 
|
| 3041 | 
		}  | 
|
| 3042 | 
		}  | 
|
| 3043 | 
		 | 
|
| 3044 | 
		protected:  | 
|
| 3045 | 
		 | 
|
| 3046 | 
		    void unlace(const Key& key) {
	 | 
|
| 3047 | 
		typename Parent::Value& node = Parent::operator[](key);  | 
|
| 3048 | 
		      if (node.prev != INVALID) {
	 | 
|
| 3049 | 
		Parent::operator[](node.prev).next = node.next;  | 
|
| 3050 | 
		      } else {
	 | 
|
| 3051 | 
		        if (node.next != INVALID) {
	 | 
|
| 3052 | 
		_first[node.value] = node.next;  | 
|
| 3053 | 
		        } else {
	 | 
|
| 3054 | 
		_first.erase(node.value);  | 
|
| 3055 | 
		}  | 
|
| 3056 | 
		}  | 
|
| 3057 | 
		      if (node.next != INVALID) {
	 | 
|
| 3058 | 
		Parent::operator[](node.next).prev = node.prev;  | 
|
| 3059 | 
		}  | 
|
| 3060 | 
		}  | 
|
| 3061 | 
		 | 
|
| 3062 | 
		    void lace(const Key& key) {
	 | 
|
| 3063 | 
		typename Parent::Value& node = Parent::operator[](key);  | 
|
| 3064 | 
		typename std::map<Value, Key>::iterator it = _first.find(node.value);  | 
|
| 3065 | 
		      if (it == _first.end()) {
	 | 
|
| 3066 | 
		node.prev = node.next = INVALID;  | 
|
| 3067 | 
		_first.insert(std::make_pair(node.value, key));  | 
|
| 3068 | 
		      } else {
	 | 
|
| 3069 | 
		node.prev = INVALID;  | 
|
| 3070 | 
		node.next = it->second;  | 
|
| 3071 | 
		        if (node.next != INVALID) {
	 | 
|
| 3072 | 
		Parent::operator[](node.next).prev = key;  | 
|
| 3073 | 
		}  | 
|
| 3074 | 
		it->second = key;  | 
|
| 3075 | 
		}  | 
|
| 3076 | 
		}  | 
|
| 3077 | 
		 | 
|
| 3078 | 
		public:  | 
|
| 3079 | 
		 | 
|
| 3080 | 
		/// \brief Forward iterator for values.  | 
|
| 3081 | 
		///  | 
|
| 3082 | 
		/// This iterator is an stl compatible forward  | 
|
| 3083 | 
		/// iterator on the values of the map. The values can  | 
|
| 3084 | 
		/// be accessed in the <tt>[beginValue, endValue)</tt> range.  | 
|
| 3085 | 
		class ValueIterator  | 
|
| 3086 | 
		      : public std::iterator<std::forward_iterator_tag, Value> {
	 | 
|
| 3087 | 
		friend class IterableValueMap;  | 
|
| 3088 | 
		private:  | 
|
| 3089 | 
		ValueIterator(typename std::map<Value, Key>::const_iterator _it)  | 
|
| 3090 | 
		        : it(_it) {}
	 | 
|
| 3091 | 
		public:  | 
|
| 3092 | 
		 | 
|
| 3093 | 
		      ValueIterator() {}
	 | 
|
| 3094 | 
		 | 
|
| 3095 | 
		      ValueIterator& operator++() { ++it; return *this; }
	 | 
|
| 3096 | 
		      ValueIterator operator++(int) {
	 | 
|
| 3097 | 
		ValueIterator tmp(*this);  | 
|
| 3098 | 
		operator++();  | 
|
| 3099 | 
		return tmp;  | 
|
| 3100 | 
		}  | 
|
| 3101 | 
		 | 
|
| 3102 | 
		      const Value& operator*() const { return it->first; }
	 | 
|
| 3103 | 
		      const Value* operator->() const { return &(it->first); }
	 | 
|
| 3104 | 
		 | 
|
| 3105 | 
		      bool operator==(ValueIterator jt) const { return it == jt.it; }
	 | 
|
| 3106 | 
		      bool operator!=(ValueIterator jt) const { return it != jt.it; }
	 | 
|
| 3107 | 
		 | 
|
| 3108 | 
		private:  | 
|
| 3109 | 
		typename std::map<Value, Key>::const_iterator it;  | 
|
| 3110 | 
		};  | 
|
| 3111 | 
		 | 
|
| 3112 | 
		/// \brief Returns an iterator to the first value.  | 
|
| 3113 | 
		///  | 
|
| 3114 | 
		/// Returns an stl compatible iterator to the  | 
|
| 3115 | 
		/// first value of the map. The values of the  | 
|
| 3116 | 
		/// map can be accessed in the <tt>[beginValue, endValue)</tt>  | 
|
| 3117 | 
		/// range.  | 
|
| 3118 | 
		    ValueIterator beginValue() const {
	 | 
|
| 3119 | 
		return ValueIterator(_first.begin());  | 
|
| 3120 | 
		}  | 
|
| 3121 | 
		 | 
|
| 3122 | 
		/// \brief Returns an iterator after the last value.  | 
|
| 3123 | 
		///  | 
|
| 3124 | 
		/// Returns an stl compatible iterator after the  | 
|
| 3125 | 
		/// last value of the map. The values of the  | 
|
| 3126 | 
		/// map can be accessed in the <tt>[beginValue, endValue)</tt>  | 
|
| 3127 | 
		/// range.  | 
|
| 3128 | 
		    ValueIterator endValue() const {
	 | 
|
| 3129 | 
		return ValueIterator(_first.end());  | 
|
| 3130 | 
		}  | 
|
| 3131 | 
		 | 
|
| 3132 | 
		/// \brief Set operation of the map.  | 
|
| 3133 | 
		///  | 
|
| 3134 | 
		/// Set operation of the map.  | 
|
| 3135 | 
		    void set(const Key& key, const Value& value) {
	 | 
|
| 3136 | 
		unlace(key);  | 
|
| 3137 | 
		Parent::operator[](key).value = value;  | 
|
| 3138 | 
		lace(key);  | 
|
| 3139 | 
		}  | 
|
| 3140 | 
		 | 
|
| 3141 | 
		/// \brief Const subscript operator of the map.  | 
|
| 3142 | 
		///  | 
|
| 3143 | 
		/// Const subscript operator of the map.  | 
|
| 3144 | 
		    const Value& operator[](const Key& key) const {
	 | 
|
| 3145 | 
		return Parent::operator[](key).value;  | 
|
| 3146 | 
		}  | 
|
| 3147 | 
		 | 
|
| 3148 | 
		/// \brief Iterator for the keys with the same value.  | 
|
| 3149 | 
		///  | 
|
| 3150 | 
		/// Iterator for the keys with the same value. It works  | 
|
| 3151 | 
		/// like a graph item iterator, it can be converted to  | 
|
| 3152 | 
		/// the item type of the map, incremented with \c ++ operator, and  | 
|
| 3153 | 
		/// if the iterator leaves the last valid item, it will be equal to  | 
|
| 3154 | 
		/// \c INVALID.  | 
|
| 3155 | 
		    class ItemIt : public Key {
	 | 
|
| 3156 | 
		public:  | 
|
| 3157 | 
		typedef Key Parent;  | 
|
| 3158 | 
		 | 
|
| 3159 | 
		/// \brief Invalid constructor \& conversion.  | 
|
| 3160 | 
		///  | 
|
| 3161 | 
		/// This constructor initializes the iterator to be invalid.  | 
|
| 3162 | 
		/// \sa Invalid for more details.  | 
|
| 3163 | 
		      ItemIt(Invalid) : Parent(INVALID), _map(0) {}
	 | 
|
| 3164 | 
		 | 
|
| 3165 | 
		/// \brief Creates an iterator with a value.  | 
|
| 3166 | 
		///  | 
|
| 3167 | 
		/// Creates an iterator with a value. It iterates on the  | 
|
| 3168 | 
		/// keys which have the given value.  | 
|
| 3169 | 
		/// \param map The IterableValueMap  | 
|
| 3170 | 
		/// \param value The value  | 
|
| 3171 | 
		      ItemIt(const IterableValueMap& map, const Value& value) : _map(&map) {
	 | 
|
| 3172 | 
		typename std::map<Value, Key>::const_iterator it =  | 
|
| 3173 | 
		map._first.find(value);  | 
|
| 3174 | 
		        if (it == map._first.end()) {
	 | 
|
| 3175 | 
		Parent::operator=(INVALID);  | 
|
| 3176 | 
		        } else {
	 | 
|
| 3177 | 
		Parent::operator=(it->second);  | 
|
| 3178 | 
		}  | 
|
| 3179 | 
		}  | 
|
| 3180 | 
		 | 
|
| 3181 | 
		/// \brief Increment operator.  | 
|
| 3182 | 
		///  | 
|
| 3183 | 
		/// Increment Operator.  | 
|
| 3184 | 
		      ItemIt& operator++() {
	 | 
|
| 3185 | 
		Parent::operator=(_map->IterableValueMap::Parent::  | 
|
| 3186 | 
		operator[](static_cast<Parent&>(*this)).next);  | 
|
| 3187 | 
		return *this;  | 
|
| 3188 | 
		}  | 
|
| 3189 | 
		 | 
|
| 3190 | 
		 | 
|
| 3191 | 
		private:  | 
|
| 3192 | 
		const IterableValueMap* _map;  | 
|
| 3193 | 
		};  | 
|
| 3194 | 
		 | 
|
| 3195 | 
		protected:  | 
|
| 3196 | 
		 | 
|
| 3197 | 
		    virtual void add(const Key& key) {
	 | 
|
| 3198 | 
		Parent::add(key);  | 
|
| 3199 | 
		unlace(key);  | 
|
| 3200 | 
		}  | 
|
| 3201 | 
		 | 
|
| 3202 | 
		    virtual void add(const std::vector<Key>& keys) {
	 | 
|
| 3203 | 
		Parent::add(keys);  | 
|
| 3204 | 
		      for (int i = 0; i < int(keys.size()); ++i) {
	 | 
|
| 3205 | 
		lace(keys[i]);  | 
|
| 3206 | 
		}  | 
|
| 3207 | 
		}  | 
|
| 3208 | 
		 | 
|
| 3209 | 
		    virtual void erase(const Key& key) {
	 | 
|
| 3210 | 
		unlace(key);  | 
|
| 3211 | 
		Parent::erase(key);  | 
|
| 3212 | 
		}  | 
|
| 3213 | 
		 | 
|
| 3214 | 
		    virtual void erase(const std::vector<Key>& keys) {
	 | 
|
| 3215 | 
		      for (int i = 0; i < int(keys.size()); ++i) {
	 | 
|
| 3216 | 
		unlace(keys[i]);  | 
|
| 3217 | 
		}  | 
|
| 3218 | 
		Parent::erase(keys);  | 
|
| 3219 | 
		}  | 
|
| 3220 | 
		 | 
|
| 3221 | 
		    virtual void build() {
	 | 
|
| 3222 | 
		Parent::build();  | 
|
| 3223 | 
		      for (typename Parent::ItemIt it(*this); it != INVALID; ++it) {
	 | 
|
| 3224 | 
		lace(it);  | 
|
| 3225 | 
		}  | 
|
| 3226 | 
		}  | 
|
| 3227 | 
		 | 
|
| 3228 | 
		    virtual void clear() {
	 | 
|
| 3229 | 
		_first.clear();  | 
|
| 3230 | 
		Parent::clear();  | 
|
| 3231 | 
		}  | 
|
| 3232 | 
		 | 
|
| 3233 | 
		private:  | 
|
| 3234 | 
		std::map<Value, Key> _first;  | 
|
| 3235 | 
		};  | 
|
| 3236 | 
		 | 
|
| 2341 | 3237 | 
		/// \brief Map of the source nodes of arcs in a digraph.  | 
| 2342 | 3238 | 
		///  | 
| 2343 | 3239 | 
		/// SourceMap provides access for the source node of each arc in a digraph,  | 
| ... | ... | 
		@@ -2507,7 +3403,7 @@  | 
| 2507 | 3403 | 
		/// in constant time. On the other hand, the values are updated automatically  | 
| 2508 | 3404 | 
		/// whenever the digraph changes.  | 
| 2509 | 3405 | 
		///  | 
| 2510 | 
		/// \warning Besides \c addNode() and \c addArc(), a digraph structure  | 
|
| 3406 | 
		/// \warning Besides \c addNode() and \c addArc(), a digraph structure  | 
|
| 2511 | 3407 | 
		/// may provide alternative ways to modify the digraph.  | 
| 2512 | 3408 | 
		/// The correct behavior of InDegMap is not guarantied if these additional  | 
| 2513 | 3409 | 
		/// features are used. For example the functions  | 
| ... | ... | 
		@@ -2523,7 +3419,7 @@  | 
| 2523 | 3419 | 
		      ::ItemNotifier::ObserverBase {
	 | 
| 2524 | 3420 | 
		 | 
| 2525 | 3421 | 
		public:  | 
| 2526 | 
		 | 
|
| 3422 | 
		 | 
|
| 2527 | 3423 | 
		/// The graph type of InDegMap  | 
| 2528 | 3424 | 
		typedef GR Graph;  | 
| 2529 | 3425 | 
		typedef GR Digraph;  | 
| ... | ... | 
		@@ -2637,7 +3533,7 @@  | 
| 2637 | 3533 | 
		/// in constant time. On the other hand, the values are updated automatically  | 
| 2638 | 3534 | 
		/// whenever the digraph changes.  | 
| 2639 | 3535 | 
		///  | 
| 2640 | 
		/// \warning Besides \c addNode() and \c addArc(), a digraph structure  | 
|
| 3536 | 
		/// \warning Besides \c addNode() and \c addArc(), a digraph structure  | 
|
| 2641 | 3537 | 
		/// may provide alternative ways to modify the digraph.  | 
| 2642 | 3538 | 
		/// The correct behavior of OutDegMap is not guarantied if these additional  | 
| 2643 | 3539 | 
		/// features are used. For example the functions  | 
| ... | ... | 
		@@ -31,6 +31,9 @@  | 
| 31 | 31 | 
		#include <lemon/maps.h>  | 
| 32 | 32 | 
		 | 
| 33 | 33 | 
		#include <lemon/bin_heap.h>  | 
| 34 | 
		#include <lemon/fib_heap.h>  | 
|
| 35 | 
		#include <lemon/radix_heap.h>  | 
|
| 36 | 
		#include <lemon/bucket_heap.h>  | 
|
| 34 | 37 | 
		 | 
| 35 | 38 | 
		#include "test_tools.h"  | 
| 36 | 39 | 
		 | 
| ... | ... | 
		@@ -183,5 +186,39 @@  | 
| 183 | 186 | 
		dijkstraHeapTest<NodeHeap>(digraph, length, source);  | 
| 184 | 187 | 
		}  | 
| 185 | 188 | 
		 | 
| 189 | 
		  {
	 | 
|
| 190 | 
		typedef FibHeap<Prio, ItemIntMap> IntHeap;  | 
|
| 191 | 
		checkConcept<Heap<Prio, ItemIntMap>, IntHeap>();  | 
|
| 192 | 
		heapSortTest<IntHeap>();  | 
|
| 193 | 
		heapIncreaseTest<IntHeap>();  | 
|
| 194 | 
		 | 
|
| 195 | 
		typedef FibHeap<Prio, IntNodeMap > NodeHeap;  | 
|
| 196 | 
		checkConcept<Heap<Prio, IntNodeMap >, NodeHeap>();  | 
|
| 197 | 
		dijkstraHeapTest<NodeHeap>(digraph, length, source);  | 
|
| 198 | 
		}  | 
|
| 199 | 
		 | 
|
| 200 | 
		  {
	 | 
|
| 201 | 
		typedef RadixHeap<ItemIntMap> IntHeap;  | 
|
| 202 | 
		checkConcept<Heap<Prio, ItemIntMap>, IntHeap>();  | 
|
| 203 | 
		heapSortTest<IntHeap>();  | 
|
| 204 | 
		heapIncreaseTest<IntHeap>();  | 
|
| 205 | 
		 | 
|
| 206 | 
		typedef RadixHeap<IntNodeMap > NodeHeap;  | 
|
| 207 | 
		checkConcept<Heap<Prio, IntNodeMap >, NodeHeap>();  | 
|
| 208 | 
		dijkstraHeapTest<NodeHeap>(digraph, length, source);  | 
|
| 209 | 
		}  | 
|
| 210 | 
		 | 
|
| 211 | 
		  {
	 | 
|
| 212 | 
		typedef BucketHeap<ItemIntMap> IntHeap;  | 
|
| 213 | 
		checkConcept<Heap<Prio, ItemIntMap>, IntHeap>();  | 
|
| 214 | 
		heapSortTest<IntHeap>();  | 
|
| 215 | 
		heapIncreaseTest<IntHeap>();  | 
|
| 216 | 
		 | 
|
| 217 | 
		typedef BucketHeap<IntNodeMap > NodeHeap;  | 
|
| 218 | 
		checkConcept<Heap<Prio, IntNodeMap >, NodeHeap>();  | 
|
| 219 | 
		dijkstraHeapTest<NodeHeap>(digraph, length, source);  | 
|
| 220 | 
		}  | 
|
| 221 | 
		 | 
|
| 222 | 
		 | 
|
| 186 | 223 | 
		return 0;  | 
| 187 | 224 | 
		}  | 
| ... | ... | 
		@@ -23,6 +23,7 @@  | 
| 23 | 23 | 
		#include <lemon/concepts/maps.h>  | 
| 24 | 24 | 
		#include <lemon/maps.h>  | 
| 25 | 25 | 
		#include <lemon/list_graph.h>  | 
| 26 | 
		#include <lemon/smart_graph.h>  | 
|
| 26 | 27 | 
		 | 
| 27 | 28 | 
		#include "test_tools.h"  | 
| 28 | 29 | 
		 | 
| ... | ... | 
		@@ -494,5 +495,192 @@  | 
| 494 | 495 | 
		it == map.endValue(), "Wrong value iterator");  | 
| 495 | 496 | 
		}  | 
| 496 | 497 | 
		 | 
| 498 | 
		// Iterable bool map  | 
|
| 499 | 
		  {
	 | 
|
| 500 | 
		typedef SmartGraph Graph;  | 
|
| 501 | 
		typedef SmartGraph::Node Item;  | 
|
| 502 | 
		 | 
|
| 503 | 
		typedef IterableBoolMap<SmartGraph, SmartGraph::Node> Ibm;  | 
|
| 504 | 
		checkConcept<ReferenceMap<Item, bool, bool&, const bool&>, Ibm>();  | 
|
| 505 | 
		 | 
|
| 506 | 
		const int num = 10;  | 
|
| 507 | 
		Graph g;  | 
|
| 508 | 
		std::vector<Item> items;  | 
|
| 509 | 
		    for (int i = 0; i < num; ++i) {
	 | 
|
| 510 | 
		items.push_back(g.addNode());  | 
|
| 511 | 
		}  | 
|
| 512 | 
		 | 
|
| 513 | 
		Ibm map1(g, true);  | 
|
| 514 | 
		int n = 0;  | 
|
| 515 | 
		    for (Ibm::TrueIt it(map1); it != INVALID; ++it) {
	 | 
|
| 516 | 
		check(map1[static_cast<Item>(it)], "Wrong TrueIt");  | 
|
| 517 | 
		++n;  | 
|
| 518 | 
		}  | 
|
| 519 | 
		check(n == num, "Wrong number");  | 
|
| 520 | 
		 | 
|
| 521 | 
		n = 0;  | 
|
| 522 | 
		    for (Ibm::ItemIt it(map1, true); it != INVALID; ++it) {
	 | 
|
| 523 | 
		check(map1[static_cast<Item>(it)], "Wrong ItemIt for true");  | 
|
| 524 | 
		++n;  | 
|
| 525 | 
		}  | 
|
| 526 | 
		check(n == num, "Wrong number");  | 
|
| 527 | 
		check(Ibm::FalseIt(map1) == INVALID, "Wrong FalseIt");  | 
|
| 528 | 
		check(Ibm::ItemIt(map1, false) == INVALID, "Wrong ItemIt for false");  | 
|
| 529 | 
		 | 
|
| 530 | 
		map1[items[5]] = true;  | 
|
| 531 | 
		 | 
|
| 532 | 
		n = 0;  | 
|
| 533 | 
		    for (Ibm::ItemIt it(map1, true); it != INVALID; ++it) {
	 | 
|
| 534 | 
		check(map1[static_cast<Item>(it)], "Wrong ItemIt for true");  | 
|
| 535 | 
		++n;  | 
|
| 536 | 
		}  | 
|
| 537 | 
		check(n == num, "Wrong number");  | 
|
| 538 | 
		 | 
|
| 539 | 
		map1[items[num / 2]] = false;  | 
|
| 540 | 
		check(map1[items[num / 2]] == false, "Wrong map value");  | 
|
| 541 | 
		 | 
|
| 542 | 
		n = 0;  | 
|
| 543 | 
		    for (Ibm::TrueIt it(map1); it != INVALID; ++it) {
	 | 
|
| 544 | 
		check(map1[static_cast<Item>(it)], "Wrong TrueIt for true");  | 
|
| 545 | 
		++n;  | 
|
| 546 | 
		}  | 
|
| 547 | 
		check(n == num - 1, "Wrong number");  | 
|
| 548 | 
		 | 
|
| 549 | 
		n = 0;  | 
|
| 550 | 
		    for (Ibm::FalseIt it(map1); it != INVALID; ++it) {
	 | 
|
| 551 | 
		check(!map1[static_cast<Item>(it)], "Wrong FalseIt for true");  | 
|
| 552 | 
		++n;  | 
|
| 553 | 
		}  | 
|
| 554 | 
		check(n == 1, "Wrong number");  | 
|
| 555 | 
		 | 
|
| 556 | 
		map1[items[0]] = false;  | 
|
| 557 | 
		check(map1[items[0]] == false, "Wrong map value");  | 
|
| 558 | 
		 | 
|
| 559 | 
		map1[items[num - 1]] = false;  | 
|
| 560 | 
		check(map1[items[num - 1]] == false, "Wrong map value");  | 
|
| 561 | 
		 | 
|
| 562 | 
		n = 0;  | 
|
| 563 | 
		    for (Ibm::TrueIt it(map1); it != INVALID; ++it) {
	 | 
|
| 564 | 
		check(map1[static_cast<Item>(it)], "Wrong TrueIt for true");  | 
|
| 565 | 
		++n;  | 
|
| 566 | 
		}  | 
|
| 567 | 
		check(n == num - 3, "Wrong number");  | 
|
| 568 | 
		check(map1.trueNum() == num - 3, "Wrong number");  | 
|
| 569 | 
		 | 
|
| 570 | 
		n = 0;  | 
|
| 571 | 
		    for (Ibm::FalseIt it(map1); it != INVALID; ++it) {
	 | 
|
| 572 | 
		check(!map1[static_cast<Item>(it)], "Wrong FalseIt for true");  | 
|
| 573 | 
		++n;  | 
|
| 574 | 
		}  | 
|
| 575 | 
		check(n == 3, "Wrong number");  | 
|
| 576 | 
		check(map1.falseNum() == 3, "Wrong number");  | 
|
| 577 | 
		}  | 
|
| 578 | 
		 | 
|
| 579 | 
		// Iterable int map  | 
|
| 580 | 
		  {
	 | 
|
| 581 | 
		typedef SmartGraph Graph;  | 
|
| 582 | 
		typedef SmartGraph::Node Item;  | 
|
| 583 | 
		typedef IterableIntMap<SmartGraph, SmartGraph::Node> Iim;  | 
|
| 584 | 
		 | 
|
| 585 | 
		checkConcept<ReferenceMap<Item, int, int&, const int&>, Iim>();  | 
|
| 586 | 
		 | 
|
| 587 | 
		const int num = 10;  | 
|
| 588 | 
		Graph g;  | 
|
| 589 | 
		std::vector<Item> items;  | 
|
| 590 | 
		    for (int i = 0; i < num; ++i) {
	 | 
|
| 591 | 
		items.push_back(g.addNode());  | 
|
| 592 | 
		}  | 
|
| 593 | 
		 | 
|
| 594 | 
		Iim map1(g);  | 
|
| 595 | 
		check(map1.size() == 0, "Wrong size");  | 
|
| 596 | 
		 | 
|
| 597 | 
		    for (int i = 0; i < num; ++i) {
	 | 
|
| 598 | 
		map1[items[i]] = i;  | 
|
| 599 | 
		}  | 
|
| 600 | 
		check(map1.size() == num, "Wrong size");  | 
|
| 601 | 
		 | 
|
| 602 | 
		    for (int i = 0; i < num; ++i) {
	 | 
|
| 603 | 
		Iim::ItemIt it(map1, i);  | 
|
| 604 | 
		check(static_cast<Item>(it) == items[i], "Wrong value");  | 
|
| 605 | 
		++it;  | 
|
| 606 | 
		check(static_cast<Item>(it) == INVALID, "Wrong value");  | 
|
| 607 | 
		}  | 
|
| 608 | 
		 | 
|
| 609 | 
		    for (int i = 0; i < num; ++i) {
	 | 
|
| 610 | 
		map1[items[i]] = i % 2;  | 
|
| 611 | 
		}  | 
|
| 612 | 
		check(map1.size() == 2, "Wrong size");  | 
|
| 613 | 
		 | 
|
| 614 | 
		int n = 0;  | 
|
| 615 | 
		    for (Iim::ItemIt it(map1, 0); it != INVALID; ++it) {
	 | 
|
| 616 | 
		check(map1[static_cast<Item>(it)] == 0, "Wrong value");  | 
|
| 617 | 
		++n;  | 
|
| 618 | 
		}  | 
|
| 619 | 
		check(n == (num + 1) / 2, "Wrong number");  | 
|
| 620 | 
		 | 
|
| 621 | 
		    for (Iim::ItemIt it(map1, 1); it != INVALID; ++it) {
	 | 
|
| 622 | 
		check(map1[static_cast<Item>(it)] == 1, "Wrong value");  | 
|
| 623 | 
		++n;  | 
|
| 624 | 
		}  | 
|
| 625 | 
		check(n == num, "Wrong number");  | 
|
| 626 | 
		 | 
|
| 627 | 
		}  | 
|
| 628 | 
		 | 
|
| 629 | 
		// Iterable value map  | 
|
| 630 | 
		  {
	 | 
|
| 631 | 
		typedef SmartGraph Graph;  | 
|
| 632 | 
		typedef SmartGraph::Node Item;  | 
|
| 633 | 
		typedef IterableValueMap<SmartGraph, SmartGraph::Node, double> Ivm;  | 
|
| 634 | 
		 | 
|
| 635 | 
		checkConcept<ReadWriteMap<Item, double>, Ivm>();  | 
|
| 636 | 
		 | 
|
| 637 | 
		const int num = 10;  | 
|
| 638 | 
		Graph g;  | 
|
| 639 | 
		std::vector<Item> items;  | 
|
| 640 | 
		    for (int i = 0; i < num; ++i) {
	 | 
|
| 641 | 
		items.push_back(g.addNode());  | 
|
| 642 | 
		}  | 
|
| 643 | 
		 | 
|
| 644 | 
		Ivm map1(g, 0.0);  | 
|
| 645 | 
		check(distance(map1.beginValue(), map1.endValue()) == 1, "Wrong size");  | 
|
| 646 | 
		check(*map1.beginValue() == 0.0, "Wrong value");  | 
|
| 647 | 
		 | 
|
| 648 | 
		    for (int i = 0; i < num; ++i) {
	 | 
|
| 649 | 
		map1.set(items[i], static_cast<double>(i));  | 
|
| 650 | 
		}  | 
|
| 651 | 
		check(distance(map1.beginValue(), map1.endValue()) == num, "Wrong size");  | 
|
| 652 | 
		 | 
|
| 653 | 
		    for (int i = 0; i < num; ++i) {
	 | 
|
| 654 | 
		Ivm::ItemIt it(map1, static_cast<double>(i));  | 
|
| 655 | 
		check(static_cast<Item>(it) == items[i], "Wrong value");  | 
|
| 656 | 
		++it;  | 
|
| 657 | 
		check(static_cast<Item>(it) == INVALID, "Wrong value");  | 
|
| 658 | 
		}  | 
|
| 659 | 
		 | 
|
| 660 | 
		for (Ivm::ValueIterator vit = map1.beginValue();  | 
|
| 661 | 
		         vit != map1.endValue(); ++vit) {
	 | 
|
| 662 | 
		check(map1[static_cast<Item>(Ivm::ItemIt(map1, *vit))] == *vit,  | 
|
| 663 | 
		"Wrong ValueIterator");  | 
|
| 664 | 
		}  | 
|
| 665 | 
		 | 
|
| 666 | 
		    for (int i = 0; i < num; ++i) {
	 | 
|
| 667 | 
		map1.set(items[i], static_cast<double>(i % 2));  | 
|
| 668 | 
		}  | 
|
| 669 | 
		check(distance(map1.beginValue(), map1.endValue()) == 2, "Wrong size");  | 
|
| 670 | 
		 | 
|
| 671 | 
		int n = 0;  | 
|
| 672 | 
		    for (Ivm::ItemIt it(map1, 0.0); it != INVALID; ++it) {
	 | 
|
| 673 | 
		check(map1[static_cast<Item>(it)] == 0.0, "Wrong value");  | 
|
| 674 | 
		++n;  | 
|
| 675 | 
		}  | 
|
| 676 | 
		check(n == (num + 1) / 2, "Wrong number");  | 
|
| 677 | 
		 | 
|
| 678 | 
		    for (Ivm::ItemIt it(map1, 1.0); it != INVALID; ++it) {
	 | 
|
| 679 | 
		check(map1[static_cast<Item>(it)] == 1.0, "Wrong value");  | 
|
| 680 | 
		++n;  | 
|
| 681 | 
		}  | 
|
| 682 | 
		check(n == num, "Wrong number");  | 
|
| 683 | 
		 | 
|
| 684 | 
		}  | 
|
| 497 | 685 | 
		return 0;  | 
| 498 | 686 | 
		}  | 
0 comments (0 inline)