contrib/mul/mbl/mbl_select_n_from_m.h
Go to the documentation of this file.
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_