alpar@1677: /* -*- C++ -*- alpar@1677: * lemon/iterable_maps.h - Part of LEMON, a generic C++ optimization library alpar@1677: * alpar@1875: * Copyright (C) 2006 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport alpar@1677: * (Egervary Research Group on Combinatorial Optimization, EGRES). alpar@1677: * alpar@1677: * Permission to use, modify and distribute this software is granted alpar@1677: * provided that this copyright notice appears in all copies. For alpar@1677: * precise terms see the accompanying LICENSE file. alpar@1677: * alpar@1677: * This software is provided "AS IS" with no warranty of any kind, alpar@1677: * express or implied, and with no claim as to its suitability for any alpar@1677: * purpose. alpar@1677: * alpar@1677: */ alpar@1677: deba@1752: #include deba@1752: #include alpar@1677: #include alpar@1677: #include alpar@1677: alpar@1677: ///\ingroup maps alpar@1677: ///\file alpar@1677: ///\brief Maps that makes it possible to iterate through the keys having alpar@1677: ///a certain value alpar@1677: /// alpar@1677: /// alpar@1677: alpar@1677: alpar@1677: namespace lemon { deba@1913: deba@1913: ///\ingroup maps deba@1913: /// deba@1913: /// \brief Dynamic iterable bool map. deba@1913: /// deba@1913: /// This class provides a special graph map type which can store deba@1913: /// for each graph item(node, edge, etc.) a bool value. For both deba@1913: /// the true and the false it is possible to iterate on the keys which deba@1913: /// mapped to the given value. deba@1913: /// deba@1913: /// \param _Graph The graph type. deba@1913: /// \param _Item One of the graph's item type, the key of the map. deba@1913: template deba@1913: class IterableBoolMap deba@1913: : protected ItemSetTraits<_Graph, _Item>::template Map::Parent { deba@1913: private: deba@1913: typedef _Graph Graph; deba@1913: typedef _Item Item; deba@1913: deba@1913: typedef typename ItemSetTraits::ItemIt ItemIt; deba@1913: typedef typename ItemSetTraits deba@1913: ::template Map::Parent Parent; deba@1913: deba@1913: std::vector array; deba@1913: int sep; deba@1913: deba@1913: const Graph& graph; alpar@1677: alpar@1677: private: alpar@1677: deba@1913: int position(const Item& item) const { deba@1913: return Parent::operator[](item); alpar@1677: } alpar@1677: alpar@1677: public: alpar@1805: deba@1913: /// Indicates that the map if reference map. deba@1913: typedef True ReferenceMapTag; alpar@1805: deba@1913: /// The key type deba@1913: typedef Item Key; deba@1913: /// The value type deba@1913: typedef bool Value; deba@1913: /// The const reference type. deba@1913: typedef const Value& ConstReference; deba@1913: deba@1913: deba@1913: /// \brief Refernce to the value of the map. deba@1913: /// deba@1913: /// This class is near to similar to the bool type. It can deba@1913: /// be converted to bool and it has the same operators. deba@1913: class Reference { deba@1913: friend class IterableBoolMap; deba@1913: private: deba@1913: Reference(IterableBoolMap& map, const Key& key) deba@1913: : _key(key), _map(map) {} alpar@1677: public: deba@1913: deba@1913: Reference& operator=(const Reference& value) { deba@1913: _map.set(_key, (bool)value); deba@1913: return *this; deba@1913: } deba@1913: deba@1913: operator bool() const { deba@1913: return static_cast(_map)[_key]; deba@1913: } deba@1913: deba@1913: Reference& operator=(bool value) { deba@1913: _map.set(_key, value); deba@1913: return *this; deba@1913: } deba@1913: Reference& operator&=(bool value) { deba@1913: _map.set(_key, _map[_key] & value); deba@1913: return *this; deba@1913: } deba@1913: Reference& operator|=(bool value) { deba@1913: _map.set(_key, _map[_key] | value); deba@1913: return *this; deba@1913: } deba@1913: Reference& operator^=(bool value) { deba@1913: _map.set(_key, _map[_key] ^ value); deba@1913: return *this; deba@1913: } deba@1913: private: deba@1913: Key _key; deba@1913: IterableBoolMap& _map; alpar@1677: }; deba@1913: deba@1913: /// \brief Constructor of the Map with a default value. deba@1913: /// deba@1913: /// Constructor of the Map with a default value. deba@1913: IterableBoolMap(const Graph& _graph, bool def = false) deba@1913: : Parent(_graph), graph(_graph) { deba@1913: for (ItemIt it(graph); it != INVALID; ++it) { deba@1913: Parent::set(it, array.size()); deba@1913: array.push_back(it); deba@1913: } deba@1913: sep = (def ? array.size() : 0); deba@1913: } deba@1913: deba@1913: /// \brief Const subscript operator of the map. deba@1913: /// deba@1913: /// Const subscript operator of the map. deba@1913: bool operator[](const Item& item) const { deba@1913: return position(item) < sep; deba@1913: } deba@1913: deba@1913: /// \brief Subscript operator of the map. deba@1913: /// deba@1913: /// Subscript operator of the map. deba@1913: Reference operator[](const Item& item) { deba@1913: return Reference(*this, item); deba@1913: } deba@1913: deba@1913: /// \brief Set operation of the map. deba@1913: /// deba@1913: /// Set operation of the map. deba@1913: void set(const Item& item, bool value) { deba@1913: int pos = position(item); deba@1913: if (value) { deba@1913: if (pos < sep) return; deba@1913: Item tmp = array[sep]; deba@1913: array[sep] = item; deba@1913: Parent::set(item, sep); deba@1913: array[pos] = tmp; deba@1913: Parent::set(tmp, pos); deba@1913: ++sep; deba@1913: } else { deba@1913: if (pos >= sep) return; deba@1913: --sep; deba@1913: Item tmp = array[sep]; deba@1913: array[sep] = item; deba@1913: Parent::set(item, sep); deba@1913: array[pos] = tmp; deba@1913: Parent::set(tmp, pos); deba@1913: } deba@1913: } deba@1913: deba@1913: /// \brief Returns the number of the items mapped to true. deba@1913: /// deba@1913: /// Returns the number of the items mapped to true. deba@1913: int trueNum() const { deba@1913: return sep; deba@1913: } deba@1913: deba@1913: /// \brief Returns the number of the items mapped to false. deba@1913: /// deba@1913: /// Returns the number of the items mapped to false. deba@1913: int falseNum() const { deba@1913: return array.size() - sep; deba@1913: } deba@1913: deba@1913: /// \brief Iterator for the keys mapped to true. deba@1913: /// deba@1913: /// Iterator for the keys mapped to true. It works deba@1913: /// like a graph item iterator in the map, it can be converted deba@1913: /// the item type of the map, incremented with \c ++ operator, and deba@1913: /// if the iterator leave the last valid item it will be equal to deba@1913: /// \c INVALID. deba@1913: class TrueIt : public Item { alpar@1677: public: deba@1913: typedef Item Parent; deba@1913: deba@1913: /// \brief Creates an iterator. deba@1913: /// deba@1913: /// Creates an iterator. It iterates on the deba@1913: /// keys which mapped to true. deba@1913: /// \param map The IterableIntMap deba@1913: TrueIt(const IterableBoolMap& _map) deba@1913: : Parent(_map.sep > 0 ? _map.array[_map.sep - 1] : INVALID), deba@1913: map(&_map) {} deba@1913: deba@1913: /// \brief Invalid constructor \& conversion. deba@1913: /// deba@1913: /// This constructor initializes the item to be invalid. deba@1913: /// \sa Invalid for more details. deba@1913: TrueIt(Invalid) : Parent(INVALID), map(0) {} deba@1913: deba@1913: /// \brief Increment operator. deba@1913: /// deba@1913: /// Increment Operator. deba@1913: TrueIt& operator++() { deba@1913: int pos = map->position(*this); deba@1913: Parent::operator=(pos > 0 ? map->array[pos - 1] : INVALID); deba@1913: return *this; deba@1913: } deba@1913: deba@1913: deba@1913: private: deba@1913: const IterableBoolMap* map; deba@1913: }; deba@1913: deba@1913: /// \brief Iterator for the keys mapped to false. deba@1913: /// deba@1913: /// Iterator for the keys mapped to false. It works deba@1913: /// like a graph item iterator in the map, it can be converted deba@1913: /// the item type of the map, incremented with \c ++ operator, and deba@1913: /// if the iterator leave the last valid item it will be equal to deba@1913: /// \c INVALID. deba@1913: class FalseIt : public Item { deba@1913: public: deba@1913: typedef Item Parent; deba@1913: deba@1913: /// \brief Creates an iterator. deba@1913: /// deba@1913: /// Creates an iterator. It iterates on the deba@1913: /// keys which mapped to false. deba@1913: /// \param map The IterableIntMap deba@1913: FalseIt(const IterableBoolMap& _map) deba@1913: : Parent(_map.sep < _map.array.size() ? _map.array.back() : INVALID), deba@1913: map(&_map) {} deba@1913: deba@1913: /// \brief Invalid constructor \& conversion. deba@1913: /// deba@1913: /// This constructor initializes the item to be invalid. deba@1913: /// \sa Invalid for more details. deba@1913: FalseIt(Invalid) : Parent(INVALID), map(0) {} deba@1913: deba@1913: /// \brief Increment operator. deba@1913: /// deba@1913: /// Increment Operator. deba@1913: FalseIt& operator++() { deba@1913: int pos = map->position(*this); deba@1913: Parent::operator=(pos > map->sep ? map->array[pos - 1] : INVALID); deba@1913: return *this; deba@1913: } deba@1913: deba@1913: private: deba@1913: const IterableBoolMap* map; deba@1913: }; deba@1913: deba@1913: protected: deba@1913: deba@1913: virtual void add(const Item& item) { deba@1913: Parent::add(item); deba@1913: Parent::set(item, array.size()); deba@1913: array.push_back(item); deba@1913: } deba@1913: deba@1913: virtual void add(const std::vector& items) { deba@1913: Parent::add(items); deba@1913: for (int i = 0; i < (int)items.size(); ++i) { deba@1913: Parent::set(items[i], array.size()); deba@1913: array.push_back(items[i]); deba@1913: } deba@1913: } deba@1913: deba@1913: virtual void erase(const Item& item) { deba@1913: int pos = position(item); deba@1913: if (pos < sep) { deba@1913: --sep; deba@1913: Parent::set(array[sep], pos); deba@1913: array[pos] = array[sep]; deba@1913: Parent::set(array.back(), sep); deba@1913: array[sep] = array.back(); deba@1913: array.pop_back(); deba@1913: } else { deba@1913: Parent::set(array.back(), pos); deba@1913: array[pos] = array.back(); deba@1913: array.pop_back(); deba@1913: } deba@1913: Parent::erase(item); deba@1913: } deba@1913: deba@1913: virtual void erase(const std::vector& items) { deba@1913: for (int i = 0; i < (int)items.size(); ++i) { deba@1913: int pos = position(items[i]); deba@1913: if (pos < sep) { deba@1913: --sep; deba@1913: Parent::set(array[sep], pos); deba@1913: array[pos] = array[sep]; deba@1913: Parent::set(array.back(), sep); deba@1913: array[sep] = array.back(); deba@1913: array.pop_back(); deba@1913: } else { deba@1913: Parent::set(array.back(), pos); deba@1913: array[pos] = array.back(); deba@1913: array.pop_back(); deba@1913: } deba@1913: } deba@1913: Parent::erase(items); deba@1913: } deba@1913: deba@1913: virtual void build() { deba@1913: Parent::build(); deba@1913: for (ItemIt it(graph); it != INVALID; ++it) { deba@1913: Parent::set(it, array.size()); deba@1913: array.push_back(it); deba@1913: } deba@1913: sep = 0; deba@1913: } deba@1913: deba@1913: virtual void clear() { deba@1913: array.clear(); deba@1913: sep = 0; deba@1913: Parent::clear(); deba@1913: } deba@1913: alpar@1677: }; alpar@1873: deba@1752: deba@1752: namespace _iterable_maps_bits { deba@1752: template deba@1752: struct IterableIntMapNode { deba@1913: IterableIntMapNode() : value(-1) {} deba@1810: IterableIntMapNode(int _value) : value(_value) {} deba@1752: Item prev, next; deba@1752: int value; deba@1752: }; deba@1752: } deba@1752: deba@1752: ///\ingroup maps deba@1752: /// deba@1752: /// \brief Dynamic iterable integer map. deba@1752: /// deba@1810: /// This class provides a special graph map type which can store deba@1810: /// for each graph item(node, edge, etc.) an integer value. For each deba@1810: /// non negative value it is possible to iterate on the keys which deba@1810: /// mapped to the given value. deba@1810: /// deba@1810: /// \param _Graph The graph type. deba@1810: /// \param _Item One of the graph's item type, the key of the map. deba@1752: template deba@1752: class IterableIntMap : protected ItemSetTraits<_Graph, _Item> deba@1752: ::template Map<_iterable_maps_bits::IterableIntMapNode<_Item> >::Parent { deba@1752: public: deba@1752: typedef typename ItemSetTraits<_Graph, _Item> deba@1752: ::template Map<_iterable_maps_bits::IterableIntMapNode<_Item> > deba@1752: ::Parent Parent; deba@1752: deba@1810: /// The key type deba@1752: typedef _Item Key; deba@1810: /// The value type deba@1752: typedef int Value; deba@1810: /// The graph type deba@1752: typedef _Graph Graph; deba@1752: deba@1810: /// \brief Constructor of the Map. deba@1810: /// deba@1810: /// Constructor of the Map. It set all values -1. deba@1810: explicit IterableIntMap(const Graph& graph) deba@1913: : Parent(graph) {} deba@1810: deba@1810: /// \brief Constructor of the Map with a given value. deba@1810: /// deba@1810: /// Constructor of the Map with a given value. deba@1810: explicit IterableIntMap(const Graph& graph, int value) deba@1810: : Parent(graph, _iterable_maps_bits::IterableIntMapNode<_Item>(value)) { deba@1810: if (value >= 0) { deba@1810: for (typename Parent::ItemIt it(*this); it != INVALID; ++it) { deba@1810: lace(it); deba@1810: } deba@1810: } deba@1810: } deba@1752: deba@1752: private: deba@1752: deba@1752: void unlace(const Key& key) { deba@1752: typename Parent::Value& node = Parent::operator[](key); deba@1752: if (node.value < 0) return; deba@1752: if (node.prev != INVALID) { deba@1752: Parent::operator[](node.prev).next = node.next; deba@1752: } else { deba@1752: first[node.value] = node.next; deba@1752: } deba@1752: if (node.next != INVALID) { deba@1752: Parent::operator[](node.next).prev = node.prev; deba@1752: } deba@1752: while (!first.empty() && first.back() == INVALID) { deba@1752: first.pop_back(); deba@1752: } deba@1752: } deba@1752: deba@1752: void lace(const Key& key) { deba@1752: typename Parent::Value& node = Parent::operator[](key); deba@1752: if (node.value < 0) return; deba@1752: if (node.value >= (int)first.size()) { deba@1752: first.resize(node.value + 1, INVALID); deba@1752: } deba@1752: node.prev = INVALID; deba@1752: node.next = first[node.value]; deba@1752: if (node.next != INVALID) { deba@1752: Parent::operator[](node.next).prev = key; deba@1752: } deba@1752: first[node.value] = key; deba@1752: } deba@1752: deba@1752: public: deba@1752: deba@1810: /// Indicates that the map if reference map. deba@1752: typedef True ReferenceMapTag; deba@1752: deba@1810: /// \brief Refernce to the value of the map. deba@1810: /// deba@1810: /// This class is near to similar to the int type. It can deba@1810: /// be converted to int and it has the same operators. deba@1752: class Reference { deba@1752: friend class IterableIntMap; deba@1752: private: deba@1752: Reference(IterableIntMap& map, const Key& key) deba@1752: : _key(key), _map(map) {} deba@1752: public: deba@1752: deba@1752: Reference& operator=(const Reference& value) { deba@1752: _map.set(_key, (const int&)value); deba@1752: return *this; deba@1752: } deba@1752: deba@1752: operator const int&() const { deba@1752: return static_cast(_map)[_key]; deba@1752: } deba@1752: deba@1752: Reference& operator=(int value) { deba@1752: _map.set(_key, value); deba@1752: return *this; deba@1752: } deba@1759: Reference& operator++() { deba@1759: _map.set(_key, _map[_key] + 1); deba@1759: return *this; deba@1759: } deba@1759: int operator++(int) { deba@1759: int value = _map[_key]; deba@1759: _map.set(_key, value + 1); deba@1759: return value; deba@1759: } deba@1759: Reference& operator--() { deba@1759: _map.set(_key, _map[_key] - 1); deba@1759: return *this; deba@1759: } deba@1759: int operator--(int) { deba@1759: int value = _map[_key]; deba@1759: _map.set(_key, value - 1); deba@1759: return value; deba@1759: } deba@1752: Reference& operator+=(int value) { deba@1752: _map.set(_key, _map[_key] + value); deba@1752: return *this; deba@1752: } deba@1752: Reference& operator-=(int value) { deba@1752: _map.set(_key, _map[_key] - value); deba@1752: return *this; deba@1752: } deba@1752: Reference& operator*=(int value) { deba@1752: _map.set(_key, _map[_key] * value); deba@1752: return *this; deba@1752: } deba@1752: Reference& operator/=(int value) { deba@1752: _map.set(_key, _map[_key] / value); deba@1752: return *this; deba@1752: } deba@1752: Reference& operator%=(int value) { deba@1752: _map.set(_key, _map[_key] % value); deba@1752: return *this; deba@1752: } deba@1752: Reference& operator&=(int value) { deba@1752: _map.set(_key, _map[_key] & value); deba@1752: return *this; deba@1752: } deba@1752: Reference& operator|=(int value) { deba@1752: _map.set(_key, _map[_key] | value); deba@1752: return *this; deba@1752: } deba@1752: Reference& operator^=(int value) { deba@1752: _map.set(_key, _map[_key] ^ value); deba@1752: return *this; deba@1752: } deba@1752: Reference& operator<<=(int value) { deba@1752: _map.set(_key, _map[_key] << value); deba@1752: return *this; deba@1752: } deba@1752: Reference& operator>>=(int value) { deba@1752: _map.set(_key, _map[_key] >> value); deba@1752: return *this; deba@1752: } deba@1752: deba@1752: private: deba@1752: Key _key; deba@1752: IterableIntMap& _map; deba@1752: }; deba@1810: deba@1810: /// The const reference type. deba@1752: typedef const Value& ConstReference; deba@1752: deba@1810: /// \brief Gives back the maximal value plus one. deba@1810: /// deba@1810: /// Gives back the maximal value plus one. deba@1752: int size() const { deba@1752: return (int)first.size(); deba@1752: } deba@1752: deba@1810: /// \brief Set operation of the map. deba@1810: /// deba@1810: /// Set operation of the map. deba@1752: void set(const Key& key, const Value& value) { deba@1752: unlace(key); deba@1752: Parent::operator[](key).value = value; deba@1752: lace(key); deba@1752: } deba@1752: deba@1810: /// \brief Const subscript operator of the map. deba@1810: /// deba@1810: /// Const subscript operator of the map. deba@1752: const Value& operator[](const Key& key) const { deba@1752: return Parent::operator[](key).value; deba@1752: } deba@1752: deba@1810: /// \brief Subscript operator of the map. deba@1810: /// deba@1810: /// Subscript operator of the map. deba@1752: Reference operator[](const Key& key) { deba@1752: return Reference(*this, key); deba@1752: } deba@1752: deba@1810: /// \brief Iterator for the keys with the same value. deba@1810: /// deba@1810: /// Iterator for the keys with the same value. It works deba@1810: /// like a graph item iterator in the map, it can be converted deba@1810: /// the item type of the map, incremented with \c ++ operator, and deba@1810: /// if the iterator leave the last valid item it will be equal to deba@1810: /// \c INVALID. deba@1752: class ItemIt : public _Item { deba@1752: public: deba@1752: typedef _Item Parent; deba@1752: deba@1810: /// \brief Invalid constructor \& conversion. deba@1810: /// deba@1810: /// This constructor initializes the item to be invalid. deba@1810: /// \sa Invalid for more details. deba@1752: ItemIt(Invalid) : Parent(INVALID), _map(0) {} deba@1752: deba@1810: /// \brief Creates an iterator with a value. deba@1810: /// deba@1810: /// Creates an iterator with a value. It iterates on the deba@1810: /// keys which have the given value. deba@1810: /// \param map The IterableIntMap deba@1810: /// \param value The value deba@1752: ItemIt(const IterableIntMap& map, int value) : _map(&map) { deba@1752: if (value < 0 || value >= (int)_map->first.size()) { deba@1752: Parent::operator=(INVALID); deba@1752: } else { deba@1752: Parent::operator=(_map->first[value]); deba@1752: } deba@1752: } deba@1752: deba@1810: /// \brief Increment operator. deba@1810: /// deba@1810: /// Increment Operator. deba@1752: ItemIt& operator++() { deba@1752: Parent::operator=(_map->IterableIntMap::Parent:: deba@1752: operator[](static_cast(*this)).next); deba@1752: return *this; deba@1752: } deba@1752: deba@1752: deba@1752: private: deba@1752: const IterableIntMap* _map; deba@1752: }; deba@1752: deba@1752: protected: deba@1752: deba@1752: virtual void erase(const Key& key) { deba@1752: unlace(key); deba@1752: Parent::erase(key); deba@1752: } deba@1752: deba@1913: virtual void erase(const std::vector& keys) { deba@1913: for (int i = 0; i < keys.size(); ++i) { deba@1913: unlace(keys[i]); deba@1913: } deba@1913: Parent::erase(keys); deba@1913: } deba@1913: deba@1752: virtual void clear() { deba@1752: first.clear(); deba@1752: Parent::clear(); deba@1752: } deba@1752: deba@1752: private: deba@1752: std::vector<_Item> first; deba@1752: }; deba@1752: alpar@1677: /// @} alpar@1677: }