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_BASIC_SALEMBIER_HH
00029 # define OLENA_LRDE_UFMT_BASIC_SALEMBIER_HH
00030
00031 # include <values.h>
00032 # include <queue>
00033 # include <map>
00034
00035 # include <oln/level/fill.hh>
00036 # include <oln/lrde/ufmt/utils.hh>
00037
00038
00039 namespace oln
00040 {
00041
00042 namespace lrde
00043 {
00044
00045 namespace ufmt
00046 {
00047
00048
00049
00050
00051
00052
00055 template <class P>
00056 struct hqueue_t
00057 {
00058 unsigned nvalues;
00059
00060 hqueue_t()
00061 {
00062 nvalues = 0;
00063 }
00064
00065 void set_nvalues(unsigned nvalues)
00066 {
00067 assert(nvalues > 0);
00068 this->nvalues = nvalues;
00069 q = new std::queue<P>[nvalues];
00070 }
00071
00072 void add(unsigned h, const P& p)
00073 {
00074 assert(h < nvalues);
00075 q[h].push(p);
00076 }
00077
00078 bool empty(unsigned h) const
00079 {
00080 assert(h < nvalues);
00081 return q[h].empty();
00082 }
00083
00084 P first(unsigned h)
00085 {
00086 assert(h < nvalues);
00087 P tmp = q[h].front();
00088 q[h].pop();
00089 return tmp;
00090 }
00091
00092 unsigned size() const
00093 {
00094 unsigned s = 0;
00095 for (unsigned i = 0; i < nvalues; ++i)
00096 s += q[i].size();
00097 return s;
00098 }
00099
00100 void print (std::ostream& os)
00101 {
00102 os << "hqueue = {";
00103 for (unsigned h = 0; h < nvalues; ++h)
00104 if (not empty(h))
00105 {
00106 os << " " << h << " -> { ";
00107 std::queue<P> queue_copy = q[h];
00108 while (not queue_copy.empty())
00109 {
00110 os << queue_copy.front () << " ";
00111 queue_copy.pop();
00112 }
00113 os << "}";
00114 }
00115 os << " }" << std::endl;
00116 }
00117
00118 std::queue<P>* q;
00119 };
00120
00121
00163 template <class I>
00164 struct basic_salembier
00165 {
00166 typedef oln_point_type(I) point;
00167 typedef oln_value_type(I) value;
00168 typedef oln_neighborhood_type(I) Nbh;
00169 typedef oln_iter_type(Nbh) niter;
00170
00171 enum {
00172 not_analyzed = MAXINT - 2,
00173 in_the_queue = MAXINT - 1
00174 };
00175
00176 const I& f;
00177 const Nbh& nbh;
00178
00179 typename mute<I, int>::ret status;
00180
00181 size_t nvalues;
00182 unsigned* number_nodes;
00183 bool* node_at_level;
00184 hqueue_t<point> hqueue;
00185 int h_min;
00186
00187 typedef std::pair<unsigned,unsigned> pair_t;
00188 std::map<pair_t, pair_t> father;
00189
00190
00191 basic_salembier(const abstract::image<I>& f,
00192 const oln_neighborhood_type(I)& nbh) :
00193 f(f.exact()),
00194 nbh(nbh),
00195
00196 status(f.size())
00197 {
00198 }
00199
00200
00201 void go()
00202 {
00203 init();
00204 flood(h_min);
00205 }
00206
00207
00208 void init()
00209 {
00210 nvalues = uint_nvalues(f);
00211 number_nodes = new unsigned[nvalues];
00212 node_at_level = new bool[nvalues];
00213 for (unsigned i = 0; i < nvalues; ++i)
00214 {
00215 number_nodes[i] = 0;
00216 node_at_level[i] = false;
00217 }
00218
00219 level::fill(status, not_analyzed);
00220
00221 hqueue.set_nvalues(nvalues);
00222 h_min = nvalues;
00223 {
00224 point p_min;
00225 oln_iter_type(I) p(f);
00226 for_all(p)
00227 if (f[p] < h_min)
00228 {
00229 h_min = f[p];
00230 p_min = p;
00231 }
00232 hqueue.add(h_min, p_min);
00233 }
00234 }
00235
00236
00237 int flood(int h)
00238 {
00239 int m;
00240 while (not hqueue.empty(h))
00241 {
00242 point p = hqueue.first(h);
00243
00244 status[p] = number_nodes[h];
00245
00246 oln_neighb_type(Nbh) q(nbh, p);
00247 for_all(q)
00248 if (f.hold(q))
00249 {
00250 if (status[q] == not_analyzed)
00251 {
00252 hqueue.add(f[q], q);
00253 status[q] = in_the_queue;
00254 node_at_level[f[q]] = true;
00255 if (f[q] > f[p])
00256 {
00257 m = f[q];
00258 while (m > h)
00259 m = flood(m);
00260 }
00261 }
00262 }
00263 }
00264 number_nodes[h] = number_nodes[h] + 1;
00265
00266 m = h - 1;
00267 while (m >= 0 and node_at_level[m] == false)
00268 m = m - 1;
00269 int i = number_nodes[h] - 1;
00270 if (m >= 0)
00271 {
00272 int j = number_nodes[m];
00273 father[pair_t(i, h)] = pair_t(j, m);
00274 }
00275 else
00276 {
00277 father[pair_t(i, h)] = pair_t(i, h);
00278 }
00279 node_at_level[h] = false;
00280 return m;
00281 }
00282
00283
00284 unsigned n_level_roots() const
00285 {
00286 return father.size();
00287 }
00288
00289 };
00290
00291
00292 }
00293
00294 }
00295
00296 }
00297
00298
00299 #endif // ! OLENA_LRDE_UFMT_BASIC_SALEMBIER_HH