From 40a519f6d7c8b977456e44ff7d975a4b4e03d84a Mon Sep 17 00:00:00 2001 From: nojhan Date: Thu, 7 Mar 2013 10:29:40 +0100 Subject: [PATCH] Add Binomial operators to EDO --- edo/src/edo | 3 ++ edo/src/edoBinomial.h | 68 ++++++++++++++++++++++++ edo/src/edoEstimatorBinomial.h | 76 ++++++++++++++++++++++++++ edo/src/edoSamplerBinomial.h | 66 +++++++++++++++++++++++ edo/test/CMakeLists.txt | 1 + edo/test/t-binomial.cpp | 97 ++++++++++++++++++++++++++++++++++ 6 files changed, 311 insertions(+) create mode 100644 edo/src/edoBinomial.h create mode 100644 edo/src/edoEstimatorBinomial.h create mode 100644 edo/src/edoSamplerBinomial.h create mode 100644 edo/test/t-binomial.cpp diff --git a/edo/src/edo b/edo/src/edo index 0da9ed9d4..33c18b1c7 100644 --- a/edo/src/edo +++ b/edo/src/edo @@ -38,6 +38,7 @@ Authors: #include "edoNormalMono.h" #include "edoNormalMulti.h" #include "edoNormalAdaptive.h" +#include "edoBinomial.h" #include "edoEstimator.h" #include "edoEstimatorUniform.h" @@ -45,6 +46,7 @@ Authors: #include "edoEstimatorNormalMulti.h" #include "edoEstimatorAdaptive.h" #include "edoEstimatorNormalAdaptive.h" +#include "edoEstimatorBinomial.h" #include "edoModifier.h" #include "edoModifierDispersion.h" @@ -58,6 +60,7 @@ Authors: #include "edoSamplerNormalMono.h" #include "edoSamplerNormalMulti.h" #include "edoSamplerNormalAdaptive.h" +#include "edoSamplerBinomial.h" #include "edoVectorBounds.h" diff --git a/edo/src/edoBinomial.h b/edo/src/edoBinomial.h new file mode 100644 index 000000000..ab8b9b8f3 --- /dev/null +++ b/edo/src/edoBinomial.h @@ -0,0 +1,68 @@ +/* +The Evolving Distribution Objects framework (EDO) is a template-based, +ANSI-C++ evolutionary computation library which helps you to write your +own estimation of distribution algorithms. + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +Copyright (C) 2013 Thales group +*/ +/* +Authors: + Johann Dréo +*/ + +#ifndef _edoBinomial_h +#define _edoBinomial_h + +#include + +#include + +/** @defgroup Binomial Binomial + * A binomial distribution that model marginal probabilities across variables. + * + * @ingroup Distributions + */ + +/** A binomial distribution that model marginal probabilities across variables. + * + * @ingroup Distributions + * @ingroup Binomial + */ +template > +class edoBinomial : public edoDistrib, public T +{ +public: + typedef double AtomType; // FIXME use container atom type + + /** This constructor takes an initial vector of probabilities. + * Use it if you have prior knowledge. + */ + edoBinomial( T initial_probas ) : T(initial_probas) {} + + /** This constructor makes no assumption about initial probabilities. + * Every probabilities are set to 0.0. + */ + edoBinomial( size_t dim, double p = 0.0 ) : T(dim,p) {} + + /** Constructor without any assumption. + * Will create a vector of size 1 with a probability of 0.0. + */ + edoBinomial() : T(1,0.0) {} +}; + +#endif // !_edoBinomial_h + diff --git a/edo/src/edoEstimatorBinomial.h b/edo/src/edoEstimatorBinomial.h new file mode 100644 index 000000000..8e0650514 --- /dev/null +++ b/edo/src/edoEstimatorBinomial.h @@ -0,0 +1,76 @@ +/* +The Evolving Distribution Objects framework (EDO) is a template-based, +ANSI-C++ evolutionary computation library which helps you to write your +own estimation of distribution algorithms. + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +Copyright (C) 2013 Thales group +*/ +/* +Authors: + Johann Dréo +*/ + +#ifndef _edoEstimatorBinomial_h +#define _edoEstimatorBinomial_h + +#include "edoEstimator.h" +#include "edoBinomial.h" + +/** An estimator for edoBinomial + * + * @ingroup Estimators + * @ingroup Binomial + */ +template< class EOT, class D = edoBinomial > +class edoEstimatorBinomial : public edoEstimator< edoBinomial< EOT > > +{ + public: + /** This generic implementation makes no assumption about the underlying + * atom type of the EOT. It can be any type that may be interpreted as + * true or false. + * + * For instance, you can use a vector, and any variable greater + * than one will increase the associated probability. + * + * FIXME: Partial template specializations without the conditional branching may be more efficient. + */ + edoBinomial operator()( eoPop& pop ) + { + unsigned int popsize = pop.size(); + assert(popsize > 0); + + unsigned int dimsize = pop[0].size(); + assert(dimsize > 0); + + edoBinomial probas(dimsize, 0.0); + + for (unsigned int i = 0; i < popsize; ++i) { + for (unsigned int d = 0; d < dimsize; ++d) { + // if this variable is true (whatever that means, x=1, x=true, etc.) + // if( pop[i][d] ) { + // probas[d] += 1/popsize; // we hope the compiler optimization pre-computes 1/p + // } + probas[d] += static_cast(pop[i][d]) / popsize; + } + } + + return probas; + } +}; + +#endif // !_edoEstimatorBinomial_h + diff --git a/edo/src/edoSamplerBinomial.h b/edo/src/edoSamplerBinomial.h new file mode 100644 index 000000000..1425b7a74 --- /dev/null +++ b/edo/src/edoSamplerBinomial.h @@ -0,0 +1,66 @@ +/* +The Evolving Distribution Objects framework (EDO) is a template-based, +ANSI-C++ evolutionary computation library which helps you to write your +own estimation of distribution algorithms. + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +Copyright (C) 2013 Thales group +*/ +/* +Authors: + Johann Dréo +*/ + +#ifndef _edoSamplerBinomial_h +#define _edoSamplerBinomial_h + +#include + +#include "edoSampler.h" +#include "edoBinomial.h" + +/** A sampler for an edoBinomial distribution. + * + * @ingroup Samplers + * @ingroup Binomial + */ +template< class EOT, class D = edoBinomial > +class edoSamplerBinomial : public edoSampler +{ +public: + edoSamplerBinomial() : edoSampler() {} + + EOT sample( edoBinomial& distrib ) + { + unsigned int size = distrib.size(); + assert(size > 0); + + // The point we want to draw + // x = {x1, x2, ..., xn} + EOT solution; + + // Sampling all dimensions + for( unsigned int i = 0; i < size; ++i ) { + // Toss a coin, biased by the proba of being 1. + solution.push_back( rng.flip(distrib[i]) ); + } + + return solution; + } +}; + +#endif // !_edoSamplerBinomial_h + diff --git a/edo/test/CMakeLists.txt b/edo/test/CMakeLists.txt index 5ab7eb21b..577c0bd31 100644 --- a/edo/test/CMakeLists.txt +++ b/edo/test/CMakeLists.txt @@ -40,6 +40,7 @@ set(SOURCES t-continue # t-dispatcher-round t-repairer-modulo + t-binomial ) foreach(current ${SOURCES}) diff --git a/edo/test/t-binomial.cpp b/edo/test/t-binomial.cpp new file mode 100644 index 000000000..db586f75c --- /dev/null +++ b/edo/test/t-binomial.cpp @@ -0,0 +1,97 @@ +/* +The Evolving Distribution Objects framework (EDO) is a template-based, +ANSI-C++ evolutionary computation library which helps you to write your +own estimation of distribution algorithms. + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +Copyright (C) 2013 Thales group +*/ +/* +Authors: + Johann Dréo +*/ + +#include +#include +#include +#include + +#include +#include +#include // for Bools + +template +void print( T v, std::string sep=" " ) +{ + for( typename T::iterator it=v.begin(); it!=v.end(); ++it ) { + std::cout << *it << sep; + } + std::cout << std::endl; +} + +int main(int ac, char** av) +{ + typedef eoBit Bools; + + eoParser parser(ac, av); + + std::string section("Algorithm parameters"); + unsigned int popsize = parser.createParam((unsigned int)100000, "popSize", "Population Size", 'P', section).value(); // P + unsigned int dim = parser.createParam((unsigned int)20, "dim", "Dimension size", 'd', section).value(); // d + double proba = parser.createParam((double)0.5, "proba", "Probability to estimate", 'b', section).value(); // b + + + // This generate a random boolean when called... + eoBooleanGenerator flip( proba ); + + // ... by this initializator... + eoInitFixedLength init( dim, flip ); + + // ... when building this pop. + std::cout << "Init a pop of eoBit of size " << popsize << " at random with p(x=1)=" << proba << std::endl; + eoPop pop( popsize, init ); + // print( pop, "\n" ); + + // EDO triplet + edoBinomial distrib(dim,0.0); + edoEstimatorBinomial estimate; + edoSamplerBinomial sample; + + std::cout << "Estimate a distribution from the init pop" << std::endl; + distrib = estimate(pop); + print( distrib ); + // std::cout << std::endl; + + std::cout << "Sample a new pop from the init distrib" << std::endl; + pop.clear(); + for( unsigned int i=0; i