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 #ifndef OLENA_LRDE_UFMT_GENERIC_SALEMBIER_HH
00029 # define OLENA_LRDE_UFMT_GENERIC_SALEMBIER_HH
00030
00031
00032 # include <climits>
00033 # include <cfloat>
00034 # include <queue>
00035 # include <set>
00036 # include <map>
00037
00038 # include <oln/level/fill.hh>
00039 # include <oln/lrde/ufmt/utils.hh>
00040
00041
00042
00043 namespace oln
00044 {
00045
00046 namespace lrde
00047 {
00048
00049 namespace ufmt
00050 {
00051
00052 template <class V, class P>
00053 struct generic_hqueue_t
00054 {
00055 typedef std::map<V, std::queue<P> > multi_queue_t;
00056
00057 void add(const V& h, const P& p)
00058 {
00059 q[h].push(p);
00060 }
00061
00062
00063 void init(const V& h)
00064 {
00065 q.insert(std::make_pair(h, std::queue<P>()));
00066 }
00067
00068 bool empty(const V& h) const
00069 {
00070 typename multi_queue_t::const_iterator i = q.find(h);
00071 if (i == q.end())
00072 return true;
00073 else
00074 return i->second.empty();
00075 }
00076
00077 P first(const V& h)
00078 {
00079 assertion (not empty(h));
00080
00081 P tmp = q[h].front();
00082 q[h].pop();
00083 return tmp;
00084 }
00085
00086 unsigned size() const
00087 {
00088 unsigned s = 0;
00089 for (typename multi_queue_t::const_iterator i = q.begin();
00090 i != q.end(); ++i)
00091 s += i->second.size();
00092 return s;
00093 }
00094
00095 void print (std::ostream& os)
00096 {
00097 os << "hqueue = {";
00098 for (typename multi_queue_t::const_iterator i = q.begin();
00099 i != q.end(); ++i)
00100 if (not i->second.empty())
00101 {
00102 os << " " << i->first << " -> { ";
00103 std::queue<P> queue_copy = i->second;
00104 while (not queue_copy.empty())
00105 {
00106 os << queue_copy.front () << " ";
00107 queue_copy.pop();
00108 }
00109 os << "}";
00110 }
00111 os << " }" << std::endl;
00112 }
00113
00114 multi_queue_t q;
00115 };
00116
00117
00118 template < class I,
00119 class Greater = std::greater< oln_value_type(I) > >
00120 struct generic_salembier
00121 {
00122 typedef oln_point_type(I) point;
00123 typedef oln_value_type(I) value;
00124 typedef oln_neighborhood_type(I) Nbh;
00125 typedef oln_iter_type(Nbh) niter;
00126
00127 enum {
00128 not_analyzed = INT_MAX - 2,
00129 in_the_queue = INT_MAX - 1
00130 };
00131
00132 const I& f;
00133 const Nbh& nbh;
00134
00135 typename mute<I, int>::ret status;
00136
00137 typedef std::map<value, unsigned> number_nodes_t;
00138 number_nodes_t number_nodes;
00139 typedef std::set<value> node_at_level_t;
00140 node_at_level_t node_at_level;
00141 generic_hqueue_t<value, point> hqueue;
00142 value h_min;
00143
00144 typedef std::set< value, Greater > levels_t;
00145 typedef typename levels_t::const_iterator level_iterator;
00146
00147
00148 levels_t levels;
00149
00150
00151 Greater level_greater;
00152
00153 typedef std::pair<unsigned, value> pair_t;
00154 std::map<pair_t, pair_t> father;
00155
00156 # ifdef OLN_DEBUG
00157 unsigned npoints;
00158 # endif // OLN_DEBUG
00159
00160 generic_salembier(const abstract::image<I>& f,
00161 const oln_neighborhood_type(I)& nbh) :
00162 f(f.exact()),
00163 nbh(nbh),
00164
00165
00166 status(f.size())
00167 # ifdef OLN_DEBUG
00168 , npoints(f.npoints())
00169 # endif
00170 {
00171 }
00172
00173
00174 void go()
00175 {
00176 init();
00177 flood(h_min);
00178 }
00179
00180
00181 void init()
00182 {
00183 level::fill(status, not_analyzed);
00184
00185 oln_iter_type(I) p(f);
00186 p = mlc::begin;
00187 point p_min = p;
00188 h_min = f[p];
00189 for_all(p)
00190 {
00191
00192 levels.insert(f[p]);
00193
00194 if (level_greater(h_min, f[p]))
00195 {
00196 h_min = f[p];
00197 p_min = p;
00198 }
00199 }
00200 hqueue.add(h_min, p_min);
00201 }
00202
00203
00204 # ifdef OLN_DEBUG
00205 void update_status (std::ostream& ostr)
00206 {
00207 static unsigned nupdates = 0;
00208 static const unsigned step = 1;
00209 static unsigned next_step = step;
00210 ++nupdates;
00211 unsigned percent = nupdates * 100 / npoints;
00212 if (percent >= next_step)
00213 {
00214
00215 std::cerr << percent << "% points processed" << std::endl;
00216
00217 while (percent >= next_step)
00218 next_step += step;
00219 }
00220 }
00221 # endif // OLN_DEBUG
00222
00223 level_iterator flood(const value& h)
00224 {
00225 level_iterator m;
00226 while (not hqueue.empty(h))
00227 {
00228 point p = hqueue.first(h);
00229
00230 status[p] = get(number_nodes, h, 0u);
00231 # ifdef OLN_DEBUG
00232 update_status(std::cerr);
00233 # endif // OLN_DEBUG
00234
00235 oln_neighb_type(Nbh) q(nbh, p);
00236 for_all(q)
00237 {
00238 if (f.hold(q))
00239 {
00240 if (status[q] == not_analyzed)
00241 {
00242 hqueue.add(f[q], q);
00243 status[q] = in_the_queue;
00244 node_at_level.insert(f[q]);
00245 if (f[q] > f[p])
00246 {
00247 m = levels.find(f[q]);
00248 if (m == levels.end())
00249 abort();
00250 while (m != levels.end() and *m > h)
00251 m = flood(*m);
00252 }
00253 }
00254 }
00255 }
00256 }
00257 number_nodes[h] = get(number_nodes, h, 0u) + 1;
00258
00259
00260 m = levels.find(h);
00261 if (m == levels.end())
00262 abort();
00263 ++m;
00264 while (m != levels.end() and
00265 node_at_level.find(*m) == node_at_level.end())
00266 ++m;
00267 int i = get(number_nodes, h, 0u) - 1;
00268
00269 if (m != levels.end())
00270 {
00271 int j = get(number_nodes, *m, 0u);
00272 father[pair_t(i, h)] = pair_t(j, *m);
00273 }
00274 else
00275 {
00276 father[pair_t(i, h)] = pair_t(i, h);
00277 }
00278 node_at_level.erase(h);
00279 return m;
00280 }
00281
00282
00283 unsigned n_level_roots() const
00284 {
00285 return father.size();
00286 }
00287
00290 template <typename Key, typename Data,
00291 typename Compare, typename Alloc>
00292 Data get(const std::map<Key, Data, Compare, Alloc>& map,
00293 const Key& key, const Data& default_val) const
00294 {
00295 typename std::map<Key, Data, Compare, Alloc>::const_iterator n =
00296 map.find(key);
00297 if (n != map.end())
00298 return n->second;
00299 else
00300 return default_val;
00301 }
00302
00303 };
00304
00305
00306 }
00307
00308 }
00309
00310 }
00311
00312
00313 #endif // ! OLENA_LRDE_UFMT_GENERIC_SALEMBIER_HH