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_UNION_HH
00029 # define OLENA_TOPO_TARJAN_UNION_HH
00030
00031 #include <oln/basics2d.hh>
00032
00033 #include <oln/level/fill.hh>
00034
00035 namespace oln {
00036
00037 namespace topo {
00039 namespace tarjan {
00040
00041 struct empty_class
00042 {};
00043
00048 template< class I, class aux_data_type>
00049 struct tarjan_set
00050 {
00051 typedef oln_point_type(I) point_type;
00052 typedef oln_value_type(I) data_type;
00053 typedef oln_concrete_type(I) image_type;
00054
00055 typedef typename mute<I, point_type>::ret ima_parent_type;
00056 typedef typename mute<I, aux_data_type>::ret ima_aux_data_type;
00057
00058 public:
00059 tarjan_set(const image_type & ima) : input(ima)
00060 {
00061 parent = typename mute<I, point_type>::ret(ima.size());
00062 level::fill(parent, inactive());
00063
00064 parent.border_adapt_assign(1, inactive());
00065 }
00066
00067
00068
00069
00070
00071 static const point_type&
00072 active()
00073 {
00074 static struct foo_def{
00075 point_type elt;
00076 foo_def()
00077 {
00078 const unsigned dim = point_type::dim;
00079 for (unsigned i = 0; i < dim; ++i )
00080 elt.nth(i) = -1;
00081 }
00082 } tmp;
00083
00084 return tmp.elt;
00085 }
00086
00087 static const point_type&
00088 inactive()
00089 {
00090 static struct foo_def {
00091 point_type elt;
00092 foo_def() {
00093 const unsigned dim = point_type::dim;
00094 for (unsigned i = 0; i < dim; ++i )
00095 elt.nth(i) = -2;
00096 }
00097 } tmp;
00098
00099 return tmp.elt;
00100 }
00101
00102 void
00103 make_set(const point_type& x)
00104 {
00105 precondition(parent[x] == inactive());
00106 parent[x] = active();
00107 }
00108
00109 void
00110 link(const point_type& x, const point_type& y)
00111 {
00112 parent[x] = y;
00113 }
00114
00115 unsigned int
00116 attribute(const point_type& x)
00117 {
00118 precondition(parent[x] == active());
00119 precondition(aux_data[x] != 0);
00120 return aux_data[x];
00121 }
00122
00123 bool
00124 equiv(const point_type& x, const point_type& y)
00125 {
00126 return ( (input[x] == input[y]));
00127 }
00128
00129
00130 void
00131 uni(const point_type& n, const point_type& p)
00132 {
00133 point_type r = find_root(n);
00134 if (r != p && equiv(r,p))
00135 link(r,p);
00136 }
00137
00138 const point_type&
00139 find_root(const point_type& x)
00140 {
00141
00142 if ((parent[x] != active()) && (parent[x] != inactive()))
00143 {
00144 parent[x] = find_root(parent[x]);
00145 return parent[x];
00146 }
00147 else
00148 return x;
00149 }
00150
00151 const point_type&
00152 sure_find_root(const point_type& x)
00153 {
00154 if ((parent[x] != active()) && (parent[x] != inactive()))
00155 return parent[x];
00156 else
00157 return x;
00158 }
00159
00160 const bool
00161 is_root(const point_type& x)
00162 {
00163 if ((parent[x] != active()) && (parent[x] != inactive()))
00164 return false;
00165 return true;
00166 }
00167
00168 const image_type &input;
00169 ima_parent_type parent;
00170 ima_aux_data_type aux_data;
00171 };
00172
00173 }
00174
00175 }
00176
00177 }
00178
00179 #endif // ! OLENA_TOPO_TARJAN_UNION_HH