diff -r 923f69c38d55 -r c8ccc1f8fd51 lemon/maps.h --- a/lemon/maps.h Wed May 17 11:05:34 2006 +0000 +++ b/lemon/maps.h Thu May 18 08:04:00 2006 +0000 @@ -20,6 +20,7 @@ #define LEMON_MAPS_H #include +#include #include #include @@ -1008,22 +1009,55 @@ return NotWriteMap(m); } + namespace _maps_bits { + template + struct Identity { + typedef Value argument_type; + typedef Value result_type; + Value operator()(const Value& val) { + return val; + } + }; + } + + /// \brief Writable bool map for store each true assigned elements. /// /// Writable bool map for store each true assigned elements. It will /// copies all the true setted keys to the given iterator. /// - /// \note The container of the iterator should contain for each element. - template + /// \note The container of the iterator should contain space + /// for each element. + /// + /// The next example shows how can you write the nodes directly + /// to the standard output. + ///\code + /// typedef IdMap UEdgeIdMap; + /// UEdgeIdMap uedgeId(ugraph); + /// + /// typedef MapFunctor UEdgeIdFunctor; + /// UEdgeIdFunctor uedgeIdFunctor(uedgeId); + /// + /// StoreBoolMap, UEdgeIdFunctor> + /// writerMap(ostream_iterator(cout, " "), uedgeIdFunctor); + /// + /// prim(ugraph, cost, writerMap); + ///\endcode + template ::value_type> > class StoreBoolMap { public: typedef _Iterator Iterator; - typedef typename std::iterator_traits::value_type Key; + typedef typename _Functor::argument_type Key; typedef bool Value; + typedef _Functor Functor; + /// Constructor - StoreBoolMap(Iterator it) : _begin(it), _end(it) {} + StoreBoolMap(Iterator it, const Functor& functor = Functor()) + : _begin(it), _end(it), _functor(functor) {} /// Gives back the given first setted iterator. Iterator begin() const { @@ -1038,12 +1072,13 @@ /// Setter function of the map void set(const Key& key, Value value) { if (value) { - *_end++ = key; + *_end++ = _functor(key); } } private: Iterator _begin, _end; + Functor _functor; }; /// \brief Writable bool map for store each true assigned elements in @@ -1051,25 +1086,43 @@ /// /// Writable bool map for store each true assigned elements in a back /// insertable container. It will push back all the true setted keys into - /// the container. - template + /// the container. It can be used to retrieve the items into a standard + /// container. The next example shows how can you store the undirected + /// edges in a vector with prim algorithm. + /// + ///\code + /// vector span_tree_uedges; + /// BackInserterBoolMap > inserter_map(span_tree_uedges); + /// prim(ugraph, cost, inserter_map); + /// + /// for (int i = 0; i < (int)span_tree_uedges.size(); ++i) { + /// std::cout << ugraph.id(ugraph.source(span_tree_uedges[i])) << ' ' + /// << ugraph.id(ugraph.target(span_tree_uedges[i])) << ' ' + /// << cost[span_tree_uedges[i]] << endl; + ///\endcode + template > class BackInserterBoolMap { public: typedef typename Container::value_type Key; typedef bool Value; /// Constructor - BackInserterBoolMap(Container& _container) : container(_container) {} + BackInserterBoolMap(Container& _container, + const Functor& _functor = Functor()) + : container(_container), functor(_functor) {} /// Setter function of the map void set(const Key& key, Value value) { if (value) { - container.push_back(key); + container.push_back(functor(key)); } } private: - Container& container; + Container& container; + Functor functor; }; /// \brief Writable bool map for store each true assigned elements in @@ -1077,15 +1130,19 @@ /// /// Writable bool map for store each true assigned elements in a front /// insertable container. It will push front all the true setted keys into - /// the container. - template + /// the container. For example see the BackInserterBoolMap. + template > class FrontInserterBoolMap { public: typedef typename Container::value_type Key; typedef bool Value; /// Constructor - FrontInserterBoolMap(Container& _container) : container(_container) {} + FrontInserterBoolMap(Container& _container, + const Functor& _functor = Functor()) + : container(_container), functor(_functor) {} /// Setter function of the map void set(const Key& key, Value value) { @@ -1096,6 +1153,7 @@ private: Container& container; + Functor functor; }; /// \brief Writable bool map for store each true assigned elements in @@ -1103,25 +1161,43 @@ /// /// Writable bool map for store each true assigned elements in an /// insertable container. It will insert all the true setted keys into - /// the container. - template + /// the container. If you want to store the cut edges of the strongly + /// connected components in a set you can use the next code: + /// + ///\code + /// set cut_edges; + /// InserterBoolMap > inserter_map(cut_edges); + /// stronglyConnectedCutEdges(graph, cost, inserter_map); + ///\endcode + template > class InserterBoolMap { public: typedef typename Container::value_type Key; typedef bool Value; /// Constructor - InserterBoolMap(Container& _container) : container(_container) {} + InserterBoolMap(Container& _container, typename Container::iterator _it, + const Functor& _functor = Functor()) + : container(_container), it(_it), functor(_functor) {} + + /// Constructor + InserterBoolMap(Container& _container, const Functor& _functor = Functor()) + : container(_container), it(_container.end()), functor(_functor) {} /// Setter function of the map void set(const Key& key, Value value) { if (value) { - container.insert(key); + it = container.insert(it, key); + ++it; } } private: - Container& container; + Container& container; + typename Container::iterator it; + Functor functor; }; /// \brief Fill the true setted elements with a given value. @@ -1129,6 +1205,27 @@ /// Writable bool map for fill the true setted elements with a given value. /// The value can be setted /// the container. + /// + /// The next code finds the connected components of the undirected graph + /// and stores it in the \c comp map: + ///\code + /// typedef UGraph::NodeMap ComponentMap; + /// ComponentMap comp(ugraph); + /// typedef FillBoolMap > ComponentFillerMap; + /// ComponentFillerMap filler(comp, 0); + /// + /// Dfs::DefProcessedMap::Create dfs(ugraph); + /// dfs.processedMap(filler); + /// dfs.init(); + /// for (NodeIt it(ugraph); it != INVALID; ++it) { + /// if (!dfs.reached(it)) { + /// dfs.addSource(it); + /// dfs.start(); + /// ++filler.fillValue(); + /// } + /// } + ///\endcode + template class FillBoolMap { public: @@ -1144,7 +1241,12 @@ : map(_map), fill() {} /// Gives back the current fill value - typename Map::Value fillValue() const { + const typename Map::Value& fillValue() const { + return fill; + } + + /// Gives back the current fill value + typename Map::Value& fillValue() { return fill; } @@ -1170,7 +1272,53 @@ /// the setting order number. /// /// Writable bool map which stores for each true assigned elements - /// the setting order number. + /// the setting order number. It make easy to calculate the leaving + /// order of the nodes in the \ref dfs "Dfs" algorithm. + /// + ///\code + /// typedef Graph::NodeMap OrderMap; + /// OrderMap order(graph); + /// typedef SettingOrderBoolMap OrderSetterMap; + /// OrderSetterMap setter(order); + /// Dfs::DefProcessedMap::Create dfs(graph); + /// dfs.processedMap(setter); + /// dfs.init(); + /// for (NodeIt it(graph); it != INVALID; ++it) { + /// if (!dfs.reached(it)) { + /// dfs.addSource(it); + /// dfs.start(); + /// } + /// } + ///\endcode + /// + /// The discovering order can be stored a little harder because the + /// ReachedMap should be readable in the dfs algorithm but the setting + /// order map is not readable. Now we should use the fork map: + /// + ///\code + /// typedef Graph::NodeMap OrderMap; + /// OrderMap order(graph); + /// typedef SettingOrderBoolMap OrderSetterMap; + /// OrderSetterMap setter(order); + /// typedef Graph::NodeMap StoreMap; + /// StoreMap store(graph); + /// + /// typedef ForkWriteMap ReachedMap; + /// ReachedMap reached(store, setter); + /// + /// Dfs::DefReachedMap::Create dfs(graph); + /// dfs.reachedMap(reached); + /// dfs.init(); + /// for (NodeIt it(graph); it != INVALID; ++it) { + /// if (!dfs.reached(it)) { + /// dfs.addSource(it); + /// dfs.start(); + /// } + /// } + /// for (NodeIt it(graph); it != INVALID; ++it) { + /// cout << graph.id(it) << ' ' << order[it] << endl; + /// } + ///\endcode template class SettingOrderBoolMap { public: