| alpar@209 |      1 | /* -*- mode: C++; indent-tabs-mode: nil; -*-
 | 
| alpar@103 |      2 |  *
 | 
| alpar@209 |      3 |  * This file is a part of LEMON, a generic C++ optimization library.
 | 
| alpar@103 |      4 |  *
 | 
| alpar@463 |      5 |  * Copyright (C) 2003-2009
 | 
| alpar@103 |      6 |  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
 | 
| alpar@103 |      7 |  * (Egervary Research Group on Combinatorial Optimization, EGRES).
 | 
| alpar@103 |      8 |  *
 | 
| alpar@103 |      9 |  * Permission to use, modify and distribute this software is granted
 | 
| alpar@103 |     10 |  * provided that this copyright notice appears in all copies. For
 | 
| alpar@103 |     11 |  * precise terms see the accompanying LICENSE file.
 | 
| alpar@103 |     12 |  *
 | 
| alpar@103 |     13 |  * This software is provided "AS IS" with no warranty of any kind,
 | 
| alpar@103 |     14 |  * express or implied, and with no claim as to its suitability for any
 | 
| alpar@103 |     15 |  * purpose.
 | 
| alpar@103 |     16 |  *
 | 
| alpar@103 |     17 |  */
 | 
| alpar@103 |     18 | 
 | 
| alpar@103 |     19 | #ifndef LEMON_KRUSKAL_H
 | 
| alpar@103 |     20 | #define LEMON_KRUSKAL_H
 | 
| alpar@103 |     21 | 
 | 
| alpar@103 |     22 | #include <algorithm>
 | 
| alpar@103 |     23 | #include <vector>
 | 
| alpar@103 |     24 | #include <lemon/unionfind.h>
 | 
| alpar@103 |     25 | #include <lemon/maps.h>
 | 
| alpar@103 |     26 | 
 | 
| deba@220 |     27 | #include <lemon/core.h>
 | 
| alpar@103 |     28 | #include <lemon/bits/traits.h>
 | 
| alpar@103 |     29 | 
 | 
| alpar@103 |     30 | ///\ingroup spantree
 | 
| alpar@103 |     31 | ///\file
 | 
| kpeter@194 |     32 | ///\brief Kruskal's algorithm to compute a minimum cost spanning tree
 | 
| alpar@103 |     33 | ///
 | 
| kpeter@194 |     34 | ///Kruskal's algorithm to compute a minimum cost spanning tree.
 | 
| alpar@103 |     35 | ///
 | 
| alpar@103 |     36 | 
 | 
| alpar@103 |     37 | namespace lemon {
 | 
| alpar@103 |     38 | 
 | 
| alpar@103 |     39 |   namespace _kruskal_bits {
 | 
| alpar@103 |     40 | 
 | 
| alpar@103 |     41 |     // Kruskal for directed graphs.
 | 
| alpar@103 |     42 | 
 | 
| alpar@103 |     43 |     template <typename Digraph, typename In, typename Out>
 | 
| alpar@103 |     44 |     typename disable_if<lemon::UndirectedTagIndicator<Digraph>,
 | 
| alpar@209 |     45 |                        typename In::value_type::second_type >::type
 | 
| alpar@103 |     46 |     kruskal(const Digraph& digraph, const In& in, Out& out,dummy<0> = 0) {
 | 
| alpar@103 |     47 |       typedef typename In::value_type::second_type Value;
 | 
| alpar@103 |     48 |       typedef typename Digraph::template NodeMap<int> IndexMap;
 | 
| alpar@103 |     49 |       typedef typename Digraph::Node Node;
 | 
| alpar@209 |     50 | 
 | 
| alpar@103 |     51 |       IndexMap index(digraph);
 | 
| alpar@103 |     52 |       UnionFind<IndexMap> uf(index);
 | 
| alpar@103 |     53 |       for (typename Digraph::NodeIt it(digraph); it != INVALID; ++it) {
 | 
| alpar@103 |     54 |         uf.insert(it);
 | 
| alpar@103 |     55 |       }
 | 
| alpar@209 |     56 | 
 | 
| alpar@103 |     57 |       Value tree_value = 0;
 | 
| alpar@103 |     58 |       for (typename In::const_iterator it = in.begin(); it != in.end(); ++it) {
 | 
| alpar@103 |     59 |         if (uf.join(digraph.target(it->first),digraph.source(it->first))) {
 | 
| alpar@103 |     60 |           out.set(it->first, true);
 | 
| alpar@103 |     61 |           tree_value += it->second;
 | 
| alpar@103 |     62 |         }
 | 
| alpar@103 |     63 |         else {
 | 
| alpar@103 |     64 |           out.set(it->first, false);
 | 
| alpar@103 |     65 |         }
 | 
| alpar@103 |     66 |       }
 | 
| alpar@103 |     67 |       return tree_value;
 | 
| alpar@103 |     68 |     }
 | 
| alpar@103 |     69 | 
 | 
| alpar@103 |     70 |     // Kruskal for undirected graphs.
 | 
| alpar@103 |     71 | 
 | 
| alpar@103 |     72 |     template <typename Graph, typename In, typename Out>
 | 
| alpar@103 |     73 |     typename enable_if<lemon::UndirectedTagIndicator<Graph>,
 | 
| alpar@209 |     74 |                        typename In::value_type::second_type >::type
 | 
| alpar@103 |     75 |     kruskal(const Graph& graph, const In& in, Out& out,dummy<1> = 1) {
 | 
| alpar@103 |     76 |       typedef typename In::value_type::second_type Value;
 | 
| alpar@103 |     77 |       typedef typename Graph::template NodeMap<int> IndexMap;
 | 
| alpar@103 |     78 |       typedef typename Graph::Node Node;
 | 
| alpar@209 |     79 | 
 | 
| alpar@103 |     80 |       IndexMap index(graph);
 | 
| alpar@103 |     81 |       UnionFind<IndexMap> uf(index);
 | 
| alpar@103 |     82 |       for (typename Graph::NodeIt it(graph); it != INVALID; ++it) {
 | 
| alpar@103 |     83 |         uf.insert(it);
 | 
| alpar@103 |     84 |       }
 | 
| alpar@209 |     85 | 
 | 
| alpar@103 |     86 |       Value tree_value = 0;
 | 
| alpar@103 |     87 |       for (typename In::const_iterator it = in.begin(); it != in.end(); ++it) {
 | 
| alpar@103 |     88 |         if (uf.join(graph.u(it->first),graph.v(it->first))) {
 | 
| alpar@103 |     89 |           out.set(it->first, true);
 | 
| alpar@103 |     90 |           tree_value += it->second;
 | 
| alpar@103 |     91 |         }
 | 
| alpar@103 |     92 |         else {
 | 
| alpar@103 |     93 |           out.set(it->first, false);
 | 
| alpar@103 |     94 |         }
 | 
| alpar@103 |     95 |       }
 | 
| alpar@103 |     96 |       return tree_value;
 | 
| alpar@103 |     97 |     }
 | 
| alpar@103 |     98 | 
 | 
| alpar@103 |     99 | 
 | 
| alpar@103 |    100 |     template <typename Sequence>
 | 
| alpar@103 |    101 |     struct PairComp {
 | 
| alpar@103 |    102 |       typedef typename Sequence::value_type Value;
 | 
| alpar@103 |    103 |       bool operator()(const Value& left, const Value& right) {
 | 
| alpar@209 |    104 |         return left.second < right.second;
 | 
| alpar@103 |    105 |       }
 | 
| alpar@103 |    106 |     };
 | 
| alpar@103 |    107 | 
 | 
| alpar@103 |    108 |     template <typename In, typename Enable = void>
 | 
| alpar@103 |    109 |     struct SequenceInputIndicator {
 | 
| alpar@103 |    110 |       static const bool value = false;
 | 
| alpar@103 |    111 |     };
 | 
| alpar@103 |    112 | 
 | 
| alpar@103 |    113 |     template <typename In>
 | 
| alpar@209 |    114 |     struct SequenceInputIndicator<In,
 | 
| alpar@103 |    115 |       typename exists<typename In::value_type::first_type>::type> {
 | 
| alpar@103 |    116 |       static const bool value = true;
 | 
| alpar@103 |    117 |     };
 | 
| alpar@103 |    118 | 
 | 
| alpar@103 |    119 |     template <typename In, typename Enable = void>
 | 
| alpar@103 |    120 |     struct MapInputIndicator {
 | 
| alpar@103 |    121 |       static const bool value = false;
 | 
| alpar@103 |    122 |     };
 | 
| alpar@103 |    123 | 
 | 
| alpar@103 |    124 |     template <typename In>
 | 
| alpar@209 |    125 |     struct MapInputIndicator<In,
 | 
| alpar@103 |    126 |       typename exists<typename In::Value>::type> {
 | 
| alpar@103 |    127 |       static const bool value = true;
 | 
| alpar@103 |    128 |     };
 | 
| alpar@103 |    129 | 
 | 
| alpar@103 |    130 |     template <typename In, typename Enable = void>
 | 
| alpar@103 |    131 |     struct SequenceOutputIndicator {
 | 
| alpar@103 |    132 |       static const bool value = false;
 | 
| alpar@103 |    133 |     };
 | 
| alpar@209 |    134 | 
 | 
| alpar@103 |    135 |     template <typename Out>
 | 
| alpar@209 |    136 |     struct SequenceOutputIndicator<Out,
 | 
| alpar@103 |    137 |       typename exists<typename Out::value_type>::type> {
 | 
| alpar@103 |    138 |       static const bool value = true;
 | 
| alpar@103 |    139 |     };
 | 
| alpar@103 |    140 | 
 | 
| alpar@103 |    141 |     template <typename Out, typename Enable = void>
 | 
| alpar@103 |    142 |     struct MapOutputIndicator {
 | 
| alpar@103 |    143 |       static const bool value = false;
 | 
| alpar@103 |    144 |     };
 | 
| alpar@103 |    145 | 
 | 
| alpar@103 |    146 |     template <typename Out>
 | 
| alpar@209 |    147 |     struct MapOutputIndicator<Out,
 | 
| alpar@103 |    148 |       typename exists<typename Out::Value>::type> {
 | 
| alpar@103 |    149 |       static const bool value = true;
 | 
| alpar@103 |    150 |     };
 | 
| alpar@103 |    151 | 
 | 
| alpar@103 |    152 |     template <typename In, typename InEnable = void>
 | 
| alpar@103 |    153 |     struct KruskalValueSelector {};
 | 
| alpar@103 |    154 | 
 | 
| alpar@103 |    155 |     template <typename In>
 | 
| alpar@103 |    156 |     struct KruskalValueSelector<In,
 | 
| alpar@209 |    157 |       typename enable_if<SequenceInputIndicator<In>, void>::type>
 | 
| alpar@103 |    158 |     {
 | 
| alpar@103 |    159 |       typedef typename In::value_type::second_type Value;
 | 
| alpar@209 |    160 |     };
 | 
| alpar@103 |    161 | 
 | 
| alpar@103 |    162 |     template <typename In>
 | 
| alpar@103 |    163 |     struct KruskalValueSelector<In,
 | 
| alpar@209 |    164 |       typename enable_if<MapInputIndicator<In>, void>::type>
 | 
| alpar@103 |    165 |     {
 | 
| alpar@103 |    166 |       typedef typename In::Value Value;
 | 
| alpar@209 |    167 |     };
 | 
| alpar@209 |    168 | 
 | 
| alpar@103 |    169 |     template <typename Graph, typename In, typename Out,
 | 
| alpar@103 |    170 |               typename InEnable = void>
 | 
| alpar@103 |    171 |     struct KruskalInputSelector {};
 | 
| alpar@103 |    172 | 
 | 
| alpar@103 |    173 |     template <typename Graph, typename In, typename Out,
 | 
| alpar@103 |    174 |               typename InEnable = void>
 | 
| alpar@103 |    175 |     struct KruskalOutputSelector {};
 | 
| alpar@209 |    176 | 
 | 
| alpar@103 |    177 |     template <typename Graph, typename In, typename Out>
 | 
| alpar@103 |    178 |     struct KruskalInputSelector<Graph, In, Out,
 | 
| alpar@209 |    179 |       typename enable_if<SequenceInputIndicator<In>, void>::type >
 | 
| alpar@103 |    180 |     {
 | 
| alpar@103 |    181 |       typedef typename In::value_type::second_type Value;
 | 
| alpar@103 |    182 | 
 | 
| alpar@103 |    183 |       static Value kruskal(const Graph& graph, const In& in, Out& out) {
 | 
| alpar@103 |    184 |         return KruskalOutputSelector<Graph, In, Out>::
 | 
| alpar@103 |    185 |           kruskal(graph, in, out);
 | 
| alpar@103 |    186 |       }
 | 
| alpar@103 |    187 | 
 | 
| alpar@103 |    188 |     };
 | 
| alpar@103 |    189 | 
 | 
| alpar@103 |    190 |     template <typename Graph, typename In, typename Out>
 | 
| alpar@103 |    191 |     struct KruskalInputSelector<Graph, In, Out,
 | 
| alpar@209 |    192 |       typename enable_if<MapInputIndicator<In>, void>::type >
 | 
| alpar@103 |    193 |     {
 | 
| alpar@103 |    194 |       typedef typename In::Value Value;
 | 
| alpar@103 |    195 |       static Value kruskal(const Graph& graph, const In& in, Out& out) {
 | 
| alpar@103 |    196 |         typedef typename In::Key MapArc;
 | 
| alpar@103 |    197 |         typedef typename In::Value Value;
 | 
| alpar@103 |    198 |         typedef typename ItemSetTraits<Graph, MapArc>::ItemIt MapArcIt;
 | 
| alpar@103 |    199 |         typedef std::vector<std::pair<MapArc, Value> > Sequence;
 | 
| alpar@103 |    200 |         Sequence seq;
 | 
| alpar@209 |    201 | 
 | 
| alpar@103 |    202 |         for (MapArcIt it(graph); it != INVALID; ++it) {
 | 
| alpar@103 |    203 |           seq.push_back(std::make_pair(it, in[it]));
 | 
| alpar@103 |    204 |         }
 | 
| alpar@103 |    205 | 
 | 
| alpar@103 |    206 |         std::sort(seq.begin(), seq.end(), PairComp<Sequence>());
 | 
| alpar@103 |    207 |         return KruskalOutputSelector<Graph, Sequence, Out>::
 | 
| alpar@103 |    208 |           kruskal(graph, seq, out);
 | 
| alpar@103 |    209 |       }
 | 
| alpar@103 |    210 |     };
 | 
| alpar@103 |    211 | 
 | 
| deba@136 |    212 |     template <typename T>
 | 
| deba@136 |    213 |     struct RemoveConst {
 | 
| deba@136 |    214 |       typedef T type;
 | 
| deba@136 |    215 |     };
 | 
| deba@136 |    216 | 
 | 
| deba@136 |    217 |     template <typename T>
 | 
| deba@136 |    218 |     struct RemoveConst<const T> {
 | 
| deba@136 |    219 |       typedef T type;
 | 
| deba@136 |    220 |     };
 | 
| deba@136 |    221 | 
 | 
| alpar@103 |    222 |     template <typename Graph, typename In, typename Out>
 | 
| alpar@103 |    223 |     struct KruskalOutputSelector<Graph, In, Out,
 | 
| alpar@209 |    224 |       typename enable_if<SequenceOutputIndicator<Out>, void>::type >
 | 
| alpar@103 |    225 |     {
 | 
| alpar@103 |    226 |       typedef typename In::value_type::second_type Value;
 | 
| alpar@103 |    227 | 
 | 
| alpar@103 |    228 |       static Value kruskal(const Graph& graph, const In& in, Out& out) {
 | 
| kpeter@167 |    229 |         typedef LoggerBoolMap<typename RemoveConst<Out>::type> Map;
 | 
| alpar@103 |    230 |         Map map(out);
 | 
| alpar@103 |    231 |         return _kruskal_bits::kruskal(graph, in, map);
 | 
| alpar@103 |    232 |       }
 | 
| alpar@103 |    233 | 
 | 
| alpar@103 |    234 |     };
 | 
| alpar@103 |    235 | 
 | 
| alpar@103 |    236 |     template <typename Graph, typename In, typename Out>
 | 
| alpar@103 |    237 |     struct KruskalOutputSelector<Graph, In, Out,
 | 
| alpar@209 |    238 |       typename enable_if<MapOutputIndicator<Out>, void>::type >
 | 
| alpar@103 |    239 |     {
 | 
| alpar@103 |    240 |       typedef typename In::value_type::second_type Value;
 | 
| alpar@103 |    241 | 
 | 
| alpar@103 |    242 |       static Value kruskal(const Graph& graph, const In& in, Out& out) {
 | 
| alpar@103 |    243 |         return _kruskal_bits::kruskal(graph, in, out);
 | 
| alpar@103 |    244 |       }
 | 
| alpar@103 |    245 |     };
 | 
| alpar@103 |    246 | 
 | 
| alpar@103 |    247 |   }
 | 
| alpar@103 |    248 | 
 | 
| alpar@103 |    249 |   /// \ingroup spantree
 | 
| alpar@103 |    250 |   ///
 | 
| kpeter@194 |    251 |   /// \brief Kruskal algorithm to find a minimum cost spanning tree of
 | 
| kpeter@194 |    252 |   /// a graph.
 | 
| alpar@103 |    253 |   ///
 | 
| alpar@209 |    254 |   /// This function runs Kruskal's algorithm to find a minimum cost
 | 
| kpeter@194 |    255 |   /// spanning tree.
 | 
| alpar@103 |    256 |   /// Due to some C++ hacking, it accepts various input and output types.
 | 
| alpar@103 |    257 |   ///
 | 
| alpar@103 |    258 |   /// \param g The graph the algorithm runs on.
 | 
| alpar@209 |    259 |   /// It can be either \ref concepts::Digraph "directed" or
 | 
| alpar@103 |    260 |   /// \ref concepts::Graph "undirected".
 | 
| alpar@209 |    261 |   /// If the graph is directed, the algorithm consider it to be
 | 
| alpar@103 |    262 |   /// undirected by disregarding the direction of the arcs.
 | 
| alpar@103 |    263 |   ///
 | 
| alpar@209 |    264 |   /// \param in This object is used to describe the arc/edge costs.
 | 
| kpeter@194 |    265 |   /// It can be one of the following choices.
 | 
| alpar@103 |    266 |   /// - An STL compatible 'Forward Container' with
 | 
| kpeter@194 |    267 |   /// <tt>std::pair<GR::Arc,X></tt> or
 | 
| kpeter@194 |    268 |   /// <tt>std::pair<GR::Edge,X></tt> as its <tt>value_type</tt>, where
 | 
| kpeter@194 |    269 |   /// \c X is the type of the costs. The pairs indicates the arcs/edges
 | 
| alpar@103 |    270 |   /// along with the assigned cost. <em>They must be in a
 | 
| alpar@103 |    271 |   /// cost-ascending order.</em>
 | 
| alpar@209 |    272 |   /// - Any readable arc/edge map. The values of the map indicate the
 | 
| kpeter@194 |    273 |   /// arc/edge costs.
 | 
| alpar@103 |    274 |   ///
 | 
| kpeter@194 |    275 |   /// \retval out Here we also have a choice.
 | 
| kpeter@194 |    276 |   /// - It can be a writable \c bool arc/edge map. After running the
 | 
| kpeter@194 |    277 |   /// algorithm it will contain the found minimum cost spanning
 | 
| kpeter@194 |    278 |   /// tree: the value of an arc/edge will be set to \c true if it belongs
 | 
| alpar@103 |    279 |   /// to the tree, otherwise it will be set to \c false. The value of
 | 
| kpeter@194 |    280 |   /// each arc/edge will be set exactly once.
 | 
| alpar@103 |    281 |   /// - It can also be an iteraror of an STL Container with
 | 
| kpeter@194 |    282 |   /// <tt>GR::Arc</tt> or <tt>GR::Edge</tt> as its
 | 
| alpar@103 |    283 |   /// <tt>value_type</tt>.  The algorithm copies the elements of the
 | 
| alpar@103 |    284 |   /// found tree into this sequence.  For example, if we know that the
 | 
| alpar@103 |    285 |   /// spanning tree of the graph \c g has say 53 arcs, then we can
 | 
| alpar@103 |    286 |   /// put its arcs into an STL vector \c tree with a code like this.
 | 
| alpar@103 |    287 |   ///\code
 | 
| alpar@103 |    288 |   /// std::vector<Arc> tree(53);
 | 
| alpar@103 |    289 |   /// kruskal(g,cost,tree.begin());
 | 
| alpar@103 |    290 |   ///\endcode
 | 
| alpar@103 |    291 |   /// Or if we don't know in advance the size of the tree, we can
 | 
| alpar@209 |    292 |   /// write this.
 | 
| kpeter@194 |    293 |   ///\code
 | 
| kpeter@194 |    294 |   /// std::vector<Arc> tree;
 | 
| alpar@209 |    295 |   /// kruskal(g,cost,std::back_inserter(tree));
 | 
| alpar@103 |    296 |   ///\endcode
 | 
| alpar@103 |    297 |   ///
 | 
| kpeter@194 |    298 |   /// \return The total cost of the found spanning tree.
 | 
| alpar@103 |    299 |   ///
 | 
| deba@220 |    300 |   /// \note If the input graph is not (weakly) connected, a spanning
 | 
| kpeter@216 |    301 |   /// forest is calculated instead of a spanning tree.
 | 
| alpar@103 |    302 | 
 | 
| alpar@103 |    303 | #ifdef DOXYGEN
 | 
| alpar@103 |    304 |   template <class Graph, class In, class Out>
 | 
| alpar@103 |    305 |   Value kruskal(GR const& g, const In& in, Out& out)
 | 
| alpar@209 |    306 | #else
 | 
| alpar@103 |    307 |   template <class Graph, class In, class Out>
 | 
| alpar@209 |    308 |   inline typename _kruskal_bits::KruskalValueSelector<In>::Value
 | 
| alpar@209 |    309 |   kruskal(const Graph& graph, const In& in, Out& out)
 | 
| alpar@103 |    310 | #endif
 | 
| alpar@103 |    311 |   {
 | 
| alpar@103 |    312 |     return _kruskal_bits::KruskalInputSelector<Graph, In, Out>::
 | 
| alpar@103 |    313 |       kruskal(graph, in, out);
 | 
| alpar@103 |    314 |   }
 | 
| alpar@103 |    315 | 
 | 
| alpar@209 |    316 | 
 | 
| alpar@209 |    317 | 
 | 
| alpar@103 |    318 | 
 | 
| alpar@103 |    319 |   template <class Graph, class In, class Out>
 | 
| alpar@103 |    320 |   inline typename _kruskal_bits::KruskalValueSelector<In>::Value
 | 
| alpar@103 |    321 |   kruskal(const Graph& graph, const In& in, const Out& out)
 | 
| alpar@103 |    322 |   {
 | 
| alpar@103 |    323 |     return _kruskal_bits::KruskalInputSelector<Graph, In, const Out>::
 | 
| alpar@103 |    324 |       kruskal(graph, in, out);
 | 
| alpar@209 |    325 |   }
 | 
| alpar@103 |    326 | 
 | 
| alpar@103 |    327 | } //namespace lemon
 | 
| alpar@103 |    328 | 
 | 
| alpar@103 |    329 | #endif //LEMON_KRUSKAL_H
 |