diff --git a/eo/src/eo b/eo/src/eo index 21bd61b6..43e84fc7 100644 --- a/eo/src/eo +++ b/eo/src/eo @@ -59,10 +59,17 @@ #include #include +// Evaluation functions #include #include #include +// Terminators +#include +#include +#include + +// Selection and reproduction stuff #include #include #include @@ -71,6 +78,9 @@ #include +// Algorithms +#include + //----------------------------------------------------------------------------- // to be continued ... //----------------------------------------------------------------------------- diff --git a/eo/src/eoEvalFunc.h b/eo/src/eoEvalFunc.h index 6d5fc4cb..266303d6 100644 --- a/eo/src/eoEvalFunc.h +++ b/eo/src/eoEvalFunc.h @@ -1,8 +1,8 @@ -// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*- - -//----------------------------------------------------------------------------- -// eoEvalFunc.h -// (c) GeNeura Team, 1998 +// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*- + +//----------------------------------------------------------------------------- +// eoEvalFunc.h +// (c) GeNeura Team, 1998 /* This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -20,32 +20,31 @@ Contact: todos@geneura.ugr.es, http://geneura.ugr.es */ -//----------------------------------------------------------------------------- - -#ifndef eoEvalFunc_H -#define eoEvalFunc_H - -/** Evaluate: takes one EO and sets its "fitness" property - * returning this fitness also. That is why EOT is passed by - * non-const reference: it must be altered within evaluate.\\ - - The requirements on the types with which this class is to be - instantiated with are null, or else, they depend on the particular - class it's going to be applied to; EO does not impose any requirement - on it. If you subclass this abstract class, and use it to evaluate an - EO, the requirements on this EO will depend on the evaluator. - */ -template< class EOT > -struct eoEvalFunc { - -#ifdef _MSC_VER - typedef EOT::Fitness EOFitT; -#else - typedef typename EOT::Fitness EOFitT; -#endif - - /// Effectively applies the evaluation function to an EO or urEO - virtual void operator() ( EOT & _eo ) const = 0; -}; - +//----------------------------------------------------------------------------- + +#ifndef eoEvalFunc_H +#define eoEvalFunc_H + +/** Evaluate: takes one EO and sets its "fitness" property + * returning this fitness also. That is why EOT is passed by + * non-const reference: it must be altered within evaluate.\\ + + The requirements on the types with which this class is to be + instantiated with are null, or else, they depend on the particular + class it's going to be applied to; EO does not impose any requirement + on it. If you subclass this abstract class, and use it to evaluate an + EO, the requirements on this EO will depend on the evaluator. + */ +template struct eoEvalFunc { + +#ifdef _MSC_VER + typedef EOT::Fitness EOFitT; +#else + typedef typename EOT::Fitness EOFitT; +#endif + + /// Effectively applies the evaluation function to an EO or urEO + virtual void operator() ( EOT & _eo ) const = 0; +}; + #endif diff --git a/eo/src/eoFitTerm.h b/eo/src/eoFitTerm.h new file mode 100644 index 00000000..d8a7087e --- /dev/null +++ b/eo/src/eoFitTerm.h @@ -0,0 +1,64 @@ +// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*- + +//----------------------------------------------------------------------------- +// eoGenTerm.h +// (c) GeNeura Team, 1999 +/* + 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 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Contact: todos@geneura.ugr.es, http://geneura.ugr.es + */ +//----------------------------------------------------------------------------- + +#ifndef _EOFITTERM_H +#define _EOFITTERM_H + +#include + + +/** Fitness termination: terminates after a the difference between the +fitness of the best individual and a maximum fitness to achieve is less +than certain number called epsilon., i.e., |maximum-fitness| +class eoFitTerm: public eoTerm { +public: + + /// Ctors/dtors + eoFitTerm( const float _maximum, const float _epsilon ) + : eoTerm (), maximum( _maximum ), epsilon(_epsilon){}; + + /// Copy ctor + eoFitTerm( const eoFitTerm& _t ) + : eoTerm ( _t ), maximum( _t.maximum ), + epsilon(_t.epsilon){}; + + /// + virtual ~eoFitTerm() {}; + + /** Returns false when a certain number of generations is + * reached */ + virtual bool operator() ( const eoPop& _vEO ) { + float bestFitness=_vEO[0].fitness(); + float dif=bestFitness-maximum; + dif=(dif<0)?-dif:dif; + return (dif>epsilon ) || (bestFitness > maximum); + } + +private: + float maximum, epsilon; +}; + +#endif diff --git a/eo/src/eoGenTerm.h b/eo/src/eoGenTerm.h new file mode 100644 index 00000000..7da104c0 --- /dev/null +++ b/eo/src/eoGenTerm.h @@ -0,0 +1,82 @@ +// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*- + +//----------------------------------------------------------------------------- +// eoGenTerm.h +// (c) GeNeura Team, 1999 +/* + 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 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Contact: todos@geneura.ugr.es, http://geneura.ugr.es + */ +//----------------------------------------------------------------------------- + +#ifndef _EOGENTERM_H +#define _EOGENTERM_H + +#include + +/** Generational termination: terminates after a number of generations +*/ +template< class EOT> +class eoGenTerm: public eoTerm { +public: + + /// Ctors/dtors + eoGenTerm( unsigned _totalGens) + : eoTerm (), repTotalGenerations( _totalGens ), + thisGeneration(0){}; + + /// Copy Ctor + eoGenTerm( const eoGenTerm& _t) + : eoTerm ( _t ), repTotalGenerations( _t.repTotalGenerations ), + thisGeneration(0){}; + + /// Assignment Operator + const eoGenTerm& operator = ( const eoGenTerm& _t) { + if ( &_t != this ) { + repTotalGenerations = _t.repTotalGenerations; + thisGeneration = 0; + } + return *this; + } + + /// Dtor + virtual ~eoGenTerm() {}; + + /** Returns false when a certain number of generations is + * reached */ + virtual bool operator() ( const eoPop& _vEO ) { + thisGeneration++; + // cout << " [" << thisGeneration << "] "; + return (thisGeneration < repTotalGenerations) ; // for the postincrement + } + + /** Sets the number of generations to reach + and sets the current generation to 0 (the begin)*/ + virtual void totalGenerations( unsigned _tg ) { + repTotalGenerations = _tg; + // thisGeneration = 0; + }; + + /** Returns the number of generations to reach*/ + virtual unsigned totalGenerations( ) { + return repTotalGenerations; + }; + +private: + unsigned repTotalGenerations, thisGeneration; +}; + +#endif diff --git a/eo/src/eoGeneration.h b/eo/src/eoGeneration.h index e8beb9c3..3adbb10e 100644 --- a/eo/src/eoGeneration.h +++ b/eo/src/eoGeneration.h @@ -28,6 +28,7 @@ //----------------------------------------------------------------------------- #include // eoPop +#include #include // eoSelect, eoTranform, eoMerge //----------------------------------------------------------------------------- @@ -43,8 +44,14 @@ template class eoGeneration: public eoAlgo eoMerge& _replace, eoEvalFunc& _evaluator): select(_select), transform(_transform), - replace(_replace), evaluator( _evaluator) {} - + replace(_replace), evaluator( _evaluator) {}; + + /// Copy Constructor. + eoGeneration(eoGeneration& _gen): + select(_gen.select), transform(_gen.transform), + replace(_gen.replace), evaluator( _gen.evaluator ) {}; + + /// Apply one generation of evolution to the population. virtual void operator()(eoPop& pop) { eoPop breeders; diff --git a/eo/src/eoTerm.h b/eo/src/eoTerm.h new file mode 100644 index 00000000..0910a19b --- /dev/null +++ b/eo/src/eoTerm.h @@ -0,0 +1,50 @@ +// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*- + +//----------------------------------------------------------------------------- +// eoTerm.h +// (c) GeNeura Team, 1999 +/* + 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 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Contact: todos@geneura.ugr.es, http://geneura.ugr.es + */ +//----------------------------------------------------------------------------- + +#ifndef _EOTERM_H +#define _EOTERM_H + +#include + +/** Termination condition for the genetic algorithm + * Takes the population as input, returns true for continue, + * false for termination + */ +template< class EOT> +class eoTerm { +public: + + /// Ctors/dtors + virtual ~eoTerm() {}; + + /** Returns false if the training has to stop, true if it + continues \\ + It is non-const since it might change the internal state + of the object, for instance, updating a counter + */ + virtual bool operator() ( const eoPop< EOT >& _pop ) = 0 ; + +}; + +#endif diff --git a/eo/test/Makefile.am b/eo/test/Makefile.am index b0aca05d..5ac001fe 100644 --- a/eo/test/Makefile.am +++ b/eo/test/Makefile.am @@ -13,7 +13,7 @@ LDADDS = $(top_builddir)/src/libeo.a ############################################################################### -noinst_PROGRAMS = t-eobreeder t-eoinclusion t-eoinsertion t-eo t-eofitness t-eoproblem t-eobin t-eolottery t-eo2dVector t-eogeneration +noinst_PROGRAMS = t-eobreeder t-eoinclusion t-eoinsertion t-eo t-eofitness t-eoproblem t-eobin t-eolottery t-eo2dVector t-eogeneration t-eoEasyEA ############################################################################### @@ -24,6 +24,13 @@ t_eogeneration_LDADD = $(LDADDS) ############################################################################### +t_eoEasyEA_SOURCES = t-eoEasyEA.cpp +t_eoEasyEA_DEPENDENCIES = $(DEPS) +t_eoEasyEA_LDFLAGS = -lm +t_eoEasyEA_LDADD = $(LDADDS) + +############################################################################### + t_eobreeder_SOURCES = t-eobreeder.cpp t_eobreeder_DEPENDENCIES = $(DEPS) t_eobreeder_LDFLAGS = -lm diff --git a/eo/test/Makefile.in b/eo/test/Makefile.in index 61e66d15..35a27402 100644 --- a/eo/test/Makefile.in +++ b/eo/test/Makefile.in @@ -87,7 +87,7 @@ LDADDS = $(top_builddir)/src/libeo.a ############################################################################### -noinst_PROGRAMS = t-eogeneration t-eobreeder t-eoinclusion t-eoinsertion t-eo t-eofitness t-eoproblem t-eobin t-eolottery +noinst_PROGRAMS = t-eobreeder t-eoinclusion t-eoinsertion t-eo t-eofitness t-eoproblem t-eobin t-eolottery t-eo2dVector t-eogeneration t-eoEasyEA ############################################################################### @@ -98,6 +98,13 @@ t_eogeneration_LDADD = $(LDADDS) ############################################################################### +t_eoEasyEA_SOURCES = t-eoEasyEA.cpp +t_eoEasyEA_DEPENDENCIES = $(DEPS) +t_eoEasyEA_LDFLAGS = -lm +t_eoEasyEA_LDADD = $(LDADDS) + +############################################################################### + t_eobreeder_SOURCES = t-eobreeder.cpp t_eobreeder_DEPENDENCIES = $(DEPS) t_eobreeder_LDFLAGS = -lm @@ -146,6 +153,13 @@ t_eolottery_SOURCES = t-eolottery.cpp t_eolottery_DEPENDENCIES = $(DEPS) t_eolottery_LDFLAGS = -lm t_eolottery_LDADD = $(LDADDS) + +############################################################################### + +t_eo2dVector_SOURCES = t-eo2dVector.cc +t_eo2dVector_DEPENDENCIES = $(DEPS) +t_eo2dVector_LDFLAGS = -lm +t_eo2dVector_LDADD = $(LDADDS) mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs CONFIG_CLEAN_FILES = PROGRAMS = $(noinst_PROGRAMS) @@ -155,7 +169,6 @@ DEFS = @DEFS@ -I. -I$(srcdir) CPPFLAGS = @CPPFLAGS@ LDFLAGS = @LDFLAGS@ LIBS = @LIBS@ -t_eogeneration_OBJECTS = t-eogeneration.o t_eobreeder_OBJECTS = t-eobreeder.o t_eoinclusion_OBJECTS = t-eoinclusion.o t_eoinsertion_OBJECTS = t-eoinsertion.o @@ -169,6 +182,9 @@ t_eoproblem_DEPENDENCIES = t_eobin_OBJECTS = t-eobin.o t_eobin_LDFLAGS = t_eolottery_OBJECTS = t-eolottery.o +t_eo2dVector_OBJECTS = t-eo2dVector.o +t_eogeneration_OBJECTS = t-eogeneration.o +t_eoEasyEA_OBJECTS = t-eoEasyEA.o CXXFLAGS = @CXXFLAGS@ CXXCOMPILE = $(CXX) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) LTCXXCOMPILE = $(LIBTOOL) --mode=compile $(CXX) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) @@ -181,15 +197,16 @@ DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) TAR = gtar GZIP_ENV = --best -DEP_FILES = .deps/t-eo.P .deps/t-eobin.P .deps/t-eobreeder.P \ -.deps/t-eofitness.P .deps/t-eogeneration.P .deps/t-eoinclusion.P \ -.deps/t-eoinsertion.P .deps/t-eolottery.P .deps/t-eoproblem.P -SOURCES = $(t_eogeneration_SOURCES) $(t_eobreeder_SOURCES) $(t_eoinclusion_SOURCES) $(t_eoinsertion_SOURCES) $(t_eo_SOURCES) $(t_eofitness_SOURCES) $(t_eoproblem_SOURCES) $(t_eobin_SOURCES) $(t_eolottery_SOURCES) -OBJECTS = $(t_eogeneration_OBJECTS) $(t_eobreeder_OBJECTS) $(t_eoinclusion_OBJECTS) $(t_eoinsertion_OBJECTS) $(t_eo_OBJECTS) $(t_eofitness_OBJECTS) $(t_eoproblem_OBJECTS) $(t_eobin_OBJECTS) $(t_eolottery_OBJECTS) +DEP_FILES = .deps/t-eo.P .deps/t-eo2dVector.P .deps/t-eoEasyEA.P \ +.deps/t-eobin.P .deps/t-eobreeder.P .deps/t-eofitness.P \ +.deps/t-eogeneration.P .deps/t-eoinclusion.P .deps/t-eoinsertion.P \ +.deps/t-eolottery.P .deps/t-eoproblem.P +SOURCES = $(t_eobreeder_SOURCES) $(t_eoinclusion_SOURCES) $(t_eoinsertion_SOURCES) $(t_eo_SOURCES) $(t_eofitness_SOURCES) $(t_eoproblem_SOURCES) $(t_eobin_SOURCES) $(t_eolottery_SOURCES) $(t_eo2dVector_SOURCES) $(t_eogeneration_SOURCES) $(t_eoEasyEA_SOURCES) +OBJECTS = $(t_eobreeder_OBJECTS) $(t_eoinclusion_OBJECTS) $(t_eoinsertion_OBJECTS) $(t_eo_OBJECTS) $(t_eofitness_OBJECTS) $(t_eoproblem_OBJECTS) $(t_eobin_OBJECTS) $(t_eolottery_OBJECTS) $(t_eo2dVector_OBJECTS) $(t_eogeneration_OBJECTS) $(t_eoEasyEA_OBJECTS) all: all-redirect .SUFFIXES: -.SUFFIXES: .S .c .cpp .lo .o .s +.SUFFIXES: .S .c .cc .cpp .lo .o .s $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) cd $(top_srcdir) && $(AUTOMAKE) --gnu test/Makefile @@ -239,10 +256,6 @@ distclean-libtool: maintainer-clean-libtool: -t-eogeneration: $(t_eogeneration_OBJECTS) $(t_eogeneration_DEPENDENCIES) - @rm -f t-eogeneration - $(CXXLINK) $(t_eogeneration_LDFLAGS) $(t_eogeneration_OBJECTS) $(t_eogeneration_LDADD) $(LIBS) - t-eobreeder: $(t_eobreeder_OBJECTS) $(t_eobreeder_DEPENDENCIES) @rm -f t-eobreeder $(CXXLINK) $(t_eobreeder_LDFLAGS) $(t_eobreeder_OBJECTS) $(t_eobreeder_LDADD) $(LIBS) @@ -274,6 +287,22 @@ t-eobin: $(t_eobin_OBJECTS) $(t_eobin_DEPENDENCIES) t-eolottery: $(t_eolottery_OBJECTS) $(t_eolottery_DEPENDENCIES) @rm -f t-eolottery $(CXXLINK) $(t_eolottery_LDFLAGS) $(t_eolottery_OBJECTS) $(t_eolottery_LDADD) $(LIBS) + +t-eo2dVector: $(t_eo2dVector_OBJECTS) $(t_eo2dVector_DEPENDENCIES) + @rm -f t-eo2dVector + $(CXXLINK) $(t_eo2dVector_LDFLAGS) $(t_eo2dVector_OBJECTS) $(t_eo2dVector_LDADD) $(LIBS) + +t-eogeneration: $(t_eogeneration_OBJECTS) $(t_eogeneration_DEPENDENCIES) + @rm -f t-eogeneration + $(CXXLINK) $(t_eogeneration_LDFLAGS) $(t_eogeneration_OBJECTS) $(t_eogeneration_LDADD) $(LIBS) + +t-eoEasyEA: $(t_eoEasyEA_OBJECTS) $(t_eoEasyEA_DEPENDENCIES) + @rm -f t-eoEasyEA + $(CXXLINK) $(t_eoEasyEA_LDFLAGS) $(t_eoEasyEA_OBJECTS) $(t_eoEasyEA_LDADD) $(LIBS) +.cc.o: + $(CXXCOMPILE) -c $< +.cc.lo: + $(LTCXXCOMPILE) -c $< .cpp.o: $(CXXCOMPILE) -c $< .cpp.lo: @@ -361,6 +390,25 @@ maintainer-clean-depend: >> .deps/$(*F).P; \ rm -f .deps/$(*F).pp +%.o: %.cc + @echo '$(CXXCOMPILE) -c $<'; \ + $(CXXCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $< + @-cp .deps/$(*F).pp .deps/$(*F).P; \ + tr ' ' '\012' < .deps/$(*F).pp \ + | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \ + >> .deps/$(*F).P; \ + rm .deps/$(*F).pp + +%.lo: %.cc + @echo '$(LTCXXCOMPILE) -c $<'; \ + $(LTCXXCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $< + @-sed -e 's/^\([^:]*\)\.o[ ]*:/\1.lo \1.o :/' \ + < .deps/$(*F).pp > .deps/$(*F).P; \ + tr ' ' '\012' < .deps/$(*F).pp \ + | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \ + >> .deps/$(*F).P; \ + rm -f .deps/$(*F).pp + %.o: %.cpp @echo '$(CXXCOMPILE) -c $<'; \ $(CXXCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $< diff --git a/eo/test/t-eoEasyEA.cpp b/eo/test/t-eoEasyEA.cpp new file mode 100644 index 00000000..59a1d33d --- /dev/null +++ b/eo/test/t-eoEasyEA.cpp @@ -0,0 +1,81 @@ +//----------------------------------------------------------------------------- +// t-eoEasyEA.cpp +//----------------------------------------------------------------------------- + +// to avoid long name warnings +#pragma warning(disable:4786) + +#include + +#include "binary_value.h" + +//----------------------------------------------------------------------------- + +typedef eoBin Chrom; + +//----------------------------------------------------------------------------- + +main() +{ + const unsigned POP_SIZE = 8, CHROM_SIZE = 16; + unsigned i; + + eoUniform uniform(false, true); + eoBinRandom random; + eoPop pop; + + for (i = 0; i < POP_SIZE; ++i) + { + Chrom chrom(CHROM_SIZE); + random(chrom); + binary_value(chrom); + pop.push_back(chrom); + } + + cout << "population:" << endl; + for (i = 0; i < pop.size(); ++i) + cout << "\t" << pop[i] << " " << pop[i].fitness() << endl; + + + // selection + eoLottery lottery; + + // breeder + eoBinBitFlip bitflip; + eoBinCrossover xover; + eoProportionalOpSel propSel; + eoBreeder breeder( propSel ); + propSel.addOp(bitflip, 0.25); + propSel.addOp(xover, 0.75); + + // replacement + eoInclusion inclusion; + + // Evaluation + eoEvalFuncPtr eval( binary_value ); + + // Terminators + eoFitTerm term( pow(2.0, CHROM_SIZE), 1 ); + + // GA generation + eoEasyEA ea(lottery, breeder, inclusion, eval, term); + + // evolution + try + { + ea(pop); + } + catch (exception& e) + { + cout << "exception: " << e.what() << endl;; + exit(EXIT_FAILURE); + } + + cout << "pop" << endl; + for (i = 0; i < pop.size(); ++i) + cout << "\t" << pop[i] << " " << pop[i].fitness() << endl; + + return 0; +} + +//-----------------------------------------------------------------------------