Also added all replacement procedures in eoEngine.html and the general operator interface in eoOperators.html
278 lines
21 KiB
HTML
278 lines
21 KiB
HTML
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
|
|
<html>
|
|
<head>
|
|
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
|
<meta name="GENERATOR" content="Mozilla/4.51 [en] (X11; I; Linux 2.2.5-15 i686) [Netscape]">
|
|
<title>First Real GA</title>
|
|
</head>
|
|
<body text="#000000" bgcolor="#C3C2B4" link="#0000EE" vlink="#551A8B" alink="#FF0000">
|
|
<a href="eoLesson1.html">Back to Lesson 1</a> - <a href="eoTutorial.html">Tutorial
|
|
main page </a>- <a href="eoTopDown.html">Algorithm-Based</a> - <a href="eoBottomUp.html">Component-Based
|
|
page</a> - <a href="eoProgramming.html">Programming hints</a> - <font face="Arial,Helvetica"><a href="../../doc/html/index.html">EO
|
|
documentation</a></font>
|
|
<br>
|
|
<hr WIDTH="100%"><!-- -------------- End of header ------------------ --><!-- ----------------------------------------------- -->
|
|
<center>
|
|
<h1>
|
|
<font color="#FF0000">A First Real GA</font></h1></center>
|
|
Click on the figure to see the corresponding code. Tutorial comments are
|
|
in variable length fonts, after the code.
|
|
<center>
|
|
<p><img SRC="EA_tutorial.jpg" USEMAP="#Map" ></center>
|
|
<map NAME="Map"><area SHAPE="rect" HREF="#init" COORDS="0,0,112,40"><area SHAPE="rect" HREF="#eval" COORDS="0,78,112,112"><area SHAPE="rect" HREF="#select" COORDS="395,70,507,107"><area SHAPE="rect" HREF="#replace" COORDS="145,144,253,182"><area SHAPE="rect" HREF="#crossover" COORDS="433,145,543,164"><area SHAPE="rect" HREF="#mutation" COORDS="433,164,543,182"><area SHAPE="rect" HREF="#eval" COORDS="218,217,325,252"><area SHAPE="rect" HREF="#output" COORDS="235,14,415,38"><area SHAPE="rect" HREF="#representation" COORDS="143,68,253,114"><area SHAPE="rect" HREF="#representation" COORDS="394,214,515,255"><area SHAPE="rect" HREF="#stop" COORDS="278,74,370,109"><area SHAPE="rect" HREF="#generation" COORDS="257,114,431,213"><!-- 4 lignes en bas --><area SHAPE="rect" HREF="#eval" COORDS="0,334,207,352"><area SHAPE="rect" HREF="#engine" COORDS="0,310,356,334"><area SHAPE="rect" HREF="#operators" COORDS="0,288,230,310"><area SHAPE="rect" HREF="#representation" COORDS="230,288,450,310"><area SHAPE="rect" HREF="#parametres" COORDS="0,358,278,378"></map>
|
|
<p><font face="Courier New,Courier"><font size=+1>//-----------------------------------------------------------------------------</font></font>
|
|
<p><font face="Courier New,Courier"><font color="#993300"><font size=+1>#include
|
|
<stdexcept > // runtime_error</font></font></font>
|
|
<p><font face="Courier New,Courier"><font size=+1>//-----------------------------------------------------------------------------</font></font>
|
|
<br><font face="Courier New,Courier"><font size=+1>// FirstRealGA.cpp</font></font>
|
|
<br><font face="Courier New,Courier"><font size=+1>//-----------------------------------------------------------------------------</font></font>
|
|
<br><font face="Courier New,Courier"><font size=+1>//*</font></font>
|
|
<br><font face="Courier New,Courier"><font size=+1>// An instance of a
|
|
VERY simple Real-coded Genetic Algorithm</font></font>
|
|
<br><font face="Courier New,Courier"><font size=+1>//</font></font>
|
|
<br><font face="Courier New,Courier"><font size=+1>//-----------------------------------------------------------------------------</font></font>
|
|
<br><font face="Courier New,Courier"><font size=+1>// standard includes</font></font>
|
|
<p><font face="Courier New,Courier"><font color="#993300"><font size=+1>#include
|
|
<iostream>// cout</font></font></font>
|
|
<br><font face="Courier New,Courier"><font color="#993300"><font size=+1>#include
|
|
<strstream>// ostrstream, istrstream</font></font></font>
|
|
<p><font face="Courier New,Courier"><font size=+1>// the general include
|
|
for eo</font></font>
|
|
<p><font face="Courier New,Courier"><font color="#FF6666"><font size=+1>#include
|
|
<eo></font></font></font>
|
|
<p><font face="Courier New,Courier"><font size=+1>// specific incluse,
|
|
as Real is not (yet) in the standard eo source dir</font></font>
|
|
<br><font face="Courier New,Courier"><font color="#FF6666"><font size=+1>#include
|
|
"eoeal.h"</font></font></font>
|
|
<br><font face="Courier New,Courier"><font color="#FF6666"><font size=+1>#include
|
|
"eoRealOp.h"</font></font></font>
|
|
<p><font face="Courier New,Courier"><font size=+1>//-----------------------------------------------------------------------------</font></font>
|
|
<br><font face="Courier New,Courier"><font size=+1>// define your individual:</font></font>
|
|
<p><a NAME="representation"></a><font face="Courier New,Courier"><font color="#FFFF00"><font size=+1>typedef
|
|
eoReal<double> Indi;</font></font></font>
|
|
<p>You say here that you will be handling <font face="Arial,Helvetica">arrays
|
|
of doubles</font>, whose fitness is a double
|
|
<br>Note that this makes Indi derive from <a href="eoProgramming.html#STL">STL
|
|
class</a> <font color="#993300">vector<double></font>
|
|
<br><font face="Courier New,Courier"><font size=+1>//-----------------------------------------------------------------------------</font></font>
|
|
<br><font face="Courier New,Courier"><font size=+1>/** a simple fitness
|
|
function that computes the euclidian norm of a real vector</font></font>
|
|
<br><font face="Courier New,Courier"><font size=+1> @param
|
|
_indi A real-valued individual</font></font>
|
|
<br><font face="Courier New,Courier"><font size=+1>*/</font></font>
|
|
<p><a NAME="evalfunc"></a><font face="Courier New,Courier"><font color="#CC0000"><font size=+1>double
|
|
real_value(const Indi & _indi)</font></font></font>
|
|
<br><font face="Courier New,Courier"><font color="#CC0000"><font size=+1>{</font></font></font>
|
|
<br><font face="Courier New,Courier"><font color="#CC0000"><font size=+1>
|
|
double sum = 0;</font></font></font>
|
|
<br><font face="Courier New,Courier"><font color="#CC0000"><font size=+1>
|
|
for (unsigned i = 0; i < _indi.size(); i++)</font></font></font>
|
|
<br><font face="Courier New,Courier"><font color="#CC0000"><font size=+1>
|
|
sum += _indi[i]*_indi[i];</font></font></font>
|
|
<br><font face="Courier New,Courier"><font color="#CC0000"><font size=+1>
|
|
return (-sum); // maximizing</font></font></font>
|
|
<br><font face="Courier New,Courier"><font color="#CC0000"><font size=+1>}</font></font></font>
|
|
<p>This simple function computes the sum of the squares of the variables
|
|
(remember Indi is here a vector of doubles)
|
|
<br><font face="Courier New,Courier"><font size=+1>//-----------------------------------------------------------------------------</font></font>
|
|
<p><font face="Courier New,Courier"><font color="#993300"><font size=+1>void
|
|
main_function(int argc, char **argv)</font></font></font>
|
|
<br><font face="Courier New,Courier"><font size=+1>{</font></font>
|
|
<br><font face="Courier New,Courier"><font color="#66FFFF"><font size=+1>const
|
|
unsigned int SEED = 42;// seed for random number generator</font></font></font>
|
|
<br><font face="Courier New,Courier"><font color="#66FFFF"><font size=+1>const
|
|
unsigned int VEC_SIZE = 8; // Number of object variables in genotypes</font></font></font>
|
|
<br><font face="Courier New,Courier"><font color="#66FFFF"><font size=+1>const
|
|
unsigned int POP_SIZE = 20; // Size of population</font></font></font>
|
|
<br><font face="Courier New,Courier"><font color="#66FFFF"><font size=+1>const
|
|
unsigned int T_SIZE = 3; // size for tournament selection</font></font></font>
|
|
<br><font face="Courier New,Courier"><font color="#66FFFF"><font size=+1>const
|
|
unsigned int MAX_GEN = 500; // Maximum number of generation before STOP</font></font></font>
|
|
<br><font face="Courier New,Courier"><font color="#66FFFF"><font size=+1>const
|
|
float CROSS_RATE = 0.8; // Crossover rate</font></font></font>
|
|
<br><font face="Courier New,Courier"><font color="#66FFFF"><font size=+1>const
|
|
double EPSILON = 0.01; // range for real uniform mutation</font></font></font>
|
|
<br><font face="Courier New,Courier"><font color="#66FFFF"><font size=+1>const
|
|
float MUT_RATE = 0.5; // mutation rate</font></font></font>
|
|
<br>
|
|
<p><font face="Courier New,Courier"><font size=+1>//////////////////////////</font></font>
|
|
<br><font face="Courier New,Courier"><font size=+1>// Random seed</font></font>
|
|
<br><font face="Courier New,Courier"><font size=+1>//////////////////////////</font></font>
|
|
<br><font face="Courier New,Courier"><font size=+1>//reproducible random
|
|
seed: if you don't change SEED above,</font></font>
|
|
<br><font face="Courier New,Courier"><font size=+1>// you'll aways get
|
|
the same result, NOT a random run</font></font>
|
|
<br><font face="Courier New,Courier"><font color="#FF6666"><font size=+1>rng.reseed(SEED);</font></font></font>
|
|
<p><font face="Courier New,Courier"><font size=+1>/////////////////////////////</font></font>
|
|
<br><font face="Courier New,Courier"><font size=+1>// Fitness function</font></font>
|
|
<br><font face="Courier New,Courier"><font size=+1>////////////////////////////</font></font>
|
|
<br><font face="Courier New,Courier"><font size=+1>// Evaluation: from
|
|
a plain C++ fn to an EvalFunc Object</font></font>
|
|
<br><a NAME="eval"></a><font face="Courier New,Courier"><font color="#CC0000"><font size=+1>eoEvalFuncPtr<Indi>
|
|
eval( <a href="#evalfunc">real_value</a> );</font></font></font>
|
|
<p>This encapsulate the C++ function real_value into a <a href="eoProgramming.html#functors">functor
|
|
object</a>
|
|
<p><font face="Courier New,Courier"><font size=+1>////////////////////////////////</font></font>
|
|
<br><font face="Courier New,Courier"><font size=+1>// Initilisation of
|
|
population</font></font>
|
|
<br><font face="Courier New,Courier"><font size=+1>////////////////////////////////</font></font>
|
|
<p><font face="Courier New,Courier"><font size=+1>// declare the population</font></font>
|
|
<br><font face="Courier New,Courier"><font color="#CC33CC"><font size=+1>eoPop<Indi>
|
|
pop;</font></font></font>
|
|
<p>Declares a <font face="Arial,Helvetica"><a href="../../doc/html/class_eopop.html">population
|
|
object</a>, </font>which is basically an <a href="eoProgramming.html#STL">STL</a>
|
|
<tt><font color="#993300"><font size=+1>vector<Indi></font></font></tt>
|
|
<p><font face="Courier New,Courier"><font size=+1>// fill it!</font></font>
|
|
<br><a NAME="init"></a><font face="Courier New,Courier"><font color="#CC33CC"><font size=+1>for
|
|
(unsigned int igeno=0; igeno<POP_SIZE; igeno++)</font></font></font>
|
|
<br><font face="Courier New,Courier"><font color="#CC33CC"><font size=+1>
|
|
{</font></font></font>
|
|
<br><font face="Courier New,Courier"><font color="#CC33CC"><font size=+1>
|
|
Indi v; // generate a random individual</font></font></font>
|
|
<br><font face="Courier New,Courier"><font color="#CC33CC"><font size=+1>
|
|
for (unsigned ivar=0; ivar<VEC_SIZE; ivar++)</font></font></font>
|
|
<br><font face="Courier New,Courier"><font color="#CC33CC"><font size=+1>
|
|
{</font></font></font>
|
|
<br><font face="Courier New,Courier"><font color="#CC33CC"><font size=+1>
|
|
double r = 2*rng.uniform() - 1; // new value, random in [-1,1)</font></font></font>
|
|
<br><font face="Courier New,Courier"><font color="#CC33CC"><font size=+1>
|
|
v.push_back(r); //</font></font></font>
|
|
<br><font face="Courier New,Courier"><font color="#CC33CC"><font size=+1>
|
|
}</font></font></font>
|
|
<br><font face="Courier New,Courier"><font color="#CC33CC"><font size=+1>
|
|
eval(v); // evaluate it</font></font></font>
|
|
<br><font face="Courier New,Courier"><font color="#CC33CC"><font size=+1>
|
|
pop.push_back(v); // and put it in the population</font></font></font>
|
|
<br><font face="Courier New,Courier"><font color="#CC33CC"><font size=+1>
|
|
}</font></font></font>
|
|
<p>This initialization of the population is straightforward
|
|
<br><font color="#CC33CC">rng.uniform()</font> generates a double <font face="Arial,Helvetica"><a href="../../doc/html/class_eorng.html">uniformly
|
|
in [0,1)</a>,</font>
|
|
<br><font color="#CC33CC">v.push_back</font> simply appends its argument
|
|
at the end of <a href="eoProgramming.html#STL">STL</a> vector <font face="Courier New,Courier"><font color="#CC33CC"><font size=+1>v</font></font></font>
|
|
<br><font color="#CC33CC">eval(v)</font>evaluates individal <font color="#CC33CC">v</font>
|
|
the <a href="eoProgramming.html#functors">functor way</a>, calling <font face="Courier New,Courier"><font color="#CC33CC"><font size=+1>eval.operator()(v)</font></font></font>
|
|
<p><font face="Courier New,Courier"><font size=+1>// sort pop before printing
|
|
it!</font></font>
|
|
<br><font face="Courier New,Courier"><font color="#66FFFF"><font size=+1>pop.sort();</font></font></font>
|
|
<p><font face="Courier New,Courier"><font size=+1>// Print (sorted) intial
|
|
population (raw printout)</font></font>
|
|
<br><font face="Courier New,Courier"><font color="#66FFFF"><font size=+1>cout
|
|
<< "Initial Population" << endl;</font></font></font>
|
|
<br><font face="Courier New,Courier"><font color="#66FFFF"><font size=+1>cout
|
|
<< pop;</font></font></font>
|
|
<p>If you looked at <font face="Arial,Helvetica"><a href="../../doc/html/class_eopop.html">eoPop</a></font>
|
|
inheritance diagram, you noticed that it derives from <font face="Arial,Helvetica"><a href="../../doc/html/class_eoprintable.html">eoPrintable</a>:</font>
|
|
hence you can stream them using the << operator. Of course, Indis
|
|
are <font face="Arial,Helvetica"><a href="../../doc/html/class_eo.html">EO objects</a>
|
|
</font>, which also are eoPrintable, and the << operator for eoPop
|
|
uses the << operator for Indi.
|
|
<p><font face="Courier New,Courier"><font size=+1>/////////////////////////////////////</font></font>
|
|
<br><a NAME="engine"></a><font face="Courier New,Courier"><font size=+1>//
|
|
selection and replacement</font></font>
|
|
<br><font face="Courier New,Courier"><font size=+1>////////////////////////////////////</font></font>
|
|
<br><font face="Courier New,Courier"><font size=+1>// The well-known roulette
|
|
selection</font></font>
|
|
<br><a NAME="select"></a><font face="Courier New,Courier"><font size=+1>//
|
|
The robust tournament selection</font></font>
|
|
<br><font face="Courier New,Courier"><font color="#009900"><font size=+1>eoDetTournament<Indi>
|
|
select(T_SIZE); // SIZE in [2,POP_SIZE]</font></font></font>
|
|
<p><a NAME="replace"></a><font face="Courier New,Courier"><font size=+1>//
|
|
eoSGA uses <font color="#009900">generational replacement</font> by default</font></font>
|
|
<br><font face="Courier New,Courier"><font size=+1>// so no replacement
|
|
procedure has to be given</font></font>
|
|
<p><font face="Courier New,Courier"><font size=+1>//////////////////////////////////////</font></font>
|
|
<br><font face="Courier New,Courier"><font size=+1>// termination condition</font></font>
|
|
<br><font face="Courier New,Courier"><font size=+1>/////////////////////////////////////</font></font>
|
|
<br><font face="Courier New,Courier"><font size=+1>// stop after MAX_GEN
|
|
generations</font></font>
|
|
<br><a NAME="stop"></a><font face="Courier New,Courier"><font color="#66FFFF"><font size=+1>eoGenContinue<Indi>
|
|
continuator(MAX_GEN);</font></font></font>
|
|
<p>This class is called <font face="Arial,Helvetica"><a href="../../doc/html/class_eogencontinue.html">eoGenContinue</a>
|
|
</font>because the main loop of all <font face="Arial,Helvetica"><a href="../../doc/html/class_eoalgo.html">eoAlgo</a>
|
|
</font>says ... while continuator(pop)
|
|
<p><font face="Courier New,Courier"><font size=+1>//////////////////////////////////////</font></font>
|
|
<br><a NAME="operators"></a><font face="Courier New,Courier"><font size=+1>//
|
|
The variation operators</font></font>
|
|
<br><font face="Courier New,Courier"><font size=+1>//////////////////////////////////////</font></font>
|
|
<p><a NAME="mutation"></a><font face="Courier New,Courier"><font size=+1>//
|
|
offspring(i) uniformly chosen in [parent(i)-epsilon, parent(i)+epsilon]</font></font>
|
|
<br><font face="Courier New,Courier"><font color="#CC33CC"><font size=+1>eoUniformMutation<Indi>
|
|
mutation(EPSILON);</font></font></font>
|
|
<br><a NAME="crossover"></a><font face="Courier New,Courier"><font size=+1>//
|
|
offspring(i) is a linear combination of parent(i)</font></font>
|
|
<br><font face="Courier New,Courier"><font color="#CC33CC"><font size=+1>eoArithmeticCrossover<Indi>
|
|
xover;</font></font></font>
|
|
<p>The <a href="eoOperators.html">variation operators</a> are respectively
|
|
an <font face="Arial,Helvetica"><a href="../../doc/html/class_eomonop.html">eoMonOp</a></font>
|
|
(unary operator) and an <font face="Arial,Helvetica"><a href="../../doc/html/class_eoquadraticop.html">eoQuadOp</a></font>
|
|
(binary operator that modifies both its arguments).
|
|
<p><font face="Courier New,Courier"><font size=+1>/////////////////////////////////////////</font></font>
|
|
<br><font face="Courier New,Courier"><font size=+1>// the algorithm</font></font>
|
|
<br><font face="Courier New,Courier"><font size=+1>////////////////////////////////////////</font></font>
|
|
<br><font face="Courier New,Courier"><font size=+1>// standard Generational
|
|
GA requires</font></font>
|
|
<br><font face="Courier New,Courier"><font size=+1>// selection, evaluation,
|
|
crossover and mutation, stopping criterion</font></font>
|
|
<br>
|
|
<p><a NAME="generation"></a><font face="Courier New,Courier"><font color="#FF6666"><font size=+1>eoSGA<Indi>
|
|
gga(select, xover, CROSS_RATE, mutation, MUT_RATE,</font></font></font>
|
|
<br><font face="Courier New,Courier"><font color="#FF6666"><font size=+1>eval,
|
|
continuator);</font></font></font>
|
|
<p><font face="Courier New,Courier"><font size=+1>// Apply algo to pop
|
|
- that's it!</font></font>
|
|
<br><font face="Courier New,Courier"><font color="#FF6666"><font size=+1>gga(pop);</font></font></font>
|
|
<p>This simple algorithm of class eoSGA is a <a href="eoProgramming.html#functors">functor
|
|
object</a>, and running the algorithm amounts to call the <font color="#993300">operator()</font>
|
|
on the initial population!
|
|
<p><font face="Courier New,Courier"><font size=+1>// Print (sorted) intial
|
|
population (raw printout)</font></font>
|
|
<br><a NAME="output"></a><font face="Courier New,Courier"><font color="#66FFFF"><font size=+1>pop.sort();</font></font></font>
|
|
<br><font face="Courier New,Courier"><font color="#66FFFF"><font size=+1>cout
|
|
<< "FINAL Population\n" << pop << endl;</font></font></font>
|
|
<p>that's it - just print the final population and you're done!!!
|
|
<p><font face="Courier New,Courier"><font size=+1>}</font></font>
|
|
<p><font face="Courier New,Courier"><font color="#000000"><font size=+1>//
|
|
A main that catches the exceptions - do not modify!</font></font></font>
|
|
<br><font face="Courier New,Courier"><font color="#993300"><font size=+1>int
|
|
main(int argc, char **argv)</font></font></font>
|
|
<br><font face="Courier New,Courier"><font color="#993300"><font size=+1>{</font></font></font>
|
|
<br><font face="Courier New,Courier"><font color="#993300"><font size=+1>#ifdef
|
|
_MSC_VER</font></font></font>
|
|
<br><font face="Courier New,Courier"><font color="#993300"><font size=+1>//
|
|
rng.reseed(42);</font></font></font>
|
|
<br><font face="Courier New,Courier"><font color="#993300"><font size=+1>int
|
|
flag = _CrtSetDbgFlag(_CRTDBG_LEAK_CHECK_DF);</font></font></font>
|
|
<br><font face="Courier New,Courier"><font color="#993300"><font size=+1>flag
|
|
|= _CRTDBG_LEAK_CHECK_DF;</font></font></font>
|
|
<br><font face="Courier New,Courier"><font color="#993300"><font size=+1>_CrtSetDbgFlag(flag);</font></font></font>
|
|
<br><font face="Courier New,Courier"><font color="#993300"><font size=+1>//
|
|
_CrtSetBreakAlloc(100);</font></font></font>
|
|
<br><font face="Courier New,Courier"><font color="#993300"><font size=+1>#endif</font></font></font>
|
|
<p><font face="Courier New,Courier"><font color="#993300"><font size=+1>try</font></font></font>
|
|
<br><font face="Courier New,Courier"><font color="#993300"><font size=+1>{</font></font></font>
|
|
<br><font face="Courier New,Courier"><font color="#993300"><font size=+1>main_function(argc,
|
|
argv);</font></font></font>
|
|
<br><font face="Courier New,Courier"><font color="#993300"><font size=+1>}</font></font></font>
|
|
<br><font face="Courier New,Courier"><font color="#993300"><font size=+1>catch(exception&
|
|
e)</font></font></font>
|
|
<br><font face="Courier New,Courier"><font color="#993300"><font size=+1>{</font></font></font>
|
|
<br><font face="Courier New,Courier"><font color="#993300"><font size=+1>cout
|
|
<< "Exception: " << e.what() << '\n';</font></font></font>
|
|
<br><font face="Courier New,Courier"><font color="#993300"><font size=+1>}</font></font></font>
|
|
<p><font face="Courier New,Courier"><font color="#993300"><font size=+1>return
|
|
1;</font></font></font>
|
|
<br><font face="Courier New,Courier"><font color="#993300"><font size=+1>}</font></font></font>
|
|
<p>
|
|
<hr WIDTH="100%"><a href="eoLesson1.html">Back to Lesson 1</a> - <a href="eoTutorial.html">Tutorial
|
|
main page </a>- <a href="eoTopDown.html">Algorithm-Based</a> - <a href="eoBottomUp.html">Component-Based
|
|
page</a> - <a href="eoProgramming.html">Programming hints</a> - <font face="Arial,Helvetica"><a href="../../doc/html/index.html">EO
|
|
documentation</a></font>
|
|
<hr>
|
|
<address>
|
|
<a href="mailto:marc@cmapx.polytechnique.fr">Marc Schoenauer</a></address>
|
|
|
|
<br><!-- Created: Wed Nov 1 07:18:21 CET 2000 --><!-- hhmts start -->Last
|
|
modified: Wed Nov 6 17:22:43 CET 2000<!-- hhmts end -->
|
|
</body>
|
|
</html>
|