00001 #include "SimpleSelect.h"
00002 #include <cmath>
00003 #include <iostream>
00004 using namespace std;
00005 SimpleSelect::SimpleSelect(GeneralRNG &LocalRandom, tProbabilityFunction myPF):
00006 Random(LocalRandom),
00007 ProbabilityFunction(myPF)
00008 {
00009
00010 }
00011
00012 SimpleSelect::~SimpleSelect()
00013 {}
00014
00015 void SimpleSelect::DoInit()
00016 {
00017 const tprobabilityv probabilities = ProbabilityFunction();
00018 const int popsize = probabilities.size();
00019 int currentindex = 0;
00020 double expsum = 0;
00021 int assignsum = 0;
00022
00023 std::vector<double> fraction(popsize,0);
00024 indices.assign(popsize,0);
00025
00026 cout << "Probs: ";
00027 for (int i= 0; i < popsize; ++i)
00028 cout << probabilities(i) << " ";
00029 cout << endl;
00030
00031 remain = popsize;
00032
00033
00034 for (int i = 0; i < popsize; ++i)
00035 {
00036 double expected = probabilities(i) * popsize;
00037
00038 expsum += expected;
00039 int assign = int(floor(expected));
00040 assignsum += assign;
00041 fraction.at(i) = expected -assign;
00042 while (assign > 0)
00043 {
00044 --assign;
00045 indices.at(currentindex) = i;
00046 ++currentindex;
00047 }
00048
00049 }
00050
00051
00052
00053 int fractionindex = 0;
00054 while (currentindex < popsize)
00055 {
00056 if ( Random.GetNumber() <= fraction.at(fractionindex) )
00057 {
00058
00059 indices.at(currentindex)=fractionindex;
00060 ++currentindex;
00061 fraction.at(fractionindex) -= 1.0;
00062 }
00063 ++fractionindex;
00064 if (fractionindex >= popsize)
00065 fractionindex -= popsize;
00066 }
00067
00068 }
00069
00070 size_t SimpleSelect::DoGetOne()
00071 {
00072 int pick = Random.GetNumber(remain);
00073 int result = indices.at(pick);
00074 --remain;
00075 indices.at(pick) = indices.at(remain);
00076 return(result);
00077 }