contrib/mul/mbl/mbl_random_n_from_m.cxx
Go to the documentation of this file.
00001 //:
00002 // \file
00003 // \brief Randomly select n from m integers without replacement
00004 // \author Tim Cootes
00005 
00006 #include "mbl_random_n_from_m.h"
00007 #include <vcl_iostream.h>
00008 #include <vcl_cstdlib.h>
00009 
00010 mbl_random_n_from_m::mbl_random_n_from_m()
00011 {
00012 }
00013 
00014 void mbl_random_n_from_m::reseed(long new_seed)
00015 {
00016   mz_random_.reseed(new_seed);
00017 }
00018 
00019 //: Select n integers from range [0,m-1], without replacement
00020 void mbl_random_n_from_m::choose_n_from_m(vcl_vector<unsigned>& choice,
00021                                           unsigned int n, unsigned int m)
00022 {
00023   if (n>m)
00024   {
00025     vcl_cerr<<"mbl_random_n_from_m::choose_n_from_m() : Can't choose "<<n
00026             <<" different integers from "<<m<<vcl_endl;
00027     vcl_abort();
00028   }
00029 
00030   if (choice.size()!=n) choice.resize(n);
00031 
00032   if (used_.size()<m) used_.resize(m);
00033 
00034   for (unsigned int i=0;i<m;i++) used_[i] = false;
00035 
00036   for (unsigned int i=0;i<n;i++)
00037   {
00038     // Select a random integer in a reducing range
00039     int j = mz_random_.lrand32(m-i-1);
00040     // Find the j'th un-used integer
00041     int k2=-1;
00042     for (int k1=0; k1<=j; ++k1)
00043     {
00044       // Move k2 to next unused
00045       ++k2;
00046       while (used_[k2])
00047         ++k2;
00048     }
00049 
00050     choice[i] = k2;
00051     used_[k2] = true;
00052   }
00053 }
00054 
00055 //: Select n integers from range [0,m-1], without replacement
00056 void mbl_random_n_from_m::choose_n_from_m(vcl_vector<unsigned>& chosen,
00057                                           vcl_vector<unsigned>& not_chosen,
00058                                           unsigned int n, unsigned int m)
00059 {
00060   choose_n_from_m(chosen,n,m);
00061 
00062   // The used array contains details of choice.
00063   unsigned int n1 = m-n; // n is guaranteed <= m
00064   if (not_chosen.size()!=n1) not_chosen.resize(n1);
00065 
00066   for (unsigned int i=0,j=0;i<m;i++)
00067     if (!used_[i])
00068       not_chosen[j++]=i;
00069 }
00070 
00071 //: Select n integers from range [0,m-1], without replacement
00072 void mbl_random_n_from_m::choose_n_from_m(vcl_vector<int>& choice,
00073                                           unsigned int n, unsigned int m)
00074 {
00075   if (n>m)
00076   {
00077     vcl_cerr<<"mbl_random_n_from_m::choose_n_from_m() : Can't choose "<<n
00078             <<" different integers from "<<m<<vcl_endl;
00079     vcl_abort();
00080   }
00081 
00082   if (choice.size()!=n) choice.resize(n);
00083 
00084   if (used_.size()<m) used_.resize(m);
00085 
00086   for (unsigned int i=0;i<m;i++) used_[i] = false;
00087 
00088   for (unsigned int i=0;i<n;i++)
00089   {
00090     // Select a random integer in a reducing range
00091     int j = mz_random_.lrand32(m-i-1);
00092     // Find the j'th un-used integer
00093     int k2=-1;
00094     for (int k1=0; k1<=j; ++k1)
00095     {
00096       // Move k2 to next unused
00097       ++k2;
00098       while (used_[k2])
00099         ++k2;
00100     }
00101 
00102     choice[i] = k2;
00103     used_[k2] = true;
00104   }
00105 }
00106 
00107 //: Select n integers from range [0,m-1], without replacement
00108 void mbl_random_n_from_m::choose_n_from_m(vcl_vector<int>& chosen,
00109                                           vcl_vector<int>& not_chosen,
00110                                           unsigned int n, unsigned int m)
00111 {
00112   choose_n_from_m(chosen,n,m);
00113 
00114   // The used array contains details of choice.
00115   unsigned int n1 = m-n; // n is guaranteed <= m
00116   if (not_chosen.size()!=n1) not_chosen.resize(n1);
00117 
00118   for (unsigned int i=0,j=0;i<m;i++)
00119     if (!used_[i])
00120       not_chosen[j++]=i;
00121 }
00122