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_TOPO_TARJAN_TARJAN_WITH_ATTR_HH
00029 # define OLENA_TOPO_TARJAN_TARJAN_WITH_ATTR_HH
00030
00031 # include <oln/topo/tarjan/tarjan.hh>
00032 # include <oln/morpho/attributes.hh>
00033 # include <ntg/basics.hh>
00034 # include <oln/level/fill.hh>
00035 # include <oln/utils/histogram.hh>
00036
00037 # include <vector>
00038 # include <map>
00039
00040 namespace oln {
00041
00042 namespace topo {
00044 namespace tarjan {
00045
00047 namespace abstract {
00048
00055 template<class Exact>
00056 struct tarjan_with_attr: public tarjan<mlc_exact_vt_type(tarjan_with_attr<Exact>, Exact) >
00057 {
00058 typedef oln_tarjan_input_type(Exact) input_type;
00059 typedef oln_point_type(input_type) point_type;
00060 typedef oln_value_type(input_type) data_type;
00061
00062 typedef oln_concrete_type(input_type) image_type;
00063 typedef oln_tarjan_output_type(Exact) image_out_type;
00064 typedef oln_tarjan_attr_type(Exact) attr_type;
00065 typedef attr_env_type(attr_type) env_type;
00066 typedef oln_value_type(image_out_type) comp_type;
00067
00068 typedef mlc_exact_vt_type(tarjan_with_attr<Exact>,
00069 Exact) exact_type;
00070 typedef tarjan<exact_type> super_type;
00071
00072
00073 friend class super_type;
00074
00079 const attr_type &get_attr(const comp_type &i) const
00080 {
00081 return data_[find_root(i)];
00082 }
00083
00084 protected:
00085
00096 tarjan_with_attr(const image_type &ima,
00097 const env_type &env):
00098 capacity_chunk((ima.npoints() < 100) ? ima.npoints() : (ima.npoints() / 100)),
00099 capacity(capacity_chunk),
00100 input_(ima),
00101 parent_(),
00102 to_comp_(ima.size()),
00103 comp_value_(),
00104 env_(env)
00105 {
00106 parent_.reserve(capacity);
00107 comp_value_.reserve(capacity);
00108 data_.reserve(capacity);
00109 }
00110
00118 bool is_proc_impl(const point_type &p) const
00119 {
00120 return to_comp_[p] != ntg_sup_val(comp_type);
00121 };
00122
00131 comp_type
00132 find_root(const comp_type& x) const
00133 {
00134 if (parent_[x] != x)
00135 return parent_[x] = find_root(parent_[x]);
00136 return x;
00137 }
00138
00147 template<class N>
00148 image_out_type
00149 get_compute_impl(const oln::abstract::neighborhood<N> &Ng)
00150 {
00151 std::vector<point_type> I(get_processing_order());
00152
00153 level::fill(to_comp_, ntg_sup_val(comp_type));
00154 to_comp_.border_adapt_assign(Ng.delta(), ntg_sup_val(comp_type));
00155 ncomps_ = 0;
00156 parent_.push_back(0);
00157 comp_value_.push_back(0);
00158 data_.push_back(attr_type());
00159
00160
00161 for (unsigned int p = 0; p < I.size(); ++p)
00162 {
00163 point_type p_p = I[p];
00164 mark_set(p_p);
00165
00166 oln_neighb_type(N) Q_prime(Ng, p_p);
00167 for_all (Q_prime)
00168 if (is_proc(Q_prime))
00169 uni(Q_prime.cur(), p_p);
00170 if (to_comp_[p_p] == (ncomps_ + 1))
00171 ++ncomps_;
00172 else
00173 {
00174 comp_value_.pop_back();
00175 parent_.pop_back();
00176 data_.pop_back();
00177 }
00178 }
00179
00180
00181 std::map<comp_type, comp_type> cmps;
00182 ncomps_ = 0;
00183 for (int p = I.size() - 1; p >= 0; --p)
00184 {
00185 point_type p_p = I[p];
00186 if (cmps.find(find_root(to_comp_[p_p])) == cmps.end())
00187 {
00188 cmps[comp_value_[find_root(to_comp_[p_p])]] = ncomps_;
00189 comp_value_[find_root(to_comp_[p_p])] = ncomps_++;
00190 }
00191 }
00192
00193 image_out_type output(input_.size());
00194 for (int p = I.size() - 1; p >= 0; --p)
00195 {
00196 point_type p_p = I[p];
00197 output[p_p] = comp_value_[find_root(to_comp_[p_p])];
00198 }
00199 return output;
00200 }
00201
00207 comp_type ncomps_impl() const
00208 {
00209 return ncomps_;
00210 }
00211
00212 unsigned capacity_chunk;
00213 unsigned capacity;
00214 const image_type &input_;
00215 mutable std::vector<comp_type> parent_;
00216 typename oln::mute<input_type, comp_type>::ret to_comp_;
00217 comp_type ncomps_;
00218 std::vector<oln_value_type(image_out_type)> comp_value_;
00219 std::vector<attr_type> data_;
00220 env_type env_;
00221 };
00222 }
00223
00224 }
00225
00226 }
00227
00228 }
00229
00230 #endif // ! OLENA_TOPO_TARJAN_TARJAN_WITH_ATTR_HH