diff --git a/eo/src/do/make_algo_scalar.h b/eo/src/do/make_algo_scalar.h index 8673a80e..43cac86f 100644 --- a/eo/src/do/make_algo_scalar.h +++ b/eo/src/do/make_algo_scalar.h @@ -117,10 +117,7 @@ eoAlgo & do_make_algo_scalar(eoParameterLoader& _parser, eoState& _state, e _state.storeFunctor(select); // the number of offspring - eoValueParam& offspringRateParam = _parser.createParam(eoRateParamType("100%"), "nbOffspring", "Nb of offspring (percentage or absolute)", 'O', "Evolution Engine"); - // an eoRateParamType is simply a pair - double offRate=offspringRateParam.value().first; - bool offInterpret_as_rate = offspringRateParam.value().second; + eoValueParam& offspringRateParam = _parser.createParam(eoHowMany(1.0), "nbOffspring", "Nb of offspring (percentage or absolute)", 'O', "Evolution Engine"); // the replacement eoValueParam& replacementParam = _parser.createParam(eoParamParamType("Comma"), "replacement", "Replacement: Comma, Plus or EPTour(T), SSGAWorst, SSGADet(T), SSGAStoch(t)", 'R', "Evolution Engine"); @@ -180,8 +177,9 @@ eoAlgo & do_make_algo_scalar(eoParameterLoader& _parser, eoState& _state, e // the general breeder eoGeneralBreeder *breed = - new eoGeneralBreeder(*select, _op, offRate, offInterpret_as_rate); - _state.storeFunctor(breed); + new eoGeneralBreeder(*select, _op, offspringRateParam.value()); + _state.storeFunctor(breed); + // now the eoEasyEA eoAlgo *algo = new eoEasyEA(_ccontinue, _eval, *breed, *replace); _state.storeFunctor(algo); diff --git a/eo/src/eoGeneralBreeder.h b/eo/src/eoGeneralBreeder.h index dfb05f8f..3f1ac663 100644 --- a/eo/src/eoGeneralBreeder.h +++ b/eo/src/eoGeneralBreeder.h @@ -60,6 +60,18 @@ class eoGeneralBreeder: public eoBreed bool _interpret_as_rate = true) : select( _select ), op(_op), howMany(_rate, _interpret_as_rate) {} + /** Ctor: + * + * @param _select a selectoOne, to be used for all selections + * @param _op a general operator (will generally be an eoOpContainer) + * @param _howMany an eoHowMany explanation + */ + eoGeneralBreeder( + eoSelectOne& _select, + eoGenOp& _op, + eoHowMany _howMany ) : + select( _select ), op(_op), howMany(_howMany) {} + /** The breeder: simply calls the genOp on a selective populator! * * @param _parents the initial population @@ -75,7 +87,7 @@ class eoGeneralBreeder: public eoBreed while (_offspring.size() < target) { op(it); - ++it; + ++it; } _offspring.resize(target); // you might have generated a few more diff --git a/eo/src/eoSelectMany.h b/eo/src/eoSelectMany.h index f1b765f2..74bbeee0 100644 --- a/eo/src/eoSelectMany.h +++ b/eo/src/eoSelectMany.h @@ -50,6 +50,10 @@ class eoSelectMany : public eoSelect double _rate, bool _interpret_as_rate = true) : select(_select), howMany(_rate, _interpret_as_rate) {} + // Ctor with eoHowMany + eoSelectMany(eoSelectOne& _select, eoHowMany _howMany) + : select(_select), howMany(_howMany) {} + /** The implementation repeatidly selects an individual diff --git a/eo/src/utils/eoHowMany.h b/eo/src/utils/eoHowMany.h index fcdce596..e2c4bdf0 100644 --- a/eo/src/utils/eoHowMany.h +++ b/eo/src/utils/eoHowMany.h @@ -26,20 +26,22 @@ #ifndef eoHowMany_h #define eoHowMany_h -// to be used in selection / replacement procedures to indicate whether -// the argument (rate, a double) shoudl be treated as a rate (number=rate*popSize) -// or as an absolute integer (number=rate regardless of popsize). -// the default value shoudl ALWAYS be true (eo_as_a_rate). -// -// this construct is mandatory because in some cases you might not know the -// population size that will enter the replacement for instance - so you -// cannot simply have a pre-computed (double) rate of 1/popSize if you want 1 guy +/** + * to be used in selection / replacement procedures to indicate whether + * the argument (rate, a double) shoudl be treated as a rate (number=rate*popSize) + * or as an absolute integer (number=rate regardless of popsize). + * the default value shoudl ALWAYS be true (eo_as_a_rate). + * + * this construct is mandatory because in some cases you might not know the + * population size that will enter the replacement for instance - so you + * cannot simply have a pre-computed (double) rate of 1/popSize if you want 1 guy + */ - -class eoHowMany +class eoHowMany : public eoPersistent { public: - eoHowMany(double _rate, bool _interpret_as_rate = true): + /** Original Ctor from direct rate + bool */ + eoHowMany(double _rate = 0.0, bool _interpret_as_rate = true): rate(0), combien(0) { if (_interpret_as_rate) @@ -56,17 +58,61 @@ public: } } + /// Virtual dtor. They are needed in virtual class hierarchies. + virtual ~eoHowMany() {} + unsigned int operator()(unsigned int _size) { if (combien == 0) { - if (rate == 0.0) - return 0; - else - return (unsigned int) (rate * _size); + return (unsigned int) (rate * _size); } return combien; } + + virtual void printOn(ostream& _os) const + { + if (combien == 0) + _os << 100*rate << "% " << std::ends; + else + _os << combien << " " << std::ends; + return; + + } + + virtual void readFrom(istream& _is) + { + string value; + _is >> value; + readFrom(value); + return; + } + + void readFrom(std::string _value) + { + // check for % + bool interpret_as_rate = false; // == no % + size_t pos = _value.find('%'); + if (pos < _value.size()) // found a % + { + interpret_as_rate = true; + _value.resize(pos); // get rid of % + } + std::istrstream is(_value.c_str()); + is >> rate; + // now store + if (interpret_as_rate) + { + combien = 0; + rate /= 100.0; + } + else + combien = unsigned(rate); // and rate will not be used + + // minimal check + if ( (combien <= 0) && (rate <= 0.0) ) + throw runtime_error("Invalid parameters read in eoHowMany::readFrom"); + } private : double rate; diff --git a/eo/src/utils/eoParam.h b/eo/src/utils/eoParam.h index 45e53c3a..c4f87351 100644 --- a/eo/src/utils/eoParam.h +++ b/eo/src/utils/eoParam.h @@ -297,97 +297,6 @@ void eoValueParam >::setValue(std::string _valu std::copy(std::istream_iterator(is), std::istream_iterator(), repValue.begin()); } -/* ABANDONNED - See class eoRateType below - /////////////////////////////////////// - Specialization for "rate_or_absolute-number" - -typedef std::pair eoRateType; -template <> -std::string eoValueParam::getValue(void) const -{ - std::ostrstream os; - if (repValue.second) - os << 100*repValue.first << "% " << std::ends; - else - os << repValue.first << " " << std::ends; - return os.str(); -} - -template <> -void eoValueParam::setValue(std::string _value) -{ - double rate; - // check for % - bool interpret_as_rate = false; // == no % - size_t pos = _value.find('%'); - if (pos < _value.size()) // found a % - { - interpret_as_rate = true; - _value.resize(pos); // get rid of % - } - std::istrstream is(_value.c_str()); - is >> rate; - repValue.first = (interpret_as_rate ? rate/100 : floor(rate)); - repValue.second = interpret_as_rate; -} -*/ -/** - * A helper class for the parsing of parameters that can be either a rate - * or an absolute value (integer) - * See eoHowMany.h - */ -class eoRateParamType : public std::pair -{ -public: - eoRateParamType(std::pair _p) : std::pair(_p) {} - eoRateParamType(std::string _value) - { - readFrom(_value); - } - - ostream & printOn(ostream & _os) const - { - if (second) - _os << 100*first << "% " << std::ends; - else - _os << first << " " << std::ends; - return _os; - } - - istream & readFrom(istream & _is) - { - string value; - _is >> value; - readFrom(value); - return _is; - } - - void readFrom(std::string _value) - { - double rate; - // check for % - bool interpret_as_rate = false; // == no % - size_t pos = _value.find('%'); - if (pos < _value.size()) // found a % - { - interpret_as_rate = true; - _value.resize(pos); // get rid of % - } - std::istrstream is(_value.c_str()); - is >> rate; - first = (interpret_as_rate ? rate/100 : floor(rate)); - second = interpret_as_rate; - } - - -}; - -// at the moment, the following are defined in eoParser.cpp -ostream & operator<<(ostream & _os, const eoRateParamType & _rate); -istream & operator>>(istream & _is, eoRateParamType & _rate); - - - /*template class eoContainerParam : public eoParam { diff --git a/eo/src/utils/eoParser.cpp b/eo/src/utils/eoParser.cpp index 6c64ac91..3f19c75e 100644 --- a/eo/src/utils/eoParser.cpp +++ b/eo/src/utils/eoParser.cpp @@ -353,18 +353,6 @@ bool eoParser::userNeedsHelp(void) } ///////////////// I put these here at the moment -ostream & operator<<(ostream & _os, const eoRateParamType & _rate) -{ - _rate.printOn(_os); - return _os; -} - -istream & operator>>(istream & _is, eoRateParamType & _rate) -{ - _rate.readFrom(_is); - return _is; -} - ostream & operator<<(ostream & _os, const eoParamParamType & _rate) { _rate.printOn(_os); diff --git a/eo/test/t-eoSelect.cpp b/eo/test/t-eoSelect.cpp index c2c45875..b5409e58 100644 --- a/eo/test/t-eoSelect.cpp +++ b/eo/test/t-eoSelect.cpp @@ -93,9 +93,9 @@ void testSelectMany(eoSelect & _select, string _name) } template -void testSelectOne(eoSelectOne & _select, double _rate, string _name) +void testSelectOne(eoSelectOne & _select, eoHowMany & _hm, string _name) { - eoSelectMany percSelect(_select, _rate); + eoSelectMany percSelect(_select, _hm); testSelectMany(percSelect, _name); } @@ -108,8 +108,10 @@ int the_main(int argc, char **argv) eoValueParam parentSizeParam = parser.createParam(10, "parentSize", "Parent size",'P'); pSize = parentSizeParam.value(); // global variable - eoValueParam offsrpringRateParam = parser.createParam(1.0, "offsrpringRate", "Offsrpring rate",'O'); - double oRate = offsrpringRateParam.value(); +// eoValueParam offsrpringRateParam = parser.createParam(1.0, "offsrpringRate", "Offsrpring rate",'O'); +// double oRate = offsrpringRateParam.value(); + eoValueParam offsrpringRateParam = parser.createParam(eoHowMany(1.0), "offsrpringRate", "Offsrpring rate (% or absolute)",'O'); + eoHowMany oRate = offsrpringRateParam.value(); eoValueParam tournamentSizeParam = parser.createParam(2, "tournamentSize", "Deterministic tournament size",'T'); unsigned int tSize = tournamentSizeParam.value();