src/work/johanna/kruskal.h
author beckerjc
Sat, 17 Apr 2004 19:19:57 +0000
changeset 349 42c660f58702
parent 246 dc95ca4ebc7b
child 352 4b89077ab715
permissions -rw-r--r--
Kruskal lenyegeben kesz.
Kell meg dokumentalni, meg meg egy par jol hasznalhato wrapper fv.
Es valamit meg kene csinalni azzal, hogy nem const ref. a kimeno boolmap,
viszont sokszor "on-the-fly" akarjuk megkonstrualni (es ilyenkor persze a
const-os mapet is lehet set-elni...)
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@349
    28
      if ( uf.joinComponents(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@246
    40
beckerjc@349
    41
  
beckerjc@349
    42
  /* ** ** Output-objektumok: egyszeruen extra bool mapek ** ** */
beckerjc@349
    43
  
beckerjc@349
    44
  /// A writable bool-map that makes a sequence of "true" keys
beckerjc@246
    45
beckerjc@349
    46
  /// A writable bool-map that creates a sequence out of keys that receive
beckerjc@349
    47
  /// the value "true".
beckerjc@349
    48
  /// \warning Not a regular property map, as it doesn't know its KeyType
beckerjc@246
    49
beckerjc@349
    50
  template<typename Iterator>
beckerjc@349
    51
  class SequenceOutput {
beckerjc@349
    52
    Iterator it;
beckerjc@150
    53
beckerjc@218
    54
  public:
beckerjc@349
    55
    typedef bool ValueType;
beckerjc@150
    56
beckerjc@349
    57
    SequenceOutput(Iterator const &_it) : it(_it) {}
beckerjc@150
    58
beckerjc@349
    59
    template<typename KeyType>
beckerjc@349
    60
    void set(KeyType const& k, bool v) { if(v) {*it=k; ++it;} }
beckerjc@218
    61
  };
beckerjc@150
    62
beckerjc@349
    63
  template<typename Iterator>
beckerjc@349
    64
  inline
beckerjc@349
    65
  SequenceOutput<Iterator>
beckerjc@349
    66
  makeSequenceOutput(Iterator it) {
beckerjc@349
    67
    return SequenceOutput<Iterator>(it);
beckerjc@349
    68
  }
beckerjc@246
    69
beckerjc@246
    70
  /* ** ** InputSource -ok ** ** */
beckerjc@246
    71
beckerjc@246
    72
  template<typename Key, typename Val>
beckerjc@349
    73
  class KruskalPairVec : public std::vector< std::pair<Key,Val> > {
beckerjc@246
    74
beckerjc@246
    75
  public:
beckerjc@246
    76
    typedef std::vector< std::pair<Key,Val> > Parent;
beckerjc@246
    77
    typedef Key KeyType;
beckerjc@246
    78
    typedef Val ValueType;
beckerjc@246
    79
    typedef std::pair<Key,Val> PairType;
beckerjc@246
    80
beckerjc@246
    81
    typedef typename Parent::iterator iterator;
beckerjc@246
    82
    typedef typename Parent::const_iterator const_iterator;
beckerjc@246
    83
beckerjc@246
    84
  private:
beckerjc@246
    85
    class comparePair {
beckerjc@246
    86
    public:
beckerjc@246
    87
      bool operator()(PairType const& a, PairType const& b) {
beckerjc@246
    88
	return a.second < b.second;
beckerjc@246
    89
      }
beckerjc@246
    90
    };
beckerjc@246
    91
beckerjc@246
    92
  public:
beckerjc@246
    93
beckerjc@246
    94
    // FIXME: kell ez?
beckerjc@349
    95
    // KruskalPairVec(Parent const& p) : Parent(p) {}
beckerjc@246
    96
    
beckerjc@246
    97
    void sort() {
beckerjc@246
    98
      std::sort(begin(), end(), comparePair());
beckerjc@246
    99
    }
beckerjc@246
   100
beckerjc@246
   101
    // FIXME: nem nagyon illik ez ide...
beckerjc@246
   102
    template<typename Graph, typename Map>
beckerjc@349
   103
    KruskalPairVec(Graph const& G, Map const& m) {
beckerjc@246
   104
      typedef typename Graph::EdgeIt EdgeIt;
beckerjc@246
   105
beckerjc@246
   106
      clear();
beckerjc@349
   107
      FOR_EACH_LOC(EdgeIt, e, G) {
beckerjc@349
   108
      // for (EdgeIt e=G.template first<EdgeIt>(); G.valid(e); G.next(e)) {
beckerjc@246
   109
	push_back(make_pair(e, m[e]));
beckerjc@246
   110
      }
beckerjc@246
   111
      sort();
beckerjc@246
   112
    }
beckerjc@246
   113
beckerjc@246
   114
    Key const& first(const_iterator i) const { return i->first; }
beckerjc@246
   115
    Key& first(iterator i) { return i->first; }
beckerjc@246
   116
beckerjc@246
   117
    Val const& second(const_iterator i) const { return i->second; }
beckerjc@246
   118
    Val& second(iterator i) { return i->second; }
beckerjc@246
   119
  };
beckerjc@246
   120
beckerjc@349
   121
beckerjc@349
   122
  template <typename Map>
beckerjc@349
   123
  class KruskalMapVec : public std::vector<typename Map::KeyType> {
beckerjc@349
   124
  public:
beckerjc@349
   125
beckerjc@349
   126
    typedef typename Map::KeyType KeyType;
beckerjc@349
   127
    typedef typename Map::ValueType ValueType;
beckerjc@349
   128
beckerjc@349
   129
    typedef typename std::vector<KeyType> Parent;
beckerjc@349
   130
    typedef typename Parent::iterator iterator;
beckerjc@349
   131
    typedef typename Parent::const_iterator const_iterator;
beckerjc@349
   132
beckerjc@349
   133
  private:
beckerjc@349
   134
beckerjc@349
   135
    const Map &m;
beckerjc@349
   136
beckerjc@349
   137
    class compareKeys {
beckerjc@349
   138
      const Map &m;
beckerjc@349
   139
    public:
beckerjc@349
   140
      compareKeys(Map const &_m) : m(_m) {}
beckerjc@349
   141
      bool operator()(KeyType const& a, KeyType const& b) {
beckerjc@349
   142
	return m[a] < m[b];
beckerjc@349
   143
      }
beckerjc@349
   144
    };
beckerjc@349
   145
beckerjc@349
   146
  public:
beckerjc@349
   147
beckerjc@349
   148
    KruskalMapVec(Map const& _m) : m(_m) {}
beckerjc@349
   149
beckerjc@349
   150
    void sort() {
beckerjc@349
   151
      std::sort(begin(), end(), compareKeys(m));
beckerjc@349
   152
    }
beckerjc@349
   153
beckerjc@349
   154
    // FIXME: nem nagyon illik ez ide...
beckerjc@349
   155
    template<typename Graph>
beckerjc@349
   156
    KruskalMapVec(Graph const& G, Map const& _m) : m(_m) {
beckerjc@349
   157
      typedef typename Graph::EdgeIt EdgeIt;
beckerjc@349
   158
beckerjc@349
   159
      clear();
beckerjc@349
   160
      FOR_EACH_LOC(EdgeIt, e, G) {
beckerjc@349
   161
      // for (EdgeIt e=G.template first<EdgeIt>(); G.valid(e); G.next(e)) {
beckerjc@349
   162
	push_back(e);
beckerjc@349
   163
      }
beckerjc@349
   164
      sort();
beckerjc@349
   165
    }
beckerjc@349
   166
beckerjc@349
   167
    KeyType const& first(const_iterator i) const { return *i; }
beckerjc@349
   168
    KeyType& first(iterator i) { return *i; }
beckerjc@349
   169
beckerjc@349
   170
    ValueType const& second(const_iterator i) const { return m[*i]; }
beckerjc@349
   171
    ValueType& second(iterator i) { return m[*i]; }
beckerjc@349
   172
  };
beckerjc@349
   173
beckerjc@246
   174
  /* ** ** Wrapper fuggvenyek ** ** */
beckerjc@246
   175
beckerjc@349
   176
beckerjc@349
   177
  /// \brief Wrapper to Kruskal().
beckerjc@349
   178
  /// Input is from an EdgeMap, output is a plain boolmap.
beckerjc@246
   179
  template <typename Graph, typename EdgeCostMap, typename RetEdgeBoolMap>
beckerjc@246
   180
  typename EdgeCostMap::ValueType
beckerjc@349
   181
  Kruskal_EdgeCostMapIn_BoolMapOut(Graph const& G,
beckerjc@349
   182
				   EdgeCostMap const& edge_costs,
beckerjc@349
   183
				   RetEdgeBoolMap &ret_bool_map) {
beckerjc@246
   184
beckerjc@349
   185
    typedef KruskalPairVec<typename Graph::Edge, typename EdgeCostMap::ValueType>
beckerjc@246
   186
      InputVec;
beckerjc@349
   187
    InputVec iv(G, edge_costs);
beckerjc@246
   188
beckerjc@349
   189
    return Kruskal(G, iv, ret_bool_map);
beckerjc@246
   190
  }
beckerjc@246
   191
beckerjc@349
   192
beckerjc@349
   193
  /// \brief Wrapper to Kruskal().
beckerjc@349
   194
  /// Input is from an EdgeMap, output is to a sequence.
beckerjc@246
   195
  template <typename Graph, typename EdgeCostMap, typename RetIterator>
beckerjc@246
   196
  typename EdgeCostMap::ValueType
beckerjc@349
   197
  Kruskal_EdgeCostMapIn_IteratorOut(Graph const& G,
beckerjc@349
   198
				    EdgeCostMap const& edge_costs,
beckerjc@349
   199
				    RetIterator ret_iterator) {
beckerjc@349
   200
    typedef SequenceOutput<RetIterator> OutMap;
beckerjc@349
   201
    OutMap out(ret_iterator);
beckerjc@246
   202
beckerjc@349
   203
    typedef KruskalPairVec<typename Graph::Edge, typename EdgeCostMap::ValueType>
beckerjc@246
   204
      InputVec;
beckerjc@349
   205
    InputVec iv(G, edge_costs);
beckerjc@246
   206
beckerjc@349
   207
    return Kruskal(G, iv, out);
beckerjc@246
   208
  }
beckerjc@246
   209
beckerjc@150
   210
beckerjc@150
   211
} //namespace hugo
beckerjc@150
   212
beckerjc@150
   213
#endif //HUGO_KRUSKAL_H