src/work/johanna/kruskal.h
author alpar
Thu, 22 Jul 2004 14:21:46 +0000
changeset 727 aada518af30f
parent 394 3a34c5626e52
child 737 2d867176d10e
permissions -rw-r--r--
- Better Makefile.am. (I hope.)
- Some more tests
beckerjc@150
     1
// -*- c++ -*- //
beckerjc@150
     2
#ifndef HUGO_KRUSKAL_H
beckerjc@150
     3
#define HUGO_KRUSKAL_H
beckerjc@150
     4
beckerjc@150
     5
#include <algorithm>
beckerjc@349
     6
#include <unionfind.h>
beckerjc@349
     7
#include <for_each_macros.h>
beckerjc@150
     8
alpar@682
     9
///\file
alpar@682
    10
///\brief Kruskal's algorithm to compute a minimum cost tree
alpar@682
    11
beckerjc@150
    12
namespace hugo {
beckerjc@150
    13
beckerjc@349
    14
  /// Kruskal's algorithm to compute a minimum cost tree
beckerjc@150
    15
beckerjc@349
    16
  template <typename Graph, typename InputEdgeOrder, typename OutBoolMap>
beckerjc@349
    17
  typename InputEdgeOrder::ValueType
beckerjc@349
    18
  Kruskal(Graph const& G, InputEdgeOrder const& edges, 
beckerjc@349
    19
	  OutBoolMap& out_map)
beckerjc@349
    20
  {
beckerjc@349
    21
    typedef typename InputEdgeOrder::ValueType EdgeCost;
beckerjc@349
    22
    typedef typename Graph::NodeMap<int> NodeIntMap;
beckerjc@349
    23
    typedef typename Graph::Node Node;
beckerjc@246
    24
beckerjc@349
    25
    NodeIntMap comp_map(G, -1);
beckerjc@349
    26
    UnionFind<Node,NodeIntMap> uf(comp_map); 
beckerjc@349
    27
      
beckerjc@349
    28
    EdgeCost tot_cost = 0;
beckerjc@349
    29
    for (typename InputEdgeOrder::const_iterator p = edges.begin(); 
beckerjc@349
    30
	 p!=edges.end(); ++p ) {
beckerjc@394
    31
      if ( uf.join(G.head(edges.first(p)),
beckerjc@349
    32
			     G.tail(edges.first(p))) ) {
beckerjc@349
    33
	out_map.set(edges.first(p), true);
beckerjc@349
    34
	tot_cost += edges.second(p);
beckerjc@349
    35
      }
beckerjc@349
    36
      else {
beckerjc@349
    37
	out_map.set(edges.first(p), false);
beckerjc@349
    38
      }
beckerjc@349
    39
    }
beckerjc@349
    40
    return tot_cost;
beckerjc@349
    41
  }
beckerjc@246
    42
beckerjc@352
    43
  /* A work-around for running Kruskal with const-reference bool maps... */
beckerjc@352
    44
beckerjc@352
    45
  template<typename Map>
beckerjc@352
    46
  class NonConstMapWr {
beckerjc@352
    47
    const Map &m;
beckerjc@352
    48
  public:
beckerjc@352
    49
    typedef typename Map::ValueType ValueType;
beckerjc@352
    50
beckerjc@352
    51
    NonConstMapWr(const Map &_m) : m(_m) {}
beckerjc@352
    52
beckerjc@352
    53
    template<typename KeyType>
beckerjc@352
    54
    void set(KeyType const& k, ValueType const &v) const { m.set(k,v); }
beckerjc@352
    55
  };
beckerjc@352
    56
beckerjc@352
    57
  template <typename Graph, typename InputEdgeOrder, typename OutBoolMap>
beckerjc@352
    58
  inline
beckerjc@352
    59
  typename InputEdgeOrder::ValueType
beckerjc@352
    60
  Kruskal(Graph const& G, InputEdgeOrder const& edges, 
beckerjc@352
    61
	  OutBoolMap const& out_map)
beckerjc@352
    62
  {
beckerjc@352
    63
    NonConstMapWr<OutBoolMap> map_wr(out_map);
beckerjc@352
    64
    return Kruskal(G, edges, map_wr);
beckerjc@352
    65
  }  
beckerjc@246
    66
beckerjc@349
    67
  
beckerjc@349
    68
  /* ** ** Output-objektumok: egyszeruen extra bool mapek ** ** */
beckerjc@349
    69
  
beckerjc@349
    70
  /// A writable bool-map that makes a sequence of "true" keys
beckerjc@246
    71
beckerjc@349
    72
  /// A writable bool-map that creates a sequence out of keys that receive
beckerjc@349
    73
  /// the value "true".
beckerjc@349
    74
  /// \warning Not a regular property map, as it doesn't know its KeyType
beckerjc@246
    75
beckerjc@349
    76
  template<typename Iterator>
beckerjc@349
    77
  class SequenceOutput {
beckerjc@352
    78
    mutable Iterator it;
beckerjc@150
    79
beckerjc@218
    80
  public:
beckerjc@349
    81
    typedef bool ValueType;
beckerjc@150
    82
beckerjc@349
    83
    SequenceOutput(Iterator const &_it) : it(_it) {}
beckerjc@150
    84
beckerjc@349
    85
    template<typename KeyType>
beckerjc@352
    86
    void set(KeyType const& k, bool v) const { if(v) {*it=k; ++it;} }
beckerjc@218
    87
  };
beckerjc@150
    88
beckerjc@349
    89
  template<typename Iterator>
beckerjc@349
    90
  inline
beckerjc@349
    91
  SequenceOutput<Iterator>
beckerjc@349
    92
  makeSequenceOutput(Iterator it) {
beckerjc@349
    93
    return SequenceOutput<Iterator>(it);
beckerjc@349
    94
  }
beckerjc@246
    95
beckerjc@246
    96
  /* ** ** InputSource -ok ** ** */
beckerjc@246
    97
beckerjc@246
    98
  template<typename Key, typename Val>
beckerjc@349
    99
  class KruskalPairVec : public std::vector< std::pair<Key,Val> > {
beckerjc@246
   100
beckerjc@246
   101
  public:
beckerjc@246
   102
    typedef std::vector< std::pair<Key,Val> > Parent;
beckerjc@246
   103
    typedef Key KeyType;
beckerjc@246
   104
    typedef Val ValueType;
beckerjc@246
   105
    typedef std::pair<Key,Val> PairType;
beckerjc@246
   106
beckerjc@246
   107
    typedef typename Parent::iterator iterator;
beckerjc@246
   108
    typedef typename Parent::const_iterator const_iterator;
beckerjc@246
   109
beckerjc@246
   110
  private:
beckerjc@246
   111
    class comparePair {
beckerjc@246
   112
    public:
beckerjc@246
   113
      bool operator()(PairType const& a, PairType const& b) {
beckerjc@246
   114
	return a.second < b.second;
beckerjc@246
   115
      }
beckerjc@246
   116
    };
beckerjc@246
   117
beckerjc@246
   118
  public:
beckerjc@246
   119
beckerjc@246
   120
    // FIXME: kell ez?
beckerjc@349
   121
    // KruskalPairVec(Parent const& p) : Parent(p) {}
beckerjc@246
   122
    
beckerjc@246
   123
    void sort() {
beckerjc@246
   124
      std::sort(begin(), end(), comparePair());
beckerjc@246
   125
    }
beckerjc@246
   126
beckerjc@246
   127
    // FIXME: nem nagyon illik ez ide...
beckerjc@246
   128
    template<typename Graph, typename Map>
beckerjc@349
   129
    KruskalPairVec(Graph const& G, Map const& m) {
beckerjc@246
   130
      typedef typename Graph::EdgeIt EdgeIt;
beckerjc@246
   131
beckerjc@246
   132
      clear();
beckerjc@349
   133
      FOR_EACH_LOC(EdgeIt, e, G) {
beckerjc@349
   134
      // for (EdgeIt e=G.template first<EdgeIt>(); G.valid(e); G.next(e)) {
beckerjc@246
   135
	push_back(make_pair(e, m[e]));
beckerjc@246
   136
      }
beckerjc@246
   137
      sort();
beckerjc@246
   138
    }
beckerjc@246
   139
beckerjc@246
   140
    Key const& first(const_iterator i) const { return i->first; }
beckerjc@246
   141
    Key& first(iterator i) { return i->first; }
beckerjc@246
   142
beckerjc@246
   143
    Val const& second(const_iterator i) const { return i->second; }
beckerjc@246
   144
    Val& second(iterator i) { return i->second; }
beckerjc@246
   145
  };
beckerjc@246
   146
beckerjc@349
   147
beckerjc@349
   148
  template <typename Map>
beckerjc@349
   149
  class KruskalMapVec : public std::vector<typename Map::KeyType> {
beckerjc@349
   150
  public:
beckerjc@349
   151
beckerjc@349
   152
    typedef typename Map::KeyType KeyType;
beckerjc@349
   153
    typedef typename Map::ValueType ValueType;
beckerjc@349
   154
beckerjc@349
   155
    typedef typename std::vector<KeyType> Parent;
beckerjc@349
   156
    typedef typename Parent::iterator iterator;
beckerjc@349
   157
    typedef typename Parent::const_iterator const_iterator;
beckerjc@349
   158
beckerjc@349
   159
  private:
beckerjc@349
   160
beckerjc@349
   161
    const Map &m;
beckerjc@349
   162
beckerjc@349
   163
    class compareKeys {
beckerjc@349
   164
      const Map &m;
beckerjc@349
   165
    public:
beckerjc@349
   166
      compareKeys(Map const &_m) : m(_m) {}
beckerjc@349
   167
      bool operator()(KeyType const& a, KeyType const& b) {
beckerjc@349
   168
	return m[a] < m[b];
beckerjc@349
   169
      }
beckerjc@349
   170
    };
beckerjc@349
   171
beckerjc@349
   172
  public:
beckerjc@349
   173
beckerjc@349
   174
    KruskalMapVec(Map const& _m) : m(_m) {}
beckerjc@349
   175
beckerjc@349
   176
    void sort() {
beckerjc@349
   177
      std::sort(begin(), end(), compareKeys(m));
beckerjc@349
   178
    }
beckerjc@349
   179
beckerjc@349
   180
    // FIXME: nem nagyon illik ez ide...
beckerjc@349
   181
    template<typename Graph>
beckerjc@349
   182
    KruskalMapVec(Graph const& G, Map const& _m) : m(_m) {
beckerjc@349
   183
      typedef typename Graph::EdgeIt EdgeIt;
beckerjc@349
   184
beckerjc@349
   185
      clear();
beckerjc@349
   186
      FOR_EACH_LOC(EdgeIt, e, G) {
beckerjc@349
   187
      // for (EdgeIt e=G.template first<EdgeIt>(); G.valid(e); G.next(e)) {
beckerjc@349
   188
	push_back(e);
beckerjc@349
   189
      }
beckerjc@349
   190
      sort();
beckerjc@349
   191
    }
beckerjc@349
   192
beckerjc@349
   193
    KeyType const& first(const_iterator i) const { return *i; }
beckerjc@349
   194
    KeyType& first(iterator i) { return *i; }
beckerjc@349
   195
beckerjc@349
   196
    ValueType const& second(const_iterator i) const { return m[*i]; }
beckerjc@349
   197
    ValueType& second(iterator i) { return m[*i]; }
beckerjc@349
   198
  };
beckerjc@349
   199
beckerjc@246
   200
  /* ** ** Wrapper fuggvenyek ** ** */
beckerjc@246
   201
beckerjc@349
   202
beckerjc@349
   203
  /// \brief Wrapper to Kruskal().
beckerjc@349
   204
  /// Input is from an EdgeMap, output is a plain boolmap.
beckerjc@246
   205
  template <typename Graph, typename EdgeCostMap, typename RetEdgeBoolMap>
beckerjc@352
   206
  inline
beckerjc@246
   207
  typename EdgeCostMap::ValueType
beckerjc@349
   208
  Kruskal_EdgeCostMapIn_BoolMapOut(Graph const& G,
beckerjc@349
   209
				   EdgeCostMap const& edge_costs,
beckerjc@349
   210
				   RetEdgeBoolMap &ret_bool_map) {
beckerjc@246
   211
beckerjc@349
   212
    typedef KruskalPairVec<typename Graph::Edge, typename EdgeCostMap::ValueType>
beckerjc@246
   213
      InputVec;
beckerjc@349
   214
    InputVec iv(G, edge_costs);
beckerjc@246
   215
beckerjc@349
   216
    return Kruskal(G, iv, ret_bool_map);
beckerjc@246
   217
  }
beckerjc@246
   218
beckerjc@349
   219
beckerjc@349
   220
  /// \brief Wrapper to Kruskal().
beckerjc@349
   221
  /// Input is from an EdgeMap, output is to a sequence.
beckerjc@246
   222
  template <typename Graph, typename EdgeCostMap, typename RetIterator>
beckerjc@352
   223
  inline
beckerjc@246
   224
  typename EdgeCostMap::ValueType
beckerjc@349
   225
  Kruskal_EdgeCostMapIn_IteratorOut(Graph const& G,
beckerjc@349
   226
				    EdgeCostMap const& edge_costs,
beckerjc@349
   227
				    RetIterator ret_iterator) {
beckerjc@349
   228
    typedef SequenceOutput<RetIterator> OutMap;
beckerjc@349
   229
    OutMap out(ret_iterator);
beckerjc@246
   230
beckerjc@349
   231
    typedef KruskalPairVec<typename Graph::Edge, typename EdgeCostMap::ValueType>
beckerjc@246
   232
      InputVec;
beckerjc@349
   233
    InputVec iv(G, edge_costs);
beckerjc@246
   234
beckerjc@349
   235
    return Kruskal(G, iv, out);
beckerjc@246
   236
  }
beckerjc@246
   237
beckerjc@150
   238
beckerjc@150
   239
} //namespace hugo
beckerjc@150
   240
beckerjc@150
   241
#endif //HUGO_KRUSKAL_H