tarjan_with_attr.hh

00001 // Copyright (C) 2004, 2006  EPITA Research and Development Laboratory
00002 //
00003 // This file is part of the Olena Library.  This library is free
00004 // software; you can redistribute it and/or modify it under the terms
00005 // of the GNU General Public License version 2 as published by the
00006 // Free Software Foundation.
00007 //
00008 // This library is distributed in the hope that it will be useful,
00009 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00010 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00011 // General Public License for more details.
00012 //
00013 // You should have received a copy of the GNU General Public License
00014 // along with this library; see the file COPYING.  If not, write to
00015 // the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00016 // Boston, MA 02110-1301, USA.
00017 //
00018 // As a special exception, you may use this file as part of a free
00019 // software library without restriction.  Specifically, if other files
00020 // instantiate templates or use macros or inline functions from this
00021 // file, or you compile this file and link it with other files to
00022 // produce an executable, this file does not by itself cause the
00023 // resulting executable to be covered by the GNU General Public
00024 // License.  This exception does not however invalidate any other
00025 // reasons why the executable file might be covered by the GNU General
00026 // Public License.
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           // Make parent class able to call implementations.
00073           friend class tarjan<exact_type>;
00074           //friend class super_type;
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             // We are ready to perform stuff
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)) // new component
00172                   ++ncomps_;
00173                 else
00174                   {
00175                     comp_value_.pop_back();
00176                     parent_.pop_back();
00177                     data_.pop_back();
00178                   }
00179               }
00180 
00181             // Resolving phase
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_;// comp number from a point
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       } // !abstract
00224 
00225     } // end of namespace tarjan
00226 
00227   } // end of namespace topo
00228 
00229 } // end of namespace oln
00230 
00231 #endif // ! OLENA_TOPO_TARJAN_TARJAN_WITH_ATTR_HH

Generated on Tue Feb 20 20:20:58 2007 for Olena by  doxygen 1.5.1