Go to the documentation of this file.00001
00002
00003
00004
00005
00006 #include "mbl_select_n_from_m.h"
00007 #include <vcl_cassert.h>
00008 #include <vcl_iostream.h>
00009
00010 mbl_select_n_from_m::mbl_select_n_from_m()
00011 : n_(0), m_(0), is_done_(false), use_random_(false)
00012 {
00013 random_.reseed(123746);
00014 }
00015
00016 mbl_select_n_from_m::mbl_select_n_from_m(unsigned int new_n, unsigned int new_m)
00017 : n_(new_n), m_(new_m), is_done_(false), use_random_(false)
00018 {
00019 set_n_m(new_n,new_m);
00020 random_.reseed(123746);
00021 }
00022
00023
00024 void mbl_select_n_from_m::reseed(long s)
00025 {
00026 random_.reseed(s);
00027 }
00028
00029
00030
00031 void mbl_select_n_from_m::set_n_m(unsigned int new_n, unsigned int new_m)
00032 {
00033 if (new_n>new_m)
00034 {
00035 vcl_cerr<<"mbl_select_n_from_m::set_n_m(): Warning: N>M: nothing selected\n"
00036 <<"N="<<new_n<<" M="<<new_m<<vcl_endl;
00037 is_done_ = true;
00038 }
00039
00040 n_=new_n;
00041 m_=new_m;
00042 index_.resize(n_);
00043 reset();
00044 }
00045
00046 void mbl_select_n_from_m::use_random(bool flag)
00047 {
00048 use_random_=flag;
00049
00050 if (use_random_)
00051 random_.choose_n_from_m(index_,not_index_,n_,m_);
00052 else
00053 reset();
00054 }
00055
00056 bool mbl_select_n_from_m::reset()
00057 {
00058 is_done_ = (n_>m_);
00059
00060 if (is_done_)
00061 return false;
00062
00063 if (use_random_)
00064 {
00065 random_.choose_n_from_m(index_,not_index_,n_,m_);
00066 return true;
00067 }
00068
00069 for (unsigned int i=0;i<n_;++i)
00070 index_[i]=i;
00071
00072 return true;
00073 }
00074
00075 bool mbl_select_n_from_m::next()
00076 {
00077 if (is_done_) return false;
00078
00079 if (use_random_)
00080 {
00081 random_.choose_n_from_m(index_,not_index_,n_,m_);
00082 return true;
00083 }
00084
00085
00086 if (n_==m_ || n_ == 0) { is_done_=true; return false; }
00087
00088 int* index_data = &index_[0];
00089 index_data[n_-1]++;
00090
00091
00092 unsigned int low_trip_digit = n_;
00093 int start_index=0;
00094 for (unsigned int j=n_-1;j>0;--j)
00095 {
00096
00097 if (index_data[j]>int(m_-n_+j))
00098 {
00099 index_data[j-1]++;
00100 low_trip_digit=j;
00101 start_index=index_data[j-1]+1;
00102
00103 }
00104 }
00105
00106 if (index_data[0]>int(m_-n_))
00107 {
00108 reset();
00109 is_done_=true;
00110 return false;
00111 }
00112 else
00113 if (low_trip_digit<n_)
00114 {
00115
00116 for (unsigned int i=low_trip_digit;i<n_;i++)
00117 {
00118 index_data[i]=start_index;
00119 start_index++;
00120 }
00121 }
00122
00123 return true;
00124 }
00125
00126 const vcl_vector<int>& mbl_select_n_from_m::subset() const
00127 {
00128 assert (!is_done_);
00129 return index_;
00130 }
00131
00132 const vcl_vector<int>& mbl_select_n_from_m::complement()
00133 {
00134 if (use_random_)
00135 return not_index_;
00136
00137
00138 assert (!is_done_);
00139 if (not_index_.size()!=m_-n_) not_index_.resize(m_-n_);
00140
00141
00142
00143 unsigned int j=0;
00144 unsigned int k=0;
00145 for (unsigned int i=0;i<n_;i++)
00146 {
00147 unsigned int ind_i = index_[i];
00148 while (k<ind_i)
00149 {
00150 not_index_[j]=k;
00151 j++;
00152 k++;
00153 }
00154 ++k;
00155 }
00156
00157
00158 while (k<m_)
00159 {
00160 not_index_[j]=k;
00161 j++;
00162 k++;
00163 }
00164
00165 return not_index_;
00166 }