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_RPC_MAXTREE_HH
00029 # define OLENA_LRDE_UFMT_RPC_MAXTREE_HH
00030
00031 # include <oln/lrde/ufmt/utils.hh>
00032 # include <oln/lrde/ufmt/ap_maxtree.hh>
00033
00034 # include <vector>
00035
00036
00037 namespace oln
00038 {
00039
00040 namespace lrde
00041 {
00042
00043 namespace ufmt
00044 {
00045
00046
00047
00048
00049 template <class I>
00050 struct rpc_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 unsigned nnodes;
00059
00060
00061 std::vector<dpoint> dp;
00062 unsigned nb;
00063
00064
00065
00066
00067 rpc_maxtree(const abstract::image<I>& f,
00068 const oln_neighborhood_type(I)& nbh)
00069 :
00070 super(f, nbh)
00071 {
00072 }
00073
00074 void go()
00075 {
00076 init();
00077 compute_parent();
00078 extract_maxtree();
00079 }
00080
00081 void init()
00082 {
00083 nb = pre<I>(nbh, dp);
00084 nnodes = 0;
00085 }
00086
00087 void compute_parent()
00088 {
00089 oln_iter_type(I) p(f);
00090 for_all(p)
00091 {
00092 make_set(p);
00093 point n = p + dp[0];
00094 if (f.hold(n))
00095 insert(n, p);
00096 for (unsigned i = 1; i < nb; ++i)
00097 {
00098 n = p + dp[i];
00099 if (f.hold(n))
00100 if (f[p] >= f[n])
00101 update(p, n);
00102 else
00103 update(n, p);
00104 }
00105 }
00106 }
00107
00108 void extract_maxtree()
00109 {
00110
00111 }
00112
00113 void insert(const point& n, const point& p)
00114 {
00115 point r = anc(n, f[p]);
00116
00117 if (f[p] != f[r])
00118 ++nnodes;
00119
00120 if (f[r] <= f[p])
00121 par[p] = r;
00122 else
00123 {
00124 if (par[r] != r)
00125 par[p] = par[r];
00126 par[r] = p;
00127 }
00128 }
00129
00130
00131 void update(point x, point y)
00132 {
00133 assert(x != y);
00134 assert(f[x] >= f[y]);
00135
00136 point a = anc(x, f[y]);
00137 point b = find_level_root(y);
00138
00139 assert(f[x] >= f[a] and f[a] >= f[y] and f[y] == f[b]);
00140
00141 if (a == b)
00142 return;
00143
00144 if (f[b] != f[a])
00145 ++nnodes;
00146
00147 point memo = par[b];
00148
00149 if (f[b] == f[a])
00150 par[b] = a;
00151 else
00152 {
00153 if (par[a] != a)
00154 par[b] = par[a];
00155 par[a] = b;
00156 }
00157
00158 assert(f[memo] <= f[a]);
00159 update(a, memo);
00160
00161
00162
00163
00164
00165 }
00166
00167
00168
00169 void update__primary_version(point x, point y)
00170 {
00171 assert(x != y);
00172
00173 if (f[x] < f[y])
00174 swap(x, y);
00175 assert(f[x] >= f[y]);
00176
00177 point xx = anc(x, f[y]);
00178 assert(f[xx] >= f[y]);
00179
00180 point yy = anc(y, f[y]);
00181 assert(yy == find_level_root(y));
00182 assert(f[yy] == f[y]);
00183
00184 assert(f[yy] <= f[xx]);
00185
00186
00187
00188 if (xx == yy)
00189 return;
00190
00191 point memo = par[yy];
00192
00193 if (f[xx] == f[yy])
00194 {
00195 par[yy] = xx;
00196 update(xx, memo);
00197 }
00198 else
00199 {
00200 assert(f[yy] < f[xx]);
00201 if (par[xx] == xx)
00202 {
00203 par[xx] = yy;
00204
00205 }
00206 else
00207 {
00208
00209 point bot = par[xx];
00210 par[xx] = yy;
00211 par[yy] = bot;
00212 update(xx, memo);
00213 }
00214 }
00215
00216
00217
00218
00219
00220 }
00221
00222
00223
00224 void insert__unfold_version(const point& n, const point& p)
00225 {
00226 if (f[n] <= f[p])
00227 {
00228
00229 par[p] = n;
00230
00231 }
00232 else
00233
00234 {
00235 point r = anc(n, f[p]);
00236 assert(f[r] >= f[p]);
00237 if (f[r] == f[p])
00238 {
00239 par[p] = r;
00240 }
00241 else
00242 {
00243 if (par[r] == r)
00244 par[r] = p;
00245 else
00246
00247
00248 {
00249 point bot = par[r];
00250 par[r] = p;
00251 par[p] = bot;
00252 }
00253 }
00254 }
00255 }
00256
00257
00258 };
00259
00260
00261
00262 }
00263
00264 }
00265
00266 }
00267
00268
00269 #endif // ! OLENA_LRDE_UFMT_RPC_MAXTREE_HH