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 tarjan<exact_type>;
00074
00075
00080 const attr_type &get_attr(const comp_type &i) const
00081 {
00082 return data_[find_root(i)];
00083 }
00084
00085 protected:
00086
00097 tarjan_with_attr(const image_type &ima,
00098 const env_type &env):
00099 capacity_chunk((ima.npoints() < 100) ? ima.npoints() : (ima.npoints() / 100)),
00100 capacity(capacity_chunk),
00101 input_(ima),
00102 parent_(),
00103 to_comp_(ima.size()),
00104 comp_value_(),
00105 env_(env)
00106 {
00107 parent_.reserve(capacity);
00108 comp_value_.reserve(capacity);
00109 data_.reserve(capacity);
00110 }
00111
00119 bool is_proc_impl(const point_type &p) const
00120 {
00121 return to_comp_[p] != ntg_sup_val(comp_type);
00122 };
00123
00132 comp_type
00133 find_root(const comp_type& x) const
00134 {
00135 if (parent_[x] != x)
00136 return parent_[x] = find_root(parent_[x]);
00137 return x;
00138 }
00139
00148 template<class N>
00149 image_out_type
00150 get_compute_impl(const oln::abstract::neighborhood<N> &Ng)
00151 {
00152 std::vector<point_type> I(this->get_processing_order());
00153
00154 level::fill(to_comp_, ntg_sup_val(comp_type));
00155 to_comp_.border_adapt_assign(Ng.delta(), ntg_sup_val(comp_type));
00156 ncomps_ = 0;
00157 parent_.push_back(0);
00158 comp_value_.push_back(0);
00159 data_.push_back(attr_type());
00160
00161
00162 for (unsigned int p = 0; p < I.size(); ++p)
00163 {
00164 point_type p_p = I[p];
00165 mark_set(p_p);
00166
00167 oln_neighb_type(N) Q_prime(Ng, p_p);
00168 for_all (Q_prime)
00169 if (is_proc(Q_prime))
00170 this->uni(Q_prime.cur(), p_p);
00171 if (to_comp_[p_p] == (ncomps_ + 1))
00172 ++ncomps_;
00173 else
00174 {
00175 comp_value_.pop_back();
00176 parent_.pop_back();
00177 data_.pop_back();
00178 }
00179 }
00180
00181
00182 std::map<comp_type, comp_type> cmps;
00183 ncomps_ = 0;
00184 for (int p = I.size() - 1; p >= 0; --p)
00185 {
00186 point_type p_p = I[p];
00187 if (cmps.find(find_root(to_comp_[p_p])) == cmps.end())
00188 {
00189 cmps[comp_value_[find_root(to_comp_[p_p])]] = ncomps_;
00190 comp_value_[find_root(to_comp_[p_p])] = ncomps_++;
00191 }
00192 }
00193
00194 image_out_type output(input_.size());
00195 for (int p = I.size() - 1; p >= 0; --p)
00196 {
00197 point_type p_p = I[p];
00198 output[p_p] = comp_value_[find_root(to_comp_[p_p])];
00199 }
00200 return output;
00201 }
00202
00208 comp_type ncomps_impl() const
00209 {
00210 return ncomps_;
00211 }
00212
00213 unsigned capacity_chunk;
00214 unsigned capacity;
00215 const image_type &input_;
00216 mutable std::vector<comp_type> parent_;
00217 typename oln::mute<input_type, comp_type>::ret to_comp_;
00218 comp_type ncomps_;
00219 std::vector<oln_value_type(image_out_type)> comp_value_;
00220 std::vector<attr_type> data_;
00221 env_type env_;
00222 };
00223 }
00224
00225 }
00226
00227 }
00228
00229 }
00230
00231 #endif // ! OLENA_TOPO_TARJAN_TARJAN_WITH_ATTR_HH