📄 eooperators.html
字号:
for <b><font face="Arial,Helvetica"><font size=+1><a href="../../doc/html/classeo_mon_op.html">eoMonOp</a></font></font></b>).<p><b><font color="#FF0000">Interfaces</font></b>:<br>The general approach in EO about simple variation operators is to perform<b><font color="#FF6600">in-placemodifications</font></b>, i.e. modifying the arguments rather than generatingnew (modified) individuals. This results in the following interface forthe functor objects eoMonOp:<p><b><tt><font color="#993300">bool operator()(EOT & )</font></tt></b><p>which you could have guessed from the inheritance diagrams up to theeoUF abstract class.<p><b><font color="#FF0000">Using mutation operators</font></b>:<br>Directly applying mutation operators is straightforward from the interfaceabove:<br><tt><font color="#993300"><b>eoMonOpDerivedClass<Indi> myMutation(parameters);</b>//pass parameters in constructor</font></tt><br><tt><font color="#993300"><b>Indi eo = ...; /</b>/ eo is candidate to mutation</font></tt><br><b><tt><font color="#993300">if (myMutation(eo))</font></tt></b><br><tt><font color="#993300"><b> { ... </b>//eo has been modified</font></tt><br><b><tt><font color="#993300"> }</font></tt></b><br><tt><font color="#993300"><b>else </b>//eo has not been modified</font></tt><p>However, you will hardly have to actually apply operators to individuals,as operators are used within other classes, and are applied systematicallyto whole sets of individuals (e.g. that have already been selected, instandard generational evolutionary algorithms).<br>Hence the way to use such operators will more likely ressemble <a href="FirstRealGA.html#operators">this</a>if you are using for instance an SGA. See also the different ways thatare described below, encapsulating the operators into combined operatorsobjects.<p><a NAME="writing_mutation"></a><b><font color="#FF0000">Writing a mutationoperator:</font></b><br>There are only two things to modify in the <a href="../Templates/mutation.tmpl">templateclass definitions</a> provided in the Templates directory (apart from thename of the class you are creating!)<ul><li>The <font color="#FF6600">constructor</font>, where you pass to the objectany useful parameter (see the private data at end of class definition).</li><li>The <font color="#FF6600">operator()</font> method, which performs theactual crossover.</li><li>The <font color="#FF6600">return value</font>, that should be <b><tt><font color="#993300">true</font></tt></b>as soon as the genotype has actually been modified. Otherwise, the<a href="eoEval.html#lazy">lazyfitness evaluation procedure</a> in EO might not know it should computethe fitness again and will keep the old value.</li></ul><hr WIDTH="100%"><a NAME="proportional_simple"></a><b><font size=+1><font color="#000099">Combiningsimple operators: </font><font color="#FF0000">proportional combinations</font></font></b><p>The best thing to do is to go to the <a href="eoLesson2.html#combined_operators">Lesson2</a>of the tutorial, where everything is explained. You will find out how youcan use<br>several mutations (respectiveley quadratic crossovers) as a singleoperator: every time the operator is called, one of the available operatorsis chosen by some roulette wheel selection using realtive weights.<p><hr WIDTH="100%"><a NAME="general"></a><b><font color="#000099"><font size=+2>GeneralOperators</font></font></b><p>General operators in EO are variation operators that are neither simplemutations nor simple crossovers. They can involve any number of parents,and create any number of offspring. Moreover, they can make use of differentways to get the parents they will involve, e.g. they can use a differentselector for each of the parents they need to select.<p>The corresponding EO class is called <b><font color="#CC33CC">eoGenOp</font></b>.and it is as usual templatized by the type of individual it can handle(see documentation for <b><font face="Arial,Helvetica"><font size=+1><a href="../../doc/html/classeo_mon_op.html">eoGenOp</a></font></font></b>:-)<p><a NAME="interface"></a><b><font color="#FF0000">Interface</font></b>:<br>All the work a general operator is done within the <b><tt><font color="#993300">apply()</font></tt></b>method. WHy not in the usual operator() method? Because some memory managementare needed, that are performed in the base class itself - which then callsthe virtual <b><tt><font color="#993300">apply()</font></tt></b> method.The interface for a <b><font color="#CC33CC">eoGenOp</font></b> thus isnot deducible from its inheritance diagram, and actually is<p><b><tt><font color="#993300"> void apply(eoPopulator<EOT>&_plop)</font></tt></b><p><font color="#000000">As you can see,the interface for </font><b><font color="#CC33CC">eoGenOp</font></b><font color="#000000">is based on that of another class, called </font><b><font color="#999900">eoPopulator</font><font color="#CC33CC">.</font></b>An<b><font color="#999900">eoPopulator</font></b>is a <b><font color="#FF6600">population</font></b>, but also behaves likean <b><font color="#FF6600">iterator</font></b> over a population (hencethe name, <b><font color="#FF6600">Popul</font></b>ation-Iter<b><font color="#FF6600">ator</font></b>). However, please note that you should probably never use an eoGenOp alone,but rather through objects of type <a href="#general_combination">eoOpContainer</a>.<p>This results in the following general interface for an <b><font color="#CC33CC">eoGenOp</font></b>:It receives as argument an <b><font color="#999900">eoPopulator</font></b>,gets the individuals it needs using the <b><tt><font color="#993300">operator*</font></tt></b>,and must handle the positinning of the using the <b><tt><font color="#993300">++operator</font></tt></b>method (<b><font color="#FF6600">Warning</font></b>: the <b><tt><font color="#993300">operator++</font></tt></b>method is not defined, as recommended by many good-programming-style books).<p><a NAME="apply"></a><b><tt><font color="#993300">bool apply()(</font><font color="#999900">eoPopulator</font><font color="#993300">&_pop)</font></tt></b><br><b><tt><font color="#993300">{</font></tt></b><br><tt><font color="#993300"><b> EOT& parent1 = *_pop;</b>//select the first parent</font></tt><br><tt><font color="#993300"><b> ++_plop; </b>//advance once for each selected parents</font></tt><br><b><tt><font color="#993300"> ...</font></tt></b><br><tt><font color="#993300"><b> EOT& parentN = *_pop;</b>//select the last parent</font></tt><br><tt><font color="#993300"><b> </b>//don't advance after the last one: _plop always</font></tt><br><tt><font color="#993300"> // points to the last that has already been treated</font></tt><p><tt><font color="#993300">// do whatever the operator is supposed todo</font></tt><br><b><tt><font color="#993300">}</font></tt></b><p><b><font color="#FF6600">Warning</font></b>: as said above, an eoPopulatorshould always point to the last individual that has already been treated.This is because it is intended to be used within a loop that looks like(see e.g. <b><tt><a href="../../doc/html/classeo_general_breeder.html">eoBreeder</a></tt></b>class):<p><tt><font color="#993300"><b> eoSelectivePopulator<EOT>popit(_parents, _offspring, select);</b> // eoSelectis an eoSelectOne</font></tt><br><b><tt><font color="#993300"> while (_offspring.size()< target)</font></tt></b><br><b><tt><font color="#993300"> {</font></tt></b><br><b><tt><font color="#993300"> op(popit);</font></tt></b><br><b><tt><font color="#993300"> ++it;</font></tt></b><br><b><tt><font color="#993300"> }</font></tt></b><p><b><font color="#FF6600">What happens next?</font></b> Well, it alldepends on how many parents and how many offspring your general op needs:<ul><li>If the number of generated offspring is <font color="#FF6600">equal</font>to the number of parents, the operator simply needs to modify them (theyare passed by reference, no useless copy takes place).</li><li>If the operator produces <font color="#FF6600">more offspring than therewere parents</font>, it needs to insert them into the list using the <b><tt><font color="#993300">insert</font></tt></b>method of the class <b><font color="#999900">eoPopulator</font></b> asin the following:</li><br> <p> <p><b><tt><font color="#993300">void apply()(</font><font color="#999900">eoPopulator</font><font color="#993300">&_pop)</font></tt></b><br><b><tt><font color="#993300">{</font></tt></b><br><tt><font color="#993300"><b> </b>// get the necessary numberof parents (see <a href="#apply">above</a>)</font></tt><br><tt><font color="#993300"> ...</font></tt><br><tt><font color="#993300"> // Now create any supplementary offspring</font></tt><br><b><tt><font color="#993300"> EOT ofs1 = create_individual(...);</font></tt></b><br><b><tt><font color="#993300"> ...</font></tt></b><br><b><tt><font color="#993300"> EOT ofsK = create_individual(...);</font></tt></b><br><tt><font color="#993300"> // advance and inserts offspring in_pop after parentN</font></tt><br><b><tt><font color="#993300"> ++_pop;</font></tt></b><br><b><tt><font color="#993300"> _pop.insert(ofs1);</font></tt></b><br><b><tt><font color="#993300"> ...</font></tt></b><p><tt><font color="#993300"><b> </b>// invalidate the parents thathave been modified</font></tt><br><b><tt><font color="#993300"> parent1.invalidate();</font></tt></b><br><b><tt><font color="#993300"> ...</font></tt></b><br><b><tt><font color="#993300"> parentN.invalidate();</font></tt></b><br><tt><font color="#993300"><b>}</b> // over</font></tt><p>Of course the size of the resulting population will grow - and you shouldhave a replacement procedure that takes care of that.<br> <li>The case where <font color="#FF6600">more parents are needed than offspringwill be created</font> is a little more delicate: think about <b><font color="#CC33CC">eoBinOp</font></b>,and try to imagine the reasons why no crossover of that class are usedin the first lessons of the tutorial, within the SGA framework.</li><br>There are two possibilities:<ul><li>If you think "generational", the first idea is to get the parents fromoutside the curent list, so the total number of (intermediate) offspringis always equal to the initial population size. By chance, the <b><font color="#999900">eoPopulator</font></b>hasa handle on the initial population that was used to start the process,and you can access it from inside the GenOp method. For instance</li><br> <p> <p><b><tt><font color="#993300">void apply()(</font><font color="#999900">eoPopulator</font><font color="#993300">&_pop)</font></tt></b><br><b><tt><font color="#993300">{</font></tt></b><br><tt><font color="#993300"><b> </b>// get as many parents as youwill have offspring (see <a href="#apply">above</a>)</font></tt><br><tt><font color="#993300"> ...</font></tt><br><tt><font color="#993300"><b> // </b>get extra parents - useprivate selector</font></tt><br><b><tt><font color="#993300"> const EOT& parentN+1 = </font><font color="#009900">select</font><font color="#993300">(_pop.source());</font></tt></b><br><b><tt><font color="#993300"> ...</font></tt></b><br><b><tt><font color="#993300"> const EOT& parentM = </font><font color="#009900">select</font><font color="#993300">(_pop.source());</font></tt></b><br><tt><font color="#993300"> // do whatever needs to be done</font></tt><br><tt><font color="#993300"> ...</font></tt><br><tt><font color="#993300"> // and of course invalidate fitnesses
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -