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