📄 code_death_birth.html
字号:
<font color="#000088">parent_genotype</font>-><font color="#008800">SetBreedStats</font>(*<font color="#000088">child_genotype</font>); <font color="#886600">// Determine the placement of the offspring...</font> const <font color="#880000">int</font> <font color="#000088">parent_id</font> = <font color="#000088">parent_organism</font>.<font color="#008800">PopInterface</font>().<font color="#008800">GetCellID</font>(); <font color="#880000">cPopulationCell</font> & <font color="#000088">parent_cell</font> = <font color="#000088">cell_array</font>[ <font color="#000088">parent_id</font> ]; <font color="#880000">cPopulationCell</font> & <font color="#000088">target_cell</font> = <font color="#008800">PositionChild</font>( <font color="#000088">parent_cell</font> ); <font color="#886600">// Update the parent's and child's phenotype.</font> <font color="#880000">cPhenotype</font> & <font color="#000088">parent_phenotype</font> = <font color="#000088">parent_organism</font>.<font color="#008800">GetPhenotype</font>(); const <font color="#880000">int</font> <font color="#000088">child_length</font> = <font color="#000088">child_organism</font>-><font color="#008800">GetGenome</font>().<font color="#008800">GetSize</font>(); <font color="#000088">parent_phenotype</font>.<font color="#008800">DivideReset</font>(<font color="#000088">parent_organism</font>.<font color="#008800">GetGenome</font>().<font color="#008800">GetSize</font>()); <font color="#000088">child_organism</font>-><font color="#008800">GetPhenotype</font>().<font color="#008800">SetupOffspring</font>(<font color="#000088">parent_phenotype</font>,<font color="#000088">child_length</font>); <font color="#886600">// If we're not about to kill the parent, do some extra work on it.</font> if (<font color="#000088">parent_cell</font>.<font color="#008800">GetID</font>() != <font color="#000088">target_cell</font>.<font color="#008800">GetID</font>()) { <font color="#000088">schedule</font>-><font color="#008800">Adjust</font>(<font color="#000088">parent_cell</font>.<font color="#008800">GetID</font>(), <font color="#000088">parent_phenotype</font>.<font color="#008800">GetMerit</font>()); <font color="#886600">// In a local run, face the child towards the parent.</font> if (<font color="#880000">cConfig</font>::<font color="#008800">GetBirthMethod</font>() < NUM_LOCAL_POSITION_CHILD) { <font color="#000088">target_cell</font>.<font color="#008800">Rotate</font>(<font color="#000088">parent_cell</font>); } } <font color="#886600">// Do any statistics on the parent that just gave birth...</font> <font color="#000088">parent_genotype</font>-><font color="#008800">AddGestationTime</font>( <font color="#000088">parent_phenotype</font>.<font color="#008800">GetGestationTime</font>() ); <font color="#000088">parent_genotype</font>-><font color="#008800">AddFitness</font>( <font color="#000088">parent_phenotype</font>.<font color="#008800">GetFitness</font>() ); <font color="#000088">parent_genotype</font>-><font color="#008800">AddMerit</font>( <font color="#000088">parent_phenotype</font>.<font color="#008800">GetMerit</font>() ); <font color="#000088">parent_genotype</font>-><font color="#008800">AddCopiedSize</font>( <font color="#000088">parent_phenotype</font>.<font color="#008800">GetCopiedSize</font>() ); <font color="#000088">parent_genotype</font>-><font color="#008800">AddExecutedSize</font>( <font color="#000088">parent_phenotype</font>.<font color="#008800">GetExecutedSize</font>() ); <font color="#886600">// Place the offspring...</font> <font color="#008800">ActivateOrganism</font>(<font color="#000088">child_organism</font>, <font color="#000088">target_cell</font>); }</pre><p>This method takes as arguments the parent and child organisms that we'reworking with. It is called by the divide command via the populationinterface. The first thing it does is assert that both the parent and childare valid organisms, and that their not the same as each other (since we don'tallow strange time-travel paradoxes in Avida).<p>The default genotype of the child is the same as its parent. If, however,there were any mutations, the "copy true" flag will be false causing thegenebank to be called to determine its real genotype. The child will thenhave its genotype assigned, and the parent will have its breed statisticsupdated to help keep track of phylogenetic tree information.<p>The next section of code is in charge of finding where in the populationthis organism should be placed. The cell of the parent is looked up, andthen the <font color="#008800">PositionChild</font>() method is called todetermine the child's cell. Since there are so many possible placementoptions that can be set in the genesis file, PositionChild() is actuallyreasonably complicated and I will devote a section to it below.<p>A couple of values are setup as easy-to-use variables, and then the<font color="#008800">DivideReset</font>() method is run on the parent'sphenotype to update everything that has to be done on a divide, and<font color="#008800">SetupOffpsring</font>() is run on the child's phenotypeto initialize it, using information from the parent.<p>If the parent is not about to be killed off (due to being replaced by thechild), we actually want to do a bit more work -- we need to adjustit in the schedule in case its merit has changed over this gestation cycle,and (if we are on a grid) we want to turn the child so that it is facingits parent.<p>Finally, we collect a bunch of statistics for the parent's genotype object,and we run ActivateOffspring using the cell we have chosen in order the placethe child into the population.<h3>Injecting an Organism into the Population</h3><p>Injecting a genome into the population that does not have a parent (such aswith the <tt>inject</tt> event) is somewhat easier to deal with:<pre> void <font color="#880000">cPopulation</font>::<font color="#008800">InjectGenome</font>(<font color="#880000">int</font> <font color="#000088">cell_id</font>, const <font color="#880000">cGenome</font> & <font color="#000088">genome</font>) { <font color="#008800">assert</font>(<font color="#000088">cell_id</font> >= 0 && <font color="#000088">cell_id</font> < <font color="#000088">cell_array</font>.<font color="#008800">GetSize</font>()); <font color="#880000">cOrganism</font> * <font color="#000088">new_organism</font> = new <font color="#880000">cOrganism</font>(<font color="#000088">genome</font>, <font color="#000088">default_interface</font>, <font color="#000088">environment</font>); <font color="#886600">// Setup the genotype...</font> <font color="#880000">cGenotype</font> * <font color="#000088">new_genotype</font> = <font color="#000088">genebank</font>-><font color="#008800">AddGenotype</font>(<font color="#000088">genome</font>); <font color="#000088">new_organism</font>-><font color="#008800">SetGenotype</font>(<font color="#000088">new_genotype</font>); <font color="#886600">// Setup the phenotype...</font> <font color="#880000">cPhenotype</font> & <font color="#000088">phenotype</font> = <font color="#000088">new_organism</font>-><font color="#008800">GetPhenotype</font>(); <font color="#000088">phenotype</font>.<font color="#008800">SetupInject</font>(<font color="#000088">genome</font>.<font color="#008800">GetSize</font>()); <font color="#000088">phenotype</font>.<font color="#008800">SetMerit</font>( <font color="#880000">cMerit</font>(<font color="#000088">new_genotype</font>-><font color="#008800">GetTestMerit</font>()) ); <font color="#886600">// Activate the organism in the population...</font> <font color="#008800">ActivateOrganism</font>(<font color="#000088">new_organism</font>, <font color="#000088">cell_array</font>[<font color="#000088">cell_id</font>]); }</pre><p>Basically, all that this method needs to do is build the organism with theproper genome, determine its genotype, setup its phenotype, put it into atest CPU to get its initial merit, and activate it! You should be able togo line-by-line through the code to see how exactly this happens foryourself.<h3>Choosing the Position of a Child</h3><p>The final method we're going to examine here is the one that determines whichpopulation cell a child organism should be placed into<pre> <font color="#880000">cPopulationCell</font> & <font color="#880000">cPopulation</font>::<font color="#008800">PositionChild</font>(<font color="#880000">cPopulationCell</font> & <font color="#000088">parent_cell</font>) { <font color="#886600">// If we are not using a local (grid) placement method, this is easy.</font> if (<font color="#880000">cConfig</font>::<font color="#008800">GetBirthMethod</font>() >= NUM_LOCAL_POSITION_CHILD) { switch (<font color="#880000">cConfig</font>::<font color="#008800">GetBirthMethod</font>()) { case POSITION_CHILD_FULL_SOUP_RANDOM: return <font color="#008800">GetCell</font>(<font color="#000088">g_random</font>.<font color="#008800">GetUInt</font>(<font color="#000088">cell_array</font>.<font color="#008800">GetSize</font>())); case POSITION_CHILD_FULL_SOUP_ELDEST: return *( <font color="#000088">reaper_queue</font>.<font color="#008800">PopRear</font>() ); } } <font color="#886600">// Construct a list of equally viable locations to place the child...</font> <font color="#880000">tList</font><<font color="#880000">cPopulationCell</font>> <font color="#000088">found_list</font>; <font color="#886600">// First, check if there is an empty organism to work with (always preferred)</font> <font color="#880000">tList</font><<font color="#880000">cPopulationCell</font>> & <font color="#000088">conn_list</font> = <font color="#000088">parent_cell</font>.<font color="#008800">ConnectionList</font>(); <font color="#008800">FindEmptyCell</font>(<font color="#000088">conn_list</font>, <font color="#000088">found_list</font>); <font color="#886600">// If we have not found an empty organism, we must use the specified function</font> <font color="#886600">// to determine how to choose among the filled organisms.</font> if (<font color="#000088">found_list</font>.<font color="#008800">GetSize</font>() == 0) { switch(<font color="#880000">cConfig</font>::<font color="#008800">GetBirthMethod</font>()) { case POSITION_CHILD_AGE: <font color="#008800">PositionAge</font>(<font color="#000088">parent_cell</font>, <font color="#000088">found_list</font>); break; case POSITION_CHILD_MERIT: <font color="#008800">PositionMerit</font>(<font color="#000088">parent_cell</font>, <font color="#000088">found_list</font>); break; case POSITION_CHILD_RANDOM: <font color="#000088">found_list</font>.<font color="#008800">Append</font>(<font color="#000088">conn_list</font>); <font color="#000088">found_list</font>.<font color="#008800">Push</font>(&<font color="#000088">parent_cell</font>); break; case POSITION_CHILD_EMPTY: <font color="#886600">// Nothing is in list if no empty cells are found...</font> <font color="#886600">// Just return the parent.</font> return <font color="#000088">parent_cell</font>; break; } } <font color="#886600">// Choose the organism randomly from those in the list, and return it.</font> <font color="#880000">int</font> <font color="#000088">choice</font> = <font color="#000088">g_random</font>.<font color="#008800">GetUInt</font>(<font color="#000088">found_list</font>.<font color="#008800">GetSize</font>()); return *( <font color="#000088">found_list</font>.<font color="#008800">GetPos</font>(<font color="#000088">choice</font>) ); }</pre><p>This method first checks if we are using a global or local replacement method.Global methods are easier to deal with, so it handles those first. Thetwo currently implemented are "Replace Random in the Full Population" (massaction) and "Replace Oldest in the Full Population" (a la Tierra).The first of these simply requests a random number and returns the corresponding cell. The second uses the reaper_queue, discussed earlier, toreturn the ID of the last cell in it.<p>The remainder of this method deals with the local replacement methodsWe create a list of population cells (initially empty) called<font color="#000088">found_list</font> as a place to contain the cells thatare good candidates for replacement. We then create a second list called<font color="#000088">conn_list</font> that contains all of the cells thatthe current cell is connected to. We run this connection list through amethod called <font color="#008800">FindEmptyCell</font>() to see if outjob is going to be easy -- if there are any empty cells, they should alwaysbe our first choice for replacement.<p>Alas, if there are no empty cells, we need to do some more work, and wehave a collection of options that can be chosen by the user in the genesisfile. We select the appropriate case, and use it to fill out the found_list.Currently, in all cases except "Find Empty" there will always be at least onecell placed in the found_list.<p>If the found list ends with more than one candidate cell in it, the one usedis selected randomly from the options available.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -