paradiseo/eo/tutorial/html/FirstRealGA_old.html
evomarc 2a93bba7e6 Changed the "to-down / bottom-up" to "algorithm-based / component-based"
Also added all replacement procedures in eoEngine.html
and the general operator interface in eoOperators.html
2000-12-19 10:17:39 +00:00

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
&lt;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
&lt;iostream>// cout</font></font></font>
<br><font face="Courier New,Courier"><font color="#993300"><font size=+1>#include
&lt;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
&lt;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&lt;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&lt;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>&nbsp;&nbsp;&nbsp; @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 &amp; _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>&nbsp;
double sum = 0;</font></font></font>
<br><font face="Courier New,Courier"><font color="#CC0000"><font size=+1>&nbsp;
for (unsigned i = 0; i &lt; _indi.size(); i++)</font></font></font>
<br><font face="Courier New,Courier"><font color="#CC0000"><font size=+1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
sum += _indi[i]*_indi[i];</font></font></font>
<br><font face="Courier New,Courier"><font color="#CC0000"><font size=+1>&nbsp;
return (-sum);&nbsp;&nbsp; // 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>&nbsp;
<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&lt;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&lt;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&lt;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&lt;POP_SIZE; igeno++)</font></font></font>
<br><font face="Courier New,Courier"><font color="#CC33CC"><font size=+1>&nbsp;
{</font></font></font>
<br><font face="Courier New,Courier"><font color="#CC33CC"><font size=+1>&nbsp;&nbsp;&nbsp;
Indi v; // generate a random individual</font></font></font>
<br><font face="Courier New,Courier"><font color="#CC33CC"><font size=+1>&nbsp;&nbsp;&nbsp;
for (unsigned ivar=0; ivar&lt;VEC_SIZE; ivar++)</font></font></font>
<br><font face="Courier New,Courier"><font color="#CC33CC"><font size=+1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
{</font></font></font>
<br><font face="Courier New,Courier"><font color="#CC33CC"><font size=+1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
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>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
v.push_back(r); //</font></font></font>
<br><font face="Courier New,Courier"><font color="#CC33CC"><font size=+1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
}</font></font></font>
<br><font face="Courier New,Courier"><font color="#CC33CC"><font size=+1>&nbsp;&nbsp;&nbsp;
eval(v); // evaluate it</font></font></font>
<br><font face="Courier New,Courier"><font color="#CC33CC"><font size=+1>&nbsp;&nbsp;&nbsp;
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>&nbsp;
}</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
&lt;&lt; "Initial Population" &lt;&lt; endl;</font></font></font>
<br><font face="Courier New,Courier"><font color="#66FFFF"><font size=+1>cout
&lt;&lt; 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 &lt;&lt; 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 &lt;&lt; operator for eoPop
uses the &lt;&lt; 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&lt;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&lt;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&lt;Indi>&nbsp;
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&lt;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>&nbsp;
<p><a NAME="generation"></a><font face="Courier New,Courier"><font color="#FF6666"><font size=+1>eoSGA&lt;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
&lt;&lt; "FINAL Population\n" &lt;&lt; pop &lt;&lt; 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&amp;
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
&lt;&lt; "Exception: " &lt;&lt; e.what() &lt;&lt; '\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>