00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034 #ifndef OLENA_LRDE_UFMT_NAIVE_GENERIC_SALEMBIER_HH
00035 # define OLENA_LRDE_UFMT_NAIVE_GENERIC_SALEMBIER_HH
00036
00037 # include <iostream>
00038
00039 # include <values.h>
00040 # include <queue>
00041 # include <map>
00042
00043 # include <set>
00044
00045 # include <oln/level/fill.hh>
00046 # include <oln/lrde/ufmt/utils.hh>
00047
00048
00049
00050
00051 namespace ntg
00052 {
00053 template <unsigned nbits, class behavior>
00054 class int_u;
00055 }
00056
00057 namespace oln
00058 {
00059
00060 namespace lrde
00061 {
00062
00063 namespace ufmt
00064 {
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00077 template <class V, class P>
00078 struct naive_generic_hqueue_t
00079 {
00080 void add(V h, const P& p)
00081 {
00082 if (q.find (h) != q.end())
00083 std::cerr
00084 << "oln::lrde::ufmt::naive_generic_hqueue_t: Warning: "
00085 << "two points at level " << h << " inserted in hqueue"
00086 << std::endl;
00087 q.insert(std::make_pair(h, p));
00088 }
00089
00090 bool empty(V h) const
00091 {
00092 return q.count(h) == 0;
00093 }
00094
00095 P first(V h)
00096 {
00097 P tmp = q[h];
00098 q.erase (h);
00099 return tmp;
00100 }
00101
00102 unsigned size() const
00103 {
00104 return q.size;
00105 }
00106
00107 std::map<V, P> q;
00108 };
00109
00110
00116 template <class I>
00117 struct naive_generic_salembier
00118 {
00119 typedef oln_point_type(I) point;
00120 typedef oln_value_type(I) value;
00121 typedef oln_neighborhood_type(I) Nbh;
00122 typedef oln_iter_type(Nbh) niter;
00123
00124 enum {
00125 not_analyzed = MAXINT - 2,
00126 in_the_queue = MAXINT - 1
00127 };
00128
00129 const I& f;
00130 const Nbh& nbh;
00131
00132 typename mute<I, int>::ret status;
00133
00134 size_t nvalues;
00135 std::map<value, unsigned> number_nodes;
00136 std::set<value> node_at_level;
00137 naive_generic_hqueue_t<value, point> hqueue;
00138 value h_min;
00139
00140 typedef std::set< value, std::greater<value> > levels_t;
00141 typedef typename levels_t::const_iterator level_iterator;
00142
00143
00144 levels_t levels;
00145
00146 typedef std::pair<unsigned, value> pair_t;
00147 std::map<pair_t, pair_t> father;
00148
00149
00150 naive_generic_salembier(const abstract::image<I>& f,
00151 const oln_neighborhood_type(I)& nbh) :
00152 f(f.exact()),
00153 nbh(nbh),
00154
00155 status(f.size())
00156 {
00157 }
00158
00159
00160 void go()
00161 {
00162 init();
00163 flood(h_min);
00164 }
00165
00166
00167 void init()
00168 {
00169 level::fill(status, not_analyzed);
00170
00171 oln_iter_type(I) p(f);
00172 p = mlc::begin;
00173 point p_min = p;
00174 h_min = f[p];
00175 for_all(p)
00176 {
00177
00178 levels.insert(f[p]);
00179
00180 if (f[p] < h_min)
00181 {
00182 h_min = f[p];
00183 p_min = p;
00184 }
00185 }
00186 hqueue.add(h_min, p_min);
00187 }
00188
00189 level_iterator flood(value h)
00190 {
00191 level_iterator m;
00192 while (not hqueue.empty(h))
00193 {
00194 point p = hqueue.first(h);
00195 status[p] = get(number_nodes, h, 0u);
00196
00197 oln_neighb_type(Nbh) q(nbh, p);
00198 for_all(q)
00199 if (f.hold(q))
00200 {
00201 if (status[q] == not_analyzed)
00202 {
00203 hqueue.add(f[q], q);
00204 status[q] = in_the_queue;
00205 node_at_level.insert(f[q]);
00206 if (f[q] > f[p])
00207 {
00208 m = levels.find(f[q]);
00209 if (m == levels.end())
00210 abort();
00211 while (m != levels.end() and *m > h)
00212 m = flood(*m);
00213 }
00214 }
00215 }
00216 }
00217 number_nodes[h] = get(number_nodes, h, 0u) + 1;
00218
00219
00220 m = levels.find(h);
00221 if (m == levels.end())
00222 abort();
00223 ++m;
00224 while (m != levels.end() and
00225 node_at_level.find(*m) == node_at_level.end())
00226 ++m;
00227 int i = get(number_nodes, h, 0u) - 1;
00228 if (m != levels.end())
00229 {
00230 int j = get(number_nodes, *m, 0u);
00231 father[pair_t(i, h)] = pair_t(j, *m);
00232 }
00233 else
00234 father[pair_t(i, h)] = pair_t(i, h);
00235 node_at_level.erase(h);
00236 return m;
00237 }
00238
00239 unsigned n_level_roots() const
00240 {
00241 return father.size();
00242 }
00243
00246 template <typename Key, typename Data,
00247 typename Compare, typename Alloc>
00248 Data get(const std::map<Key, Data, Compare, Alloc>& map,
00249 const Key& key, const Data& default_val) const
00250 {
00251 typename std::map<Key, Data, Compare, Alloc>::const_iterator n =
00252 map.find(key);
00253 if (n != map.end())
00254 return n->second;
00255 else
00256 return default_val;
00257 }
00258
00259 };
00260
00261
00262
00263 }
00264
00265 }
00266
00267 }
00268
00269
00270 #endif // ! OLENA_LRDE_UFMT_NAIVE_GENERIC_SALEMBIER_HH