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_HPC_MAXTREE_HH
00029 # define OLENA_LRDE_UFMT_HPC_MAXTREE_HH
00030
00031 # include <oln/level/fill.hh>
00032 # include <oln/lrde/ufmt/utils.hh>
00033 # include <oln/lrde/ufmt/ap_maxtree.hh>
00034 # include <oln/lrde/ufmt/attributes.hh>
00035
00036
00037
00038 namespace oln
00039 {
00040
00041 namespace lrde
00042 {
00043
00044 namespace ufmt
00045 {
00046
00047
00048
00049 template <class I>
00050 struct hpc_maxtree : public ap_maxtree<I>
00051 {
00052 typedef ap_maxtree<I> super;
00053 using super::f;
00054 using super::nbh;
00055 using super::par;
00056 oln_lrde_ufmt_import_ap_maxtree_typedefs;
00057
00058
00059 std::vector<point> S;
00060 std::vector<size_t> H;
00061 std::vector<dpoint> dp_pre, dp_post;
00062 unsigned nb;
00063 unsigned nnodes;
00064 typename mute<I, unsigned>::ret label;
00065
00066
00067
00068
00069 hpc_maxtree(const abstract::image<I>& f,
00070 const oln_neighborhood_type(I)& nbh)
00071 :
00072 super(f, nbh),
00073 label(f.size())
00074 {
00075 }
00076
00077 template <class A>
00078 void go()
00079 {
00080 init();
00081 compute_parent();
00082 extract_maxtree<A>();
00083 }
00084
00085 void init()
00086 {
00087 S = histogram_reverse_sort_p(f, H);
00088 nb = split<I>(nbh, dp_pre, dp_post);
00089 nnodes = 0;
00090 }
00091
00092 void compute_parent()
00093 {
00094 int i = 0;
00095 for (int h = uint_nvalues(f) - 1; h >= 0; --h)
00096 {
00097 int i_first = i;
00098 int i_last = i_first + H[h];
00099
00100
00101
00102 for (i = i_first; i < i_last; ++i)
00103 {
00104 point p = S[i];
00105 make_set(p);
00106
00107 for (unsigned j = 0; j < nb; ++j)
00108 {
00109 point n = p + dp_pre[j];
00110 if (f.hold(n) and f[n] >= h)
00111 do_union(n, p, h);
00112 }
00113
00114 for (unsigned j = 0; j < nb; ++j)
00115 {
00116 point n = p + dp_post[j];
00117 if (f.hold(n) and f[n] > h)
00118 do_union(n, p, h);
00119 }
00120 }
00121
00122
00123
00124
00125
00126
00127 for (int k = i_last - 1; k >= i_first; --k)
00128 {
00129 point p = S[k];
00130 if (is_root(p))
00131 ++nnodes;
00132 else
00133 par[p] = par[par[p]];
00134 }
00135 }
00136 }
00137
00138
00139 template <class A>
00140 std::vector< node_<A> >
00141 extract_maxtree()
00142 {
00143 std::vector< node_<A> > node(nnodes);
00144
00145
00146 unsigned cur_l = nnodes - 1;
00147 for (int i = S.size() - 1; i != 0; --i)
00148 {
00149 point p = S[i];
00150
00151
00152
00153
00154 if (is_level_root(p))
00155 {
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176 label[p] = cur_l;
00177 node[cur_l].par = label[par[p]];
00178 --cur_l;
00179 }
00180 else
00181
00182 label[p] = label[par[p]];
00183 }
00184 return node;
00185 }
00186
00187
00188 template <class A>
00189 void compute_attributes(std::vector< node_<A> >& node)
00190
00191 {
00192 for (int i = S.size() - 1; i != 0; --i)
00193 {
00194 point p = S[i];
00195 if (is_level_root(p))
00196 node[label[p]].init(f, p);
00197 else
00198 node[label[p]].insert(f, p);
00199 }
00200 for (int l = 0; l < nnodes; ++l)
00201 if (node[l].par != l)
00202 node[node[l].par].embrace(node[l]);
00203 }
00204
00205 void make_set(const point& x)
00206 {
00207 par[x] = x;
00208 }
00209
00210 bool is_root(const point& x) const
00211 {
00212 return par[x] == x;
00213 }
00214
00215 bool is_level_root(const point& x) const
00216 {
00217 return is_root(x) or f[par[x]] < f[x];
00218 }
00219
00220 point find_level_root(const point& x)
00221 {
00222 if (is_level_root(x))
00223 return x;
00224 else
00225 return par[x] = find_level_root(par[x]);
00226 }
00227
00228 point find_root(point x, value h)
00229 {
00230 while (not is_root(x))
00231 if (f[x] > h)
00232 x = par[x];
00233 else
00234 x = find_level_root(par[x]);
00235 return x;
00236 }
00237
00238 void do_union(const point& n, const point& p, value h)
00239 {
00240 point r = find_root(n, h);
00241 if (r != p)
00242 par[r] = p;
00243 }
00244
00245
00246 };
00247
00248
00249
00250 }
00251
00252 }
00253
00254 }
00255
00256
00257 #endif // ! OLENA_LRDE_UFMT_HPC_MAXTREE_HH