Go to the documentation of this file.00001 #include "brip_label_equivalence.h"
00002
00003
00004
00005 #include <vcl_utility.h>
00006 #include <vcl_iostream.h>
00007
00008
00009 void brip_label_equivalence::add_label_pair(unsigned la, unsigned lb)
00010 {
00011 vcl_pair<vcl_set<unsigned>::iterator, bool> result;
00012 result = forward_pairs_[la].insert(lb);
00013 if (result.second)
00014 if (la>max_label_)
00015 max_label_ = la;
00016 result = reverse_pairs_[lb].insert(la);
00017 if (result.second)
00018 if (la>max_label_)
00019 max_label_ = lb;
00020 }
00021
00022 vcl_set<unsigned> brip_label_equivalence::labels() const
00023 {
00024 vcl_set<unsigned> labs;
00025 vcl_map<unsigned, vcl_set<unsigned> >::const_iterator mit =
00026 forward_pairs_.begin();
00027 for (; mit != forward_pairs_.end(); ++mit) {
00028 labs.insert((*mit).first);
00029 }
00030 mit = reverse_pairs_.begin();
00031 for (; mit != reverse_pairs_.end(); ++mit) {
00032 labs.insert((*mit).first);
00033 }
00034 return labs;
00035 }
00036
00037 bool brip_label_equivalence::
00038 merge_equivalence(vcl_map<unsigned int, vcl_set<unsigned int> >& tab,
00039 unsigned int cur_label,
00040 unsigned int label)
00041 {
00042 vcl_map<unsigned , vcl_set<unsigned> >::iterator hashi;
00043
00044 hashi = tab.find(label);
00045 if (hashi == tab.end()) {
00046 return false;
00047 }
00048
00049 vcl_set<unsigned>& labels = hashi->second;
00050
00051
00052 unsigned len = labels.size();
00053 if (!len)
00054 return false;
00055
00056 hashi = equivalence_sets_.find(cur_label);
00057 if ( hashi == equivalence_sets_.end())
00058 {
00059
00060
00061 equivalence_sets_[cur_label] = vcl_set<unsigned>();
00062 }
00063
00064 for (vcl_set<unsigned>::iterator lit = labels.begin();
00065 lit != labels.end(); ++lit)
00066 equivalence_sets_[cur_label].insert(*lit);
00067 return true;
00068 }
00069
00070
00071
00072
00073
00074 bool brip_label_equivalence::get_next_label(vcl_set<unsigned> const& labels,
00075 unsigned int& label)
00076 {
00077
00078
00079 unsigned int tmp = label+1;
00080 if (!labels.size())
00081 if (tmp<max_label_)
00082 {
00083 label = tmp;
00084 return true;
00085 }
00086
00087
00088
00089 for (unsigned int i = tmp; i<=max_label_; i++)
00090 {
00091 vcl_set<unsigned>::const_iterator sit=labels.find(i);
00092 if (sit==labels.end()){
00093 label = i;
00094 return true;
00095 }
00096 }
00097 return false;
00098 }
00099
00100
00101 void brip_label_equivalence::transitive_closure()
00102 {
00103 vcl_set<unsigned> labs = this->labels();
00104 if (labs.size()<=1)
00105 return;
00106 unsigned cur_label = *(labs.begin());
00107
00108
00109 vcl_map<unsigned , vcl_set<unsigned > >::iterator mei;
00110 while (true)
00111 {
00112 bool merging = true;
00113 unsigned i = cur_label;
00114 vcl_set<unsigned> cur_set;
00115 int len = 0;
00116 int old_len;
00117 while (merging)
00118 {
00119 old_len = len;
00120 merging = false;
00121
00122 bool find_forward =
00123 this->merge_equivalence(forward_pairs_, cur_label, i);
00124 vcl_map<unsigned, vcl_set<unsigned> >::iterator sit;
00125 if (find_forward)
00126 {
00127 sit = forward_pairs_.find(i);
00128 if (sit!=forward_pairs_.end())
00129 forward_pairs_.erase(sit);
00130 }
00131 #if 0
00132 if (find_forward)
00133 vcl_cout << "merged forward pairs on label " << i << '\n' << vcl_flush;
00134 #endif
00135
00136 bool find_reverse =
00137 this->merge_equivalence(reverse_pairs_, cur_label, i);
00138 if (find_reverse)
00139 {
00140 sit = reverse_pairs_.find(i);
00141 if (sit!=reverse_pairs_.end())
00142 reverse_pairs_.erase(sit);
00143 }
00144 #if 0
00145 if (find_reverse)
00146 vcl_cout << "merged reverse pairs on label " << i << '\n' << vcl_flush;
00147 #endif
00148
00149
00150
00151 mei = equivalence_sets_.find(cur_label);
00152 if (mei == equivalence_sets_.end()) continue;
00153
00154
00155
00156
00157
00158
00159 cur_set =equivalence_sets_[cur_label];
00160 len = cur_set.size();
00161 if (!len) continue;
00162
00163
00164
00165 if (len > old_len) i = cur_label;
00166
00167 if (len > 200)
00168 {
00169 merging = false;
00170 continue;
00171 }
00172
00173
00174 for (vcl_set<unsigned>::iterator cit = cur_set.begin();
00175 cit != cur_set.end() && !merging; ++cit)
00176 if (*cit>i)
00177 {
00178 i = *cit;
00179 merging = true;
00180 }
00181
00182
00183 }
00184
00185
00186 if (!get_next_label(cur_set, cur_label)) return;
00187 #if 0
00188 vcl_cout << "Getting next label to seed equivalence "
00189 << cur_label << '\n' << vcl_flush;
00190 #endif
00191 }
00192 }