00001 #ifndef mbl_select_n_from_m_h_ 00002 #define mbl_select_n_from_m_h_ 00003 //: 00004 // \file 00005 // \brief A class which returns an N element subset of the integers [0..M-1] 00006 // \author Tim Cootes 00007 00008 #include <mbl/mbl_random_n_from_m.h> 00009 00010 //: A class which returns an N element subset of the integers [0..M-1] 00011 // By default it systematically steps through all combinations of choosing 00012 // N integers from a set of 0..M-1 00013 // Thus when N=1 repeated calls to subset() return 1,2,3,4,...,M 00014 // When N=2 calls to subset give (0,1), (0,1) .. (0,M-1), (1,2), (1,3),..(M-2,M-1) 00015 // However, the use_random() function allows random examples to be 00016 // returned (using the mbl_random_n_from_m class). 00017 // When N > M, nothing is returned, ie, next() immediately returns false. 00018 // When N == 0, the empty set is returned. 00019 // The complement() function returns the integers not in the subset. 00020 // 00021 // The following code snippet runs process_data() on all possible subsets: 00022 // \code 00023 // mbl_select_n_from_m selector(3,5); 00024 // if (selector.reset()) 00025 // do 00026 // { 00027 // process_data(selector.subset()); 00028 // } while selector.next(); 00029 // \endcode 00030 class mbl_select_n_from_m 00031 { 00032 private: 00033 unsigned int n_; 00034 unsigned int m_; 00035 bool is_done_; 00036 bool use_random_; 00037 00038 vcl_vector<int> index_; 00039 vcl_vector<int> not_index_; 00040 00041 mbl_random_n_from_m random_; 00042 00043 public: 00044 00045 //: Dflt ctor 00046 mbl_select_n_from_m(); 00047 00048 //: Construct to select n from m 00049 mbl_select_n_from_m(unsigned int n, unsigned int m); 00050 00051 //: Construct to select n from m 00052 void set_n_m(unsigned int new_n, unsigned int new_m); 00053 00054 //: If true then use random subsets 00055 void use_random(bool flag); 00056 00057 //: Reseed randomiser 00058 void reseed(long); 00059 00060 //: Reset to first example. Returns true if there is a valid first example. 00061 bool reset(); 00062 00063 //: Generate next set. Return true until all combinations exhausted. 00064 bool next(); 00065 00066 //: Returns true when all sets enumerated 00067 // Never returns true when random subsets being chosen 00068 bool is_done() const { return is_done_; } 00069 00070 //: Current subset of n from m. 00071 // is_done() should not be true when this function is being called 00072 const vcl_vector<int>& subset() const; 00073 00074 //: Sub-set not chosen (m-n) from m. 00075 // is_done() should not be true when this function is being called 00076 const vcl_vector<int>& complement(); 00077 }; 00078 00079 #endif // mbl_select_n_from_m_h_