1 /*
2 * cPhenotype.cc
3 * Avida
4 *
5 * Called "phenotype.cc" prior to 12/5/05.
6 * Copyright 1999-2011 Michigan State University. All rights reserved.
7 * Copyright 1993-2003 California Institute of Technology.
8 *
9 *
10 * This file is part of Avida.
11 *
12 * Avida is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License
13 * as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
14 *
15 * Avida is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public License along with Avida.
19 * If not, see <http://www.gnu.org/licenses/>.
20 *
21 */
22
23 #include "cPhenotype.h"
24 #include "cContextPhenotype.h"
25 #include "cEnvironment.h"
26 #include "cDeme.h"
27 #include "cOrganism.h"
28 #include "cReactionResult.h"
29 #include "cTaskState.h"
30 #include "cWorld.h"
31 #include "tList.h"
32
33 #include <fstream>
34
35 using namespace std;
36
37
cPhenotype(cWorld * world,int parent_generation,int num_nops)38 cPhenotype::cPhenotype(cWorld* world, int parent_generation, int num_nops)
39 : m_world(world)
40 , initialized(false)
41 , energy_store(0.0)
42 , cur_task_count(m_world->GetEnvironment().GetNumTasks())
43 , cur_para_tasks(m_world->GetEnvironment().GetNumTasks())
44 , cur_host_tasks(m_world->GetEnvironment().GetNumTasks())
45 , cur_internal_task_count(m_world->GetEnvironment().GetNumTasks())
46 , eff_task_count(m_world->GetEnvironment().GetNumTasks())
47 , cur_task_quality(m_world->GetEnvironment().GetNumTasks())
48 , cur_task_value(m_world->GetEnvironment().GetNumTasks())
49 , cur_internal_task_quality(m_world->GetEnvironment().GetNumTasks())
50 , cur_rbins_total(m_world->GetEnvironment().GetResourceLib().GetSize())
51 , cur_rbins_avail(m_world->GetEnvironment().GetResourceLib().GetSize())
52 , cur_reaction_count(m_world->GetEnvironment().GetReactionLib().GetSize())
53 , first_reaction_cycles(m_world->GetEnvironment().GetReactionLib().GetSize())
54 , first_reaction_execs(m_world->GetEnvironment().GetReactionLib().GetSize())
55 , cur_stolen_reaction_count(m_world->GetEnvironment().GetReactionLib().GetSize())
56 , cur_reaction_add_reward(m_world->GetEnvironment().GetReactionLib().GetSize())
57 , cur_sense_count(m_world->GetStats().GetSenseSize())
58 , sensed_resources(m_world->GetEnvironment().GetResourceLib().GetSize())
59 , cur_task_time(m_world->GetEnvironment().GetNumTasks()) // Added for tracking time; WRE 03-18-07
60 , m_tolerance_immigrants()
61 , m_tolerance_offspring_own()
62 , m_tolerance_offspring_others()
63 , m_intolerances((m_world->GetConfig().TOLERANCE_VARIATIONS.Get() > 0) ? 1 : 3)
64 , mating_type(MATING_TYPE_JUVENILE)
65 , mate_preference(MATE_PREFERENCE_RANDOM)
66 , cur_mating_display_a(0)
67 , cur_mating_display_b(0)
68 , m_reaction_result(NULL)
69 , last_task_count(m_world->GetEnvironment().GetNumTasks())
70 , last_para_tasks(m_world->GetEnvironment().GetNumTasks())
71 , last_host_tasks(m_world->GetEnvironment().GetNumTasks())
72 , last_internal_task_count(m_world->GetEnvironment().GetNumTasks())
73 , last_task_quality(m_world->GetEnvironment().GetNumTasks())
74 , last_task_value(m_world->GetEnvironment().GetNumTasks())
75 , last_internal_task_quality(m_world->GetEnvironment().GetNumTasks())
76 , last_rbins_total(m_world->GetEnvironment().GetResourceLib().GetSize())
77 , last_rbins_avail(m_world->GetEnvironment().GetResourceLib().GetSize())
78 , last_collect_spec_counts()
79 , last_reaction_count(m_world->GetEnvironment().GetReactionLib().GetSize())
80 , last_reaction_add_reward(m_world->GetEnvironment().GetReactionLib().GetSize())
81 , last_sense_count(m_world->GetStats().GetSenseSize())
82 , last_mating_display_a(0)
83 , last_mating_display_b(0)
84 , generation(0)
85 , birth_cell_id(0)
86 , birth_group_id(0)
87 , birth_forager_type(-1)
88 , last_task_id(-1)
89 , num_new_unique_reactions(0)
90 , res_consumed(0)
91 , is_germ_cell(m_world->GetConfig().DEMES_ORGS_START_IN_GERM.Get())
92 , last_task_time(0)
93
94 {
95 if (parent_generation >= 0) {
96 generation = parent_generation;
97 if (m_world->GetConfig().GENERATION_INC_METHOD.Get() != GENERATION_INC_BOTH) generation++;
98 }
99
100 double num_resources = m_world->GetEnvironment().GetResourceLib().GetSize();
101 if (num_resources <= 0 || num_nops <= 0) return;
102 double most_nops_needed = ceil(log(num_resources) / log((double)num_nops));
103 cur_collect_spec_counts.Resize(int((pow((double)num_nops, most_nops_needed + 1.0) - 1.0) / ((double)num_nops - 1.0)));
104 }
105
~cPhenotype()106 cPhenotype::~cPhenotype()
107 {
108 // Remove Task States
109 tArray<cTaskState*> task_states(0);
110 m_task_states.GetValues(task_states);
111 for (int i = 0; i < task_states.GetSize(); i++) delete task_states[i];
112 delete m_reaction_result;
113 }
114
115
cPhenotype(const cPhenotype & in_phen)116 cPhenotype::cPhenotype(const cPhenotype& in_phen) : m_reaction_result(NULL)
117 {
118 *this = in_phen;
119 }
120
121
operator =(const cPhenotype & in_phen)122 cPhenotype& cPhenotype::operator=(const cPhenotype& in_phen)
123 {
124
125 m_world = in_phen.m_world;
126 initialized = in_phen.initialized;
127
128
129 // 1. These are values calculated at the last divide (of self or offspring)
130 merit = in_phen.merit;
131 executionRatio = in_phen.executionRatio;
132 energy_store = in_phen.energy_store;
133 energy_tobe_applied = in_phen.energy_tobe_applied;
134 energy_testament = in_phen.energy_testament;
135 energy_received_buffer = in_phen.energy_received_buffer;
136 genome_length = in_phen.genome_length;
137 bonus_instruction_count = in_phen.bonus_instruction_count;
138 copied_size = in_phen.copied_size;
139 executed_size = in_phen.executed_size;
140 gestation_time = in_phen.gestation_time;
141
142 gestation_start = in_phen.gestation_start;
143 fitness = in_phen.fitness;
144 div_type = in_phen.div_type;
145
146 // 2. These are "in progress" variables, updated as the organism operates
147 cur_bonus = in_phen.cur_bonus;
148 cur_energy_bonus = in_phen.cur_energy_bonus;
149 cur_num_errors = in_phen.cur_num_errors;
150 cur_num_donates = in_phen.cur_num_donates;
151 cur_task_count = in_phen.cur_task_count;
152 cur_para_tasks = in_phen.cur_para_tasks;
153 cur_host_tasks = in_phen.cur_host_tasks;
154 eff_task_count = in_phen.eff_task_count;
155 cur_internal_task_count = in_phen.cur_internal_task_count;
156 cur_task_quality = in_phen.cur_task_quality;
157 cur_internal_task_quality= in_phen.cur_internal_task_quality;
158 cur_task_value = in_phen.cur_task_value;
159 cur_rbins_total = in_phen.cur_rbins_total;
160 cur_rbins_avail = in_phen.cur_rbins_avail;
161 cur_collect_spec_counts = in_phen.cur_collect_spec_counts;
162 cur_reaction_count = in_phen.cur_reaction_count;
163 first_reaction_cycles = in_phen.first_reaction_cycles;
164 first_reaction_execs = first_reaction_execs;
165 cur_reaction_add_reward = in_phen.cur_reaction_add_reward;
166 cur_inst_count = in_phen.cur_inst_count;
167 cur_sense_count = in_phen.cur_sense_count;
168 sensed_resources = in_phen.sensed_resources;
169 cur_task_time = in_phen.cur_task_time;
170 m_tolerance_immigrants = in_phen.m_tolerance_immigrants;
171 m_tolerance_offspring_own = in_phen.m_tolerance_offspring_own;
172 m_tolerance_offspring_others = in_phen.m_tolerance_offspring_others;
173 m_intolerances = in_phen.m_intolerances;
174 cur_child_germline_propensity = in_phen.cur_child_germline_propensity;
175 cur_stolen_reaction_count = in_phen.cur_stolen_reaction_count;
176 mating_type = in_phen.mating_type; //@CHC
177 mate_preference = in_phen.mate_preference; //@CHC
178 cur_mating_display_a = in_phen.cur_mating_display_a;
179 cur_mating_display_b = in_phen.cur_mating_display_b;
180 last_mating_display_a = in_phen.last_mating_display_a;
181 last_mating_display_b = in_phen.last_mating_display_b;
182
183 // Dynamically allocated m_task_states requires special handling
184 tList<cTaskState*> hash_values;
185 tList<void*> hash_keys;
186 in_phen.m_task_states.AsLists(hash_keys, hash_values);
187 tListIterator<cTaskState*> vit(hash_values);
188 tListIterator<void*> kit(hash_keys);
189 while(vit.Next() && kit.Next())
190 {
191 cTaskState* new_ts = new cTaskState(**(vit.Get()));
192 m_task_states.Set(*(kit.Get()), new_ts);
193 }
194
195 // 3. These mark the status of "in progess" variables at the last divide.
196 last_merit_base = in_phen.last_merit_base;
197 last_bonus = in_phen.last_bonus;
198 last_energy_bonus = in_phen.last_energy_bonus;
199 last_num_errors = in_phen.last_num_errors;
200 last_num_donates = in_phen.last_num_donates;
201 last_task_count = in_phen.last_task_count;
202 last_host_tasks = in_phen.last_host_tasks;
203 last_para_tasks = in_phen.last_para_tasks;
204 last_internal_task_count = in_phen.last_internal_task_count;
205 last_task_quality = in_phen.last_task_quality;
206 last_internal_task_quality=in_phen.last_internal_task_quality;
207 last_task_value = in_phen.last_task_value;
208 last_rbins_total = in_phen.last_rbins_total;
209 last_rbins_avail = in_phen.last_rbins_avail;
210 last_collect_spec_counts = in_phen.last_collect_spec_counts;
211 last_reaction_count = in_phen.last_reaction_count;
212 last_reaction_add_reward = in_phen.last_reaction_add_reward;
213 last_inst_count = in_phen.last_inst_count;
214 last_sense_count = in_phen.last_sense_count;
215 last_fitness = in_phen.last_fitness;
216 last_child_germline_propensity = in_phen.last_child_germline_propensity;
217 total_energy_donated = in_phen.total_energy_donated;
218 total_energy_received = in_phen.total_energy_received;
219 total_energy_applied = in_phen.total_energy_applied;
220
221 // 4. Records from this organisms life...
222 num_divides = in_phen.num_divides;
223 num_divides_failed = in_phen.num_divides_failed;
224 generation = in_phen.generation;
225 cpu_cycles_used = in_phen.cpu_cycles_used;
226 time_used = in_phen.time_used;
227 num_execs = in_phen.num_execs;
228 age = in_phen.age;
229 fault_desc = in_phen.fault_desc;
230 neutral_metric = in_phen.neutral_metric;
231 life_fitness = in_phen.life_fitness;
232 exec_time_born = in_phen.exec_time_born;
233 birth_update = in_phen.birth_update;
234 num_new_unique_reactions = in_phen.num_new_unique_reactions;
235 last_task_id = in_phen.last_task_id;
236 last_task_time = in_phen.last_task_time;
237 res_consumed = in_phen.res_consumed;
238 is_germ_cell = in_phen.is_germ_cell;
239
240 // 5. Status Flags... (updated at each divide)
241 to_die = in_phen.to_die;
242 to_delete = in_phen.to_delete;
243 is_injected = in_phen.is_injected;
244 is_donor_cur = in_phen.is_donor_cur;
245 is_donor_last = in_phen.is_donor_last;
246 is_donor_rand = in_phen.is_donor_rand;
247 is_donor_rand_last = in_phen.is_donor_rand_last;
248 is_donor_null = in_phen.is_donor_null;
249 is_donor_null_last = in_phen.is_donor_null_last;
250 is_donor_kin = in_phen.is_donor_kin;
251 is_donor_kin_last = in_phen.is_donor_kin_last;
252 is_donor_edit = in_phen.is_donor_edit;
253 is_donor_edit_last = in_phen.is_donor_edit_last;
254 is_donor_gbg = in_phen.is_donor_gbg;
255 is_donor_gbg_last = in_phen.is_donor_gbg_last;
256 is_donor_truegb = in_phen.is_donor_truegb;
257 is_donor_truegb_last = in_phen.is_donor_truegb_last;
258 is_donor_threshgb = in_phen.is_donor_threshgb;
259 is_donor_threshgb_last = in_phen.is_donor_threshgb_last;
260 is_donor_quanta_threshgb = in_phen.is_donor_quanta_threshgb;
261 is_donor_quanta_threshgb_last = in_phen.is_donor_quanta_threshgb_last;
262 is_donor_shadedgb = in_phen.is_donor_shadedgb;
263 is_donor_shadedgb_last = in_phen.is_donor_shadedgb_last;
264 is_donor_locus = in_phen.is_donor_locus;
265 is_donor_locus_last = in_phen.is_donor_locus_last;
266 num_thresh_gb_donations = in_phen.num_thresh_gb_donations;
267 num_thresh_gb_donations_last = in_phen.num_thresh_gb_donations_last;
268 num_quanta_thresh_gb_donations = in_phen.num_quanta_thresh_gb_donations;
269 num_quanta_thresh_gb_donations_last = in_phen.num_quanta_thresh_gb_donations_last;
270 num_shaded_gb_donations = in_phen.num_shaded_gb_donations;
271 num_shaded_gb_donations_last = in_phen.num_shaded_gb_donations_last;
272 num_donations_locus = in_phen.num_donations_locus;
273 num_donations_locus_last = in_phen.num_donations_locus_last;
274 is_receiver = in_phen.is_receiver;
275 is_receiver_last = in_phen.is_receiver_last;
276 is_receiver_rand = in_phen.is_receiver_rand;
277 is_receiver_kin = in_phen.is_receiver_kin;
278 is_receiver_kin_last = in_phen.is_receiver_kin_last;
279 is_receiver_edit = in_phen.is_receiver_edit;
280 is_receiver_edit_last = in_phen.is_receiver_edit_last;
281 is_receiver_gbg = in_phen.is_receiver_gbg;
282 is_receiver_truegb = in_phen.is_receiver_truegb;
283 is_receiver_truegb_last = in_phen.is_receiver_truegb_last;
284 is_receiver_threshgb = in_phen.is_receiver_threshgb;
285 is_receiver_threshgb_last = in_phen.is_receiver_threshgb_last;
286 is_receiver_quanta_threshgb = in_phen.is_receiver_quanta_threshgb;
287 is_receiver_quanta_threshgb_last = in_phen.is_receiver_quanta_threshgb_last;
288 is_receiver_shadedgb = in_phen.is_receiver_shadedgb;
289 is_receiver_shadedgb_last = in_phen.is_receiver_shadedgb_last;
290 is_receiver_gb_same_locus = in_phen.is_receiver_gb_same_locus;
291 is_receiver_gb_same_locus_last = in_phen.is_receiver_gb_same_locus_last;
292 is_modifier = in_phen.is_modifier;
293 is_modified = in_phen.is_modified;
294 is_fertile = in_phen.is_fertile;
295 is_mutated = in_phen.is_mutated;
296 is_multi_thread = in_phen.is_multi_thread;
297 parent_true = in_phen.parent_true;
298 parent_sex = in_phen.parent_sex;
299 parent_cross_num = in_phen.parent_cross_num;
300
301 is_energy_requestor = in_phen.is_energy_requestor;
302 is_energy_donor = in_phen.is_energy_donor;
303 is_energy_receiver = in_phen.is_energy_receiver;
304 has_used_donated_energy = in_phen.has_used_donated_energy;
305 has_open_energy_request = in_phen.has_open_energy_request;
306 total_energy_donated = in_phen.total_energy_donated;
307 total_energy_received = in_phen.total_energy_received;
308 total_energy_applied = in_phen.total_energy_applied;
309
310 // 6. Child information...
311 copy_true = in_phen.copy_true;
312 divide_sex = in_phen.divide_sex;
313 mate_select_id = in_phen.mate_select_id;
314 cross_num = in_phen.cross_num;
315 child_fertile = in_phen.child_fertile;
316 last_child_fertile = in_phen.last_child_fertile;
317 child_copied_size = in_phen.child_copied_size;
318
319 // 7. Permanent information...
320 permanent_germline_propensity = in_phen.permanent_germline_propensity;
321
322 return *this;
323 }
324
325
326 /**
327 * This function is run whenever a new organism is being constructed inside
328 * of its parent.
329 *
330 * Assumptions:
331 * - parent_phenotype has had DivideReset run on it already!
332 * - this is the first method run on an otherwise freshly built phenotype.
333 **/
334
SetupOffspring(const cPhenotype & parent_phenotype,const Sequence & _genome)335 void cPhenotype::SetupOffspring(const cPhenotype& parent_phenotype, const Sequence& _genome)
336 {
337 // Copy divide values from parent, which should already be setup.
338 merit = parent_phenotype.merit;
339 if(m_world->GetConfig().INHERIT_EXE_RATE.Get() == 0)
340 executionRatio = 1.0;
341 else
342 executionRatio = parent_phenotype.executionRatio;
343
344 energy_store = min(energy_store, m_world->GetConfig().ENERGY_CAP.Get());
345 energy_tobe_applied = 0.0;
346 energy_testament = 0.0;
347 energy_received_buffer = 0.0;
348 genome_length = _genome.GetSize();
349 copied_size = parent_phenotype.child_copied_size;
350 executed_size = parent_phenotype.executed_size;
351
352 gestation_time = parent_phenotype.gestation_time;
353 gestation_start = 0;
354 cpu_cycles_used = 0;
355 fitness = parent_phenotype.fitness;
356 div_type = parent_phenotype.div_type;
357
358 assert(genome_length > 0);
359 assert(copied_size > 0);
360 assert(gestation_time >= 0); //@JEB 0 valid for some fitness methods
361 assert(div_type > 0);
362
363 // Initialize current values, as neeeded.
364 cur_bonus = m_world->GetConfig().DEFAULT_BONUS.Get();
365 cur_energy_bonus = 0.0;
366 cur_num_errors = 0;
367 cur_num_donates = 0;
368 cur_task_count.SetAll(0);
369 cur_internal_task_count.SetAll(0);
370 eff_task_count.SetAll(0);
371 cur_host_tasks.SetAll(0);
372 cur_para_tasks.SetAll(0);
373 cur_task_quality.SetAll(0);
374 cur_task_value.SetAll(0);
375 cur_internal_task_quality.SetAll(0);
376 cur_rbins_total.SetAll(0); // total resources collected in lifetime
377 // parent's resources have already been halved or reset in DivideReset;
378 // offspring gets that value (half or 0) too.
379 cur_rbins_avail.SetAll(0);
380 for (int i = 0; i < cur_rbins_avail.GetSize(); i++) {
381 const int resource = m_world->GetConfig().COLLECT_SPECIFIC_RESOURCE.Get();
382 if (m_world->GetConfig().RESOURCE_GIVEN_AT_BIRTH.Get() > 0.0) {
383 cur_rbins_avail[resource] = m_world->GetConfig().RESOURCE_GIVEN_AT_BIRTH.Get();
384 }
385 if (m_world->GetConfig().SPLIT_ON_DIVIDE.Get()) {
386 cur_rbins_avail[i] = parent_phenotype.cur_rbins_avail[i];
387 cur_rbins_avail[resource] = cur_rbins_avail[resource] + m_world->GetConfig().RESOURCE_GIVEN_AT_BIRTH.Get();
388 }
389 }
390 cur_collect_spec_counts.SetAll(0);
391 cur_reaction_count.SetAll(0);
392 first_reaction_cycles.SetAll(-1);
393 first_reaction_execs.SetAll(-1);
394 cur_stolen_reaction_count.SetAll(0);
395 cur_reaction_add_reward.SetAll(0);
396 cur_inst_count.SetAll(0);
397 cur_sense_count.SetAll(0);
398 cur_task_time.SetAll(0.0); // Added for time tracking; WRE 03-18-07
399 for (int j = 0; j < sensed_resources.GetSize(); j++) {
400 sensed_resources[j] = parent_phenotype.sensed_resources[j];
401 }
402 cur_trial_fitnesses.Resize(0);
403 cur_trial_bonuses.Resize(0);
404 cur_trial_times_used.Resize(0);
405 trial_time_used = 0;
406 trial_cpu_cycles_used = 0;
407 m_tolerance_immigrants.Clear();
408 m_tolerance_offspring_own.Clear();
409 m_tolerance_offspring_others.Clear();
410 m_intolerances.SetAll(make_pair(-1, -1));
411 cur_child_germline_propensity = m_world->GetConfig().DEMES_DEFAULT_GERMLINE_PROPENSITY.Get();
412 mating_type = MATING_TYPE_JUVENILE; //@CHC
413 mate_preference = MATE_PREFERENCE_RANDOM; //@CHC
414
415 cur_mating_display_a = 0;
416 cur_mating_display_b = 0;
417 last_mating_display_a = 0;
418 last_mating_display_b = 0;
419
420 // Copy last values from parent
421 last_merit_base = parent_phenotype.last_merit_base;
422 last_bonus = parent_phenotype.last_bonus;
423 last_cpu_cycles_used = parent_phenotype.last_cpu_cycles_used;
424 last_num_errors = parent_phenotype.last_num_errors;
425 last_num_donates = parent_phenotype.last_num_donates;
426 last_task_count = parent_phenotype.last_task_count;
427 last_host_tasks = parent_phenotype.last_host_tasks;
428 last_para_tasks = parent_phenotype.last_para_tasks;
429 last_internal_task_count = parent_phenotype.last_internal_task_count;
430 last_task_quality = parent_phenotype.last_task_quality;
431 last_task_value = parent_phenotype.last_task_value;
432 last_internal_task_quality= parent_phenotype.last_internal_task_quality;
433 last_rbins_total = parent_phenotype.last_rbins_total;
434 last_rbins_avail = parent_phenotype.last_rbins_avail;
435 last_collect_spec_counts = parent_phenotype.last_collect_spec_counts;
436 last_reaction_count = parent_phenotype.last_reaction_count;
437 last_reaction_add_reward = parent_phenotype.last_reaction_add_reward;
438 last_inst_count = parent_phenotype.last_inst_count;
439 last_sense_count = parent_phenotype.last_sense_count;
440 last_fitness = CalcFitness(last_merit_base, last_bonus, gestation_time, last_cpu_cycles_used);
441 last_child_germline_propensity = parent_phenotype.last_child_germline_propensity; // chance of child being a germline cell; @JEB
442
443 // Setup other miscellaneous values...
444 num_divides = 0;
445 num_divides_failed = 0;
446 generation = parent_phenotype.generation;
447 if (m_world->GetConfig().GENERATION_INC_METHOD.Get() != GENERATION_INC_BOTH) generation++;
448 cpu_cycles_used = 0;
449 time_used = 0;
450 num_execs = 0;
451 age = 0;
452 fault_desc = "";
453 neutral_metric = parent_phenotype.neutral_metric + m_world->GetRandom().GetRandNormal();
454 life_fitness = fitness;
455 exec_time_born = parent_phenotype.exec_time_born; //@MRR treating offspring and parent as siblings; already set in DivideReset
456 birth_update = parent_phenotype.birth_update;
457 num_new_unique_reactions = 0;
458 last_task_id = -1;
459 res_consumed = 0;
460 is_germ_cell = parent_phenotype.is_germ_cell;
461 last_task_time = 0;
462
463 num_thresh_gb_donations = 0;
464 num_thresh_gb_donations_last = parent_phenotype.num_thresh_gb_donations_last;
465 num_quanta_thresh_gb_donations = 0;
466 num_quanta_thresh_gb_donations_last = parent_phenotype.num_thresh_gb_donations_last;
467 num_shaded_gb_donations = 0;
468 num_shaded_gb_donations_last = parent_phenotype.num_shaded_gb_donations_last;
469 num_donations_locus = 0;
470 num_donations_locus_last = parent_phenotype.num_donations_locus_last;
471
472
473 // Setup flags...
474 is_injected = false;
475 is_donor_cur = false;
476 is_donor_last = parent_phenotype.is_donor_last;
477 is_donor_rand = false;
478 is_donor_rand_last = parent_phenotype.is_donor_rand_last;
479 is_donor_null = false;
480 is_donor_null_last = parent_phenotype.is_donor_null_last;
481 is_donor_kin = false;
482 is_donor_kin_last = parent_phenotype.is_donor_kin_last;
483 is_donor_edit = false;
484 is_donor_edit_last = parent_phenotype.is_donor_edit_last;
485 is_donor_gbg = false;
486 is_donor_gbg_last = parent_phenotype.is_donor_gbg_last;
487 is_donor_truegb = false;
488 is_donor_truegb_last = parent_phenotype.is_donor_truegb_last;
489 is_donor_threshgb = false;
490 is_donor_threshgb_last = parent_phenotype.is_donor_threshgb_last;
491 is_donor_quanta_threshgb = false;
492 is_donor_quanta_threshgb_last = parent_phenotype.is_donor_quanta_threshgb_last;
493 is_donor_shadedgb = false;
494 is_donor_shadedgb_last = parent_phenotype.is_donor_shadedgb_last;
495 is_donor_locus.SetAll(false);
496 is_donor_locus_last = parent_phenotype.is_donor_locus_last;
497
498 is_receiver = false;
499 is_receiver_last = parent_phenotype.is_receiver_last;
500 is_receiver_rand = false;
501 is_receiver_kin = false;
502 is_receiver_kin_last = parent_phenotype.is_receiver_kin_last;
503 is_receiver_edit = false;
504 is_receiver_edit_last = parent_phenotype.is_receiver_edit_last;
505 is_receiver_gbg = false;
506 is_receiver_truegb = false;
507 is_receiver_truegb_last = parent_phenotype.is_receiver_truegb_last;
508 is_receiver_threshgb = false;
509 is_receiver_threshgb_last = parent_phenotype.is_receiver_threshgb_last;
510 is_receiver_quanta_threshgb = false;
511 is_receiver_quanta_threshgb_last = parent_phenotype.is_receiver_quanta_threshgb_last;
512 is_receiver_shadedgb = false;
513 is_receiver_shadedgb_last = parent_phenotype.is_receiver_shadedgb_last;
514 is_receiver_gb_same_locus = false;
515 is_receiver_gb_same_locus_last = parent_phenotype.is_receiver_gb_same_locus;
516
517 is_modifier = false;
518 is_modified = false;
519 is_fertile = parent_phenotype.last_child_fertile;
520 is_mutated = false;
521 if (m_world->GetConfig().INHERIT_MULTITHREAD.Get()) {
522 is_multi_thread = parent_phenotype.is_multi_thread;
523 } else {
524 is_multi_thread = false;
525 }
526
527 parent_true = parent_phenotype.copy_true;
528 parent_sex = parent_phenotype.divide_sex;
529 parent_cross_num = parent_phenotype.cross_num;
530 to_die = false;
531 to_delete = false;
532
533 is_energy_requestor = false;
534 is_energy_donor = false;
535 is_energy_receiver = false;
536 has_used_donated_energy = false;
537 has_open_energy_request = false;
538 total_energy_donated = 0.0;
539 total_energy_received = 0.0;
540 total_energy_applied = 0.0;
541
542 // Setup child info...
543 copy_true = false;
544 divide_sex = false;
545 mate_select_id = -1;
546 cross_num = 0;
547 last_child_fertile = is_fertile;
548 child_fertile = true;
549 child_copied_size = 0;
550
551 // permanently set germline propensity of org (since DivideReset is called first, it is now in the "last" slot...)
552 permanent_germline_propensity = parent_phenotype.last_child_germline_propensity;
553
554 initialized = true;
555 }
556
557
558 /**
559 * This function is run whenever a new organism is being constructed via
560 * some form of injection into the population, or in a test environment.
561 *
562 * Assumptions:
563 * - Updates to these values (i.e. resetting of merit) will occur afterward
564 * - This is the first method run on an otherwise freshly built phenotype.
565 **/
566
SetupInject(const Sequence & _genome)567 void cPhenotype::SetupInject(const Sequence& _genome)
568 {
569 // Setup reasonable initial values injected organism...
570 genome_length = _genome.GetSize();
571 merit = genome_length;
572 copied_size = genome_length;
573 executed_size = genome_length;
574 energy_store = min(m_world->GetConfig().ENERGY_GIVEN_ON_INJECT.Get(), m_world->GetConfig().ENERGY_CAP.Get());
575 energy_tobe_applied = 0.0;
576 energy_testament = 0.0;
577 energy_received_buffer = 0.0;
578 executionRatio = 1.0;
579 gestation_time = 0;
580 gestation_start = 0;
581 fitness = 0;
582 div_type = 1;
583
584 // Initialize current values, as neeeded.
585 cur_bonus = m_world->GetConfig().DEFAULT_BONUS.Get();
586 cur_energy_bonus = 0.0;
587 cur_num_errors = 0;
588 cur_num_donates = 0;
589 cur_task_count.SetAll(0);
590 cur_para_tasks.SetAll(0);
591 cur_host_tasks.SetAll(0);
592 cur_internal_task_count.SetAll(0);
593 eff_task_count.SetAll(0);
594 cur_task_quality.SetAll(0);
595 cur_task_value.SetAll(0);
596 cur_internal_task_quality.SetAll(0);
597 cur_rbins_total.SetAll(0);
598 if (m_world->GetConfig().RESOURCE_GIVEN_ON_INJECT.Get() > 0.0) {
599 const int resource = m_world->GetConfig().COLLECT_SPECIFIC_RESOURCE.Get();
600 cur_rbins_avail[resource] = m_world->GetConfig().RESOURCE_GIVEN_ON_INJECT.Get();
601 }
602 else cur_rbins_avail.SetAll(0);
603 cur_collect_spec_counts.SetAll(0);
604 cur_reaction_count.SetAll(0);
605 first_reaction_cycles.SetAll(-1);
606 first_reaction_execs.SetAll(-1);
607 cur_stolen_reaction_count.SetAll(0);
608 cur_reaction_add_reward.SetAll(0);
609 cur_inst_count.SetAll(0);
610 sensed_resources.SetAll(0);
611 cur_sense_count.SetAll(0);
612 cur_task_time.SetAll(0.0);
613 cur_trial_fitnesses.Resize(0);
614 cur_trial_bonuses.Resize(0);
615 cur_trial_times_used.Resize(0);
616 trial_time_used = 0;
617 trial_cpu_cycles_used = 0;
618 m_tolerance_immigrants.Clear();
619 m_tolerance_offspring_own.Clear();
620 m_tolerance_offspring_others.Clear();
621 m_intolerances.SetAll(make_pair(-1, -1));
622 cur_child_germline_propensity = m_world->GetConfig().DEMES_DEFAULT_GERMLINE_PROPENSITY.Get();
623 mating_type = MATING_TYPE_JUVENILE; // @CHC
624 mate_preference = MATE_PREFERENCE_RANDOM; //@CHC
625
626 // New organism has no parent and so cannot use its last values; initialize as needed
627 last_merit_base = genome_length;
628 last_bonus = 1;
629 last_cpu_cycles_used = 0;
630 last_num_errors = 0;
631 last_num_donates = 0;
632 last_task_count.SetAll(0);
633 last_host_tasks.SetAll(0);
634 last_para_tasks.SetAll(0);
635 last_internal_task_count.SetAll(0);
636 last_task_quality.SetAll(0);
637 last_task_value.SetAll(0);
638 last_internal_task_quality.SetAll(0);
639 last_rbins_total.SetAll(0);
640 last_rbins_avail.SetAll(0);
641 last_collect_spec_counts.SetAll(0);
642 last_reaction_count.SetAll(0);
643 last_reaction_add_reward.SetAll(0);
644 last_inst_count.SetAll(0);
645 last_sense_count.SetAll(0);
646 last_child_germline_propensity = m_world->GetConfig().DEMES_DEFAULT_GERMLINE_PROPENSITY.Get();
647
648 // Setup other miscellaneous values...
649 num_divides = 0;
650 num_divides_failed = 0;
651 generation = 0;
652 cpu_cycles_used = 0;
653 time_used = 0;
654 num_execs = 0;
655 age = 0;
656 fault_desc = "";
657 neutral_metric = 0;
658 life_fitness = 0;
659 exec_time_born = 0;
660 birth_update = m_world->GetStats().GetUpdate();
661
662 num_thresh_gb_donations = 0;
663 num_thresh_gb_donations_last = 0;
664 num_quanta_thresh_gb_donations = 0;
665 num_quanta_thresh_gb_donations_last = 0;
666 num_shaded_gb_donations = 0;
667 num_shaded_gb_donations_last = 0;
668 num_donations_locus = 0;
669 num_donations_locus_last = 0;
670
671 // Setup flags...
672 is_injected = true;
673 is_donor_last = false;
674 is_donor_cur = false;
675 is_donor_rand = false;
676 is_donor_rand_last = false;
677 is_donor_null = false;
678 is_donor_null_last = false;
679 is_donor_kin = false;
680 is_donor_kin_last = false;
681 is_donor_edit = false;
682 is_donor_edit_last = false;
683 is_donor_gbg = false;
684 is_donor_gbg_last = false;
685 is_donor_truegb = false;
686 is_donor_truegb_last = false;
687 is_donor_threshgb = false;
688 is_donor_threshgb_last = false;
689 is_donor_quanta_threshgb = false;
690 is_donor_quanta_threshgb_last = false;
691 is_donor_shadedgb = false;
692 is_donor_shadedgb_last = false;
693 is_donor_locus.SetAll(false);
694 is_donor_locus_last.SetAll(false);
695
696 is_receiver = false;
697 is_receiver_last = false;
698 is_receiver_rand = false;
699 is_receiver_kin = false;
700 is_receiver_kin_last = false;
701 is_receiver_edit = false;
702 is_receiver_edit_last = false;
703 is_receiver_gbg = false;
704 is_receiver_truegb = false;
705 is_receiver_truegb_last = false;
706 is_receiver_threshgb = false;
707 is_receiver_threshgb_last = false;
708 is_receiver_quanta_threshgb = false;
709 is_receiver_quanta_threshgb_last = false;
710 is_receiver_shadedgb = false;
711 is_receiver_shadedgb_last = false;
712 is_receiver_gb_same_locus = false;
713 is_receiver_gb_same_locus_last = false;
714
715 is_modifier = false;
716 is_modified = false;
717 is_fertile = true;
718 is_mutated = false;
719 is_multi_thread = false;
720 parent_true = true;
721 parent_sex = false;
722 parent_cross_num = 0;
723 to_die = false;
724 to_delete = false;
725
726 is_energy_requestor = false;
727 is_energy_donor = false;
728 is_energy_receiver = false;
729 has_used_donated_energy = false;
730 has_open_energy_request = false;
731 total_energy_donated = 0.0;
732 total_energy_received = 0.0;
733 total_energy_applied = 0.0;
734
735 // Setup child info...
736 copy_true = false;
737 divide_sex = false;
738 mate_select_id = -1;
739 cross_num = 0;
740 child_fertile = true;
741 last_child_fertile = true;
742 child_copied_size = 0;
743
744 permanent_germline_propensity = m_world->GetConfig().DEMES_DEFAULT_GERMLINE_PROPENSITY.Get();
745
746 initialized = true;
747 }
748
749
ResetMerit(const Sequence & _cgenome)750 void cPhenotype::ResetMerit(const Sequence & _cgenome)
751 {
752 int cur_merit_base = CalcSizeMerit();
753 const int merit_default_bonus = m_world->GetConfig().MERIT_DEFAULT_BONUS.Get();
754 if (merit_default_bonus) {
755 cur_bonus = merit_default_bonus;
756 }
757 merit = cur_merit_base * cur_bonus;
758
759 if (m_world->GetConfig().INHERIT_MERIT.Get() == 0) {
760 merit = cur_merit_base;
761 }
762 }
763
764
765 /**
766 * This function is run whenever an organism executes a successful divide.
767 **/
768
DivideReset(const Sequence & _genome)769 void cPhenotype::DivideReset(const Sequence& _genome)
770 {
771 assert(time_used >= 0);
772 assert(initialized == true);
773
774 // Update these values as needed...
775 int cur_merit_base = CalcSizeMerit();
776
777 // If we are resetting the current merit, do it here
778 // and it will also be propagated to the child
779 const int merit_default_bonus = m_world->GetConfig().MERIT_DEFAULT_BONUS.Get();
780 if (merit_default_bonus) {
781 cur_bonus = merit_default_bonus;
782 }
783 merit = cur_merit_base * cur_bonus;
784
785 if(m_world->GetConfig().INHERIT_MERIT.Get() == 0)
786 merit = cur_merit_base;
787
788 SetEnergy(energy_store + cur_energy_bonus);
789 m_world->GetStats().SumEnergyTestamentAcceptedByOrganisms().Add(energy_testament);
790 energy_testament = 0.0;
791 energy_received_buffer = 0.0; // If donated energy not applied, it's lost here
792
793 genome_length = _genome.GetSize();
794 (void) copied_size; // Unchanged
795 (void) executed_size; // Unchanged
796 gestation_time = time_used - gestation_start;
797 gestation_start = time_used;
798 fitness = CalcFitness( cur_merit_base, cur_bonus, gestation_time, cpu_cycles_used);
799
800 // Lock in cur values as last values.
801 last_merit_base = cur_merit_base;
802 last_bonus = cur_bonus;
803 last_cpu_cycles_used = cpu_cycles_used;
804 //TODO? last_energy = cur_energy_bonus;
805 last_num_errors = cur_num_errors;
806 last_num_donates = cur_num_donates;
807 last_task_count = cur_task_count;
808 last_host_tasks = cur_host_tasks;
809 last_para_tasks = cur_para_tasks;
810 last_internal_task_count = cur_internal_task_count;
811 last_task_quality = cur_task_quality;
812 last_task_value = cur_task_value;
813 last_internal_task_quality= cur_internal_task_quality;
814 last_rbins_total = cur_rbins_total;
815 last_rbins_avail = cur_rbins_avail;
816 last_collect_spec_counts = cur_collect_spec_counts;
817 last_reaction_count = cur_reaction_count;
818 last_reaction_add_reward = cur_reaction_add_reward;
819 last_inst_count = cur_inst_count;
820 last_sense_count = cur_sense_count;
821 last_child_germline_propensity = cur_child_germline_propensity;
822
823 last_mating_display_a = cur_mating_display_a; //@CHC
824 last_mating_display_b = cur_mating_display_b;
825
826 // Reset cur values.
827 cur_bonus = m_world->GetConfig().DEFAULT_BONUS.Get();
828 cpu_cycles_used = 0;
829 cur_energy_bonus = 0.0;
830 cur_num_errors = 0;
831 cur_num_donates = 0;
832 cur_task_count.SetAll(0);
833 cur_host_tasks.SetAll(0);
834
835 cur_mating_display_a = 0; //@CHC
836 cur_mating_display_b = 0;
837
838 // @LZ: figure out when and where to reset cur_para_tasks, depending on the divide method, and
839 // resonable assumptions
840 if (m_world->GetConfig().DIVIDE_METHOD.Get() == DIVIDE_METHOD_SPLIT) {
841 last_para_tasks = cur_para_tasks;
842 cur_para_tasks.SetAll(0);
843 }
844 cur_internal_task_count.SetAll(0);
845 eff_task_count.SetAll(0);
846 cur_task_quality.SetAll(0);
847 cur_task_value.SetAll(0);
848 cur_internal_task_quality.SetAll(0);
849 if (m_world->GetConfig().SPLIT_ON_DIVIDE.Get()) {
850 // resources available are split in half -- the offspring gets the other half
851 for (int i = 0; i < cur_rbins_avail.GetSize(); i++) {cur_rbins_avail[i] /= 2.0;}
852 }
853 else if (m_world->GetConfig().DIVIDE_METHOD.Get() != 0) {
854 cur_rbins_avail.SetAll(0);
855 cur_rbins_total.SetAll(0); // total resources collected in lifetime
856 }
857 cur_collect_spec_counts.SetAll(0);
858 cur_reaction_count.SetAll(0);
859 first_reaction_cycles.SetAll(-1);
860 first_reaction_execs.SetAll(-1);
861 cur_stolen_reaction_count.SetAll(0);
862 cur_reaction_add_reward.SetAll(0);
863 cur_inst_count.SetAll(0);
864 cur_sense_count.SetAll(0);
865 cur_task_time.SetAll(0.0);
866 cur_child_germline_propensity = m_world->GetConfig().DEMES_DEFAULT_GERMLINE_PROPENSITY.Get();
867
868 // Setup other miscellaneous values...
869 num_divides++;
870 (void) generation;
871 (void) time_used;
872 num_execs = 0;
873 age = 0;
874 fault_desc = "";
875 (void) neutral_metric;
876 life_fitness = fitness;
877 exec_time_born += gestation_time; //@MRR Treating organism as sibling
878 birth_update = m_world->GetStats().GetUpdate();
879 num_new_unique_reactions = 0;
880 last_task_id = -1;
881 res_consumed = 0;
882 last_task_time = 0;
883
884 num_thresh_gb_donations_last = num_thresh_gb_donations;
885 num_thresh_gb_donations = 0;
886 num_quanta_thresh_gb_donations_last = num_quanta_thresh_gb_donations;
887 num_quanta_thresh_gb_donations = 0;
888 num_shaded_gb_donations_last = num_shaded_gb_donations;
889 num_shaded_gb_donations = 0;
890 num_donations_locus_last = num_donations_locus;
891 num_donations_locus = 0;
892
893 // Leave flags alone...
894 (void) is_injected;
895 is_donor_last = is_donor_cur;
896 is_donor_cur = false;
897 is_donor_rand_last = is_donor_rand;
898 is_donor_rand = false;
899 is_donor_null_last = is_donor_null;
900 is_donor_null = false;
901 is_donor_kin_last = is_donor_kin;
902 is_donor_kin = false;
903 is_donor_edit_last = is_donor_edit;
904 is_donor_edit = false;
905 is_donor_gbg_last = is_donor_gbg;
906 is_donor_gbg = false;
907 is_donor_truegb_last = is_donor_truegb;
908 is_donor_truegb = false;
909 is_donor_threshgb_last = is_donor_threshgb;
910 is_donor_threshgb = false;
911 is_donor_quanta_threshgb_last = is_donor_quanta_threshgb;
912 is_donor_quanta_threshgb = false;
913 is_donor_shadedgb_last = is_donor_shadedgb;
914 is_donor_shadedgb = false;
915 is_donor_locus_last = is_donor_locus;
916 is_donor_locus.SetAll(false);
917
918 is_receiver_last = is_receiver;
919 is_receiver = false;
920 is_receiver_rand = false;
921 is_receiver_kin_last = is_receiver_kin;
922 is_receiver_kin = false;
923 is_receiver_edit_last = is_receiver_edit;
924 is_receiver_edit = false;
925 is_receiver_gbg = false;
926 is_receiver_truegb_last = is_receiver_truegb;
927 is_receiver_truegb = false;
928 is_receiver_threshgb_last = is_receiver_threshgb;
929 is_receiver_threshgb = false;
930 is_receiver_quanta_threshgb_last = is_receiver_quanta_threshgb;
931 is_receiver_quanta_threshgb = false;
932 is_receiver_shadedgb_last = is_receiver_shadedgb;
933 is_receiver_shadedgb = false;
934 is_receiver_gb_same_locus_last = is_receiver_gb_same_locus;
935 is_receiver_gb_same_locus = false;
936
937 (void) is_modifier;
938 (void) is_modified;
939 (void) is_fertile;
940 (void) is_mutated;
941 (void) is_multi_thread;
942 (void) parent_true;
943 (void) parent_sex;
944 (void) parent_cross_num;
945
946 // Reset child info...
947 (void) copy_true;
948 (void) divide_sex;
949 (void) mate_select_id;
950 (void) cross_num;
951 last_child_fertile = child_fertile;
952 child_fertile = true;
953 (void) child_copied_size;
954
955 // A few final changes if the parent was supposed to be be considered
956 // a second child on the divide.
957 if ((m_world->GetConfig().DIVIDE_METHOD.Get() == DIVIDE_METHOD_SPLIT) ||
958 (m_world->GetConfig().DIVIDE_METHOD.Get() == DIVIDE_METHOD_BIRTH)) {
959 gestation_start = 0;
960 cpu_cycles_used = 0;
961 time_used = 0;
962 neutral_metric += m_world->GetRandom().GetRandNormal();
963 }
964
965 if (m_world->GetConfig().DIVIDE_METHOD.Get() == DIVIDE_METHOD_SPLIT) {
966 m_tolerance_immigrants.Clear();
967 m_tolerance_offspring_own.Clear();
968 m_tolerance_offspring_others.Clear();
969 m_intolerances.SetAll(make_pair(-1, -1));
970 }
971
972 if (m_world->GetConfig().GENERATION_INC_METHOD.Get() == GENERATION_INC_BOTH) generation++;
973
974 // Reset Task States
975 tArray<cTaskState*> task_states(0);
976 m_task_states.GetValues(task_states);
977 for (int i = 0; i < task_states.GetSize(); i++) delete task_states[i];
978 m_task_states.ClearAll();
979 }
980
981 /**
982 * This function runs whenever a *test* CPU divides. It processes much of
983 * the information for that CPU in order to actively reflect its executed
984 * and copied size in its merit.
985 **/
986
TestDivideReset(const Sequence & _genome)987 void cPhenotype::TestDivideReset(const Sequence& _genome)
988 {
989 assert(time_used > 0);
990 assert(initialized == true);
991
992 // Update these values as needed...
993 int cur_merit_base = CalcSizeMerit();
994 const int merit_default_bonus = m_world->GetConfig().MERIT_DEFAULT_BONUS.Get();
995 if (merit_default_bonus) {
996 cur_bonus = merit_default_bonus;
997 }
998 merit = cur_merit_base * cur_bonus;
999
1000 if (m_world->GetConfig().INHERIT_MERIT.Get() == 0) {
1001 merit = cur_merit_base;
1002 }
1003
1004 genome_length = _genome.GetSize();
1005 (void) copied_size; // Unchanged
1006 (void) executed_size; // Unchanged
1007 gestation_time = time_used - gestation_start;
1008 gestation_start = time_used;
1009 fitness = CalcFitness(cur_merit_base, cur_bonus, gestation_time, cpu_cycles_used);
1010 (void) div_type; // Unchanged
1011
1012 // Lock in cur values as last values.
1013 last_merit_base = cur_merit_base;
1014 last_bonus = cur_bonus;
1015 last_cpu_cycles_used = cpu_cycles_used;
1016 last_num_errors = cur_num_errors;
1017 last_num_donates = cur_num_donates;
1018 last_task_count = cur_task_count;
1019 last_host_tasks = cur_host_tasks;
1020 last_para_tasks = cur_para_tasks;
1021 last_internal_task_count = cur_internal_task_count;
1022 last_task_quality = cur_task_quality;
1023 last_task_value = cur_task_value;
1024 last_internal_task_quality= cur_internal_task_quality;
1025 last_rbins_total = cur_rbins_total;
1026 last_rbins_avail = cur_rbins_avail;
1027 last_collect_spec_counts = cur_collect_spec_counts;
1028 last_reaction_count = cur_reaction_count;
1029 last_reaction_add_reward = cur_reaction_add_reward;
1030 last_inst_count = cur_inst_count;
1031 last_sense_count = cur_sense_count;
1032 last_child_germline_propensity = cur_child_germline_propensity;
1033
1034 // Reset cur values.
1035 cur_bonus = m_world->GetConfig().DEFAULT_BONUS.Get();
1036 cpu_cycles_used = 0;
1037 cur_num_errors = 0;
1038 cur_num_donates = 0;
1039 cur_task_count.SetAll(0);
1040 cur_host_tasks.SetAll(0);
1041 // @LZ: figure out when and where to reset cur_para_tasks, depending on the divide method, and
1042 // resonable assumptions
1043 if (m_world->GetConfig().DIVIDE_METHOD.Get() == DIVIDE_METHOD_SPLIT) {
1044 last_para_tasks = cur_para_tasks;
1045 cur_para_tasks.SetAll(0);
1046 }
1047 cur_internal_task_count.SetAll(0);
1048 eff_task_count.SetAll(0);
1049 cur_task_quality.SetAll(0);
1050 cur_task_value.SetAll(0);
1051 cur_internal_task_quality.SetAll(0);
1052 cur_rbins_total.SetAll(0); // total resources collected in lifetime
1053 if (m_world->GetConfig().RESOURCE_GIVEN_ON_INJECT.Get() > 0.0) {
1054 const int resource = m_world->GetConfig().COLLECT_SPECIFIC_RESOURCE.Get();
1055 cur_rbins_avail[resource] = m_world->GetConfig().RESOURCE_GIVEN_ON_INJECT.Get();
1056 }
1057 else cur_rbins_avail.SetAll(0);
1058 cur_collect_spec_counts.SetAll(0);
1059 cur_reaction_count.SetAll(0);
1060 first_reaction_cycles.SetAll(-1);
1061 first_reaction_execs.SetAll(-1);
1062 cur_stolen_reaction_count.SetAll(0);
1063 cur_reaction_add_reward.SetAll(0);
1064 cur_inst_count.SetAll(0);
1065 cur_sense_count.SetAll(0);
1066 cur_task_time.SetAll(0.0);
1067 sensed_resources.SetAll(-1.0);
1068 cur_trial_fitnesses.Resize(0);
1069 cur_trial_bonuses.Resize(0);
1070 cur_trial_times_used.Resize(0);
1071 trial_time_used = 0;
1072 trial_cpu_cycles_used = 0;
1073 m_tolerance_immigrants.Clear();
1074 m_tolerance_offspring_own.Clear();
1075 m_tolerance_offspring_others.Clear();
1076 m_intolerances.SetAll(make_pair(-1, -1));
1077 cur_child_germline_propensity = m_world->GetConfig().DEMES_DEFAULT_GERMLINE_PROPENSITY.Get();
1078
1079 // Setup other miscellaneous values...
1080 num_divides++;
1081 generation++;
1082 (void) time_used;
1083 (void) num_execs;
1084 (void) age;
1085 (void) fault_desc;
1086 (void) neutral_metric;
1087 life_fitness = fitness;
1088 exec_time_born += gestation_time; //@MRR See DivideReset
1089 birth_update = m_world->GetStats().GetUpdate();
1090 num_new_unique_reactions = 0;
1091 last_task_id = -1;
1092 res_consumed = 0;
1093 last_task_time = 0;
1094
1095
1096 num_thresh_gb_donations_last = num_thresh_gb_donations;
1097 num_thresh_gb_donations = 0;
1098 num_quanta_thresh_gb_donations_last = num_quanta_thresh_gb_donations;
1099 num_quanta_thresh_gb_donations = 0;
1100 num_shaded_gb_donations_last = num_shaded_gb_donations;
1101 num_shaded_gb_donations = 0;
1102 num_donations_locus_last = num_donations_locus;
1103 num_donations_locus = 0;
1104
1105 // Leave flags alone...
1106 (void) is_injected;
1107 is_donor_last = is_donor_cur;
1108 is_donor_cur = false;
1109 is_donor_rand_last = is_donor_rand;
1110 is_donor_rand = false;
1111 is_donor_null_last = is_donor_null;
1112 is_donor_null = false;
1113 is_donor_kin_last = is_donor_kin;
1114 is_donor_kin = false;
1115 is_donor_edit_last = is_donor_edit;
1116 is_donor_edit = false;
1117 is_donor_gbg_last = is_donor_gbg;
1118 is_donor_gbg = false;
1119 is_donor_truegb_last = is_donor_truegb;
1120 is_donor_truegb = false;
1121 is_donor_threshgb_last = is_donor_threshgb;
1122 is_donor_threshgb = false;
1123 is_donor_quanta_threshgb_last = is_donor_quanta_threshgb;
1124 is_donor_quanta_threshgb = false;
1125 is_donor_shadedgb_last = is_donor_shadedgb;
1126 is_donor_shadedgb = false;
1127 is_donor_locus_last = is_donor_locus;
1128 is_donor_locus.SetAll(false);
1129
1130 is_receiver_last = is_receiver;
1131 is_receiver = false;
1132 is_receiver_rand = false;
1133 is_receiver_kin_last = is_receiver_kin;
1134 is_receiver_kin = false;
1135 is_receiver_edit_last = is_receiver_edit;
1136 is_receiver_edit = false;
1137 is_receiver_gbg = false;
1138 is_receiver_truegb_last = is_receiver_truegb;
1139 is_receiver_truegb = false;
1140 is_receiver_threshgb_last = is_receiver_threshgb;
1141 is_receiver_threshgb = false;
1142 is_receiver_quanta_threshgb_last = is_receiver_quanta_threshgb;
1143 is_receiver_quanta_threshgb = false;
1144 is_receiver_shadedgb_last = is_receiver_shadedgb;
1145 is_receiver_shadedgb = false;
1146 is_receiver_gb_same_locus_last = is_receiver_gb_same_locus;
1147 is_receiver_gb_same_locus = false;
1148
1149 (void) is_modifier;
1150 (void) is_modified;
1151 (void) is_fertile;
1152 (void) is_mutated;
1153 (void) is_multi_thread;
1154 (void) parent_true;
1155 (void) parent_sex;
1156 (void) parent_cross_num;
1157
1158 // Reset child info...
1159 (void) copy_true;
1160 (void) divide_sex;
1161 (void) mate_select_id;
1162 (void) cross_num;
1163 (void) child_fertile;
1164 (void) last_child_fertile;
1165 (void) child_copied_size;
1166 }
1167
1168
1169 /**
1170 * This function is run when an organism is being forced to replicate, but
1171 * not at the end of its replication cycle.
1172 *
1173 * Assumptions:
1174 * - new organism is an exact clone of the parent, with *same* last info.
1175 * - this is the first method run on an otherwise freshly built phenotype.
1176 **/
1177
SetupClone(const cPhenotype & clone_phenotype)1178 void cPhenotype::SetupClone(const cPhenotype& clone_phenotype)
1179 {
1180 // Copy divide values from parent, which should already be setup.
1181 merit = clone_phenotype.merit;
1182
1183 energy_store = clone_phenotype.energy_store;
1184 energy_tobe_applied = 0.0;
1185 energy_testament = 0.0;
1186 energy_received_buffer = 0.0;
1187
1188 if (m_world->GetConfig().INHERIT_EXE_RATE.Get() == 0) executionRatio = 1.0;
1189 else executionRatio = clone_phenotype.executionRatio;
1190
1191 genome_length = clone_phenotype.genome_length;
1192 copied_size = clone_phenotype.copied_size;
1193 // copied_size = clone_phenotype.child_copied_size;
1194 executed_size = clone_phenotype.executed_size;
1195 gestation_time = clone_phenotype.gestation_time;
1196 gestation_start = 0;
1197 fitness = clone_phenotype.fitness;
1198 div_type = clone_phenotype.div_type;
1199
1200 assert(genome_length > 0);
1201 assert(copied_size > 0);
1202 assert(gestation_time >= 0); //@JEB 0 valid for some fitness methods
1203 assert(div_type > 0);
1204
1205 // Initialize current values, as neeeded.
1206 cur_bonus = m_world->GetConfig().DEFAULT_BONUS.Get();
1207 cpu_cycles_used = 0;
1208 cur_num_errors = 0;
1209 cur_num_donates = 0;
1210 cur_task_count.SetAll(0);
1211 cur_host_tasks.SetAll(0);
1212 cur_para_tasks.SetAll(0);
1213 cur_internal_task_count.SetAll(0);
1214 eff_task_count.SetAll(0);
1215 cur_rbins_total.SetAll(0);
1216 cur_rbins_avail.SetAll(0);
1217 cur_collect_spec_counts.SetAll(0);
1218 cur_reaction_count.SetAll(0);
1219 first_reaction_cycles.SetAll(-1);
1220 first_reaction_execs.SetAll(-1);
1221 cur_stolen_reaction_count.SetAll(0);
1222 cur_reaction_add_reward.SetAll(0);
1223 cur_inst_count.SetAll(0);
1224 cur_sense_count.SetAll(0);
1225 cur_task_time.SetAll(0.0);
1226 for (int j = 0; j < sensed_resources.GetSize(); j++) {
1227 sensed_resources[j] = clone_phenotype.sensed_resources[j];
1228 }
1229 cur_trial_fitnesses.Resize(0);
1230 cur_trial_bonuses.Resize(0);
1231 cur_trial_times_used.Resize(0);
1232 trial_time_used = 0;
1233 trial_cpu_cycles_used = 0;
1234 m_tolerance_immigrants.Clear();
1235 m_tolerance_offspring_own.Clear();
1236 m_tolerance_offspring_others.Clear();
1237 m_intolerances.SetAll(make_pair(-1, -1));
1238 cur_child_germline_propensity = m_world->GetConfig().DEMES_DEFAULT_GERMLINE_PROPENSITY.Get();
1239 mating_type = MATING_TYPE_JUVENILE; // @CHC
1240 mate_preference = MATE_PREFERENCE_RANDOM; //@CHC
1241
1242 // Copy last values from parent
1243 last_merit_base = clone_phenotype.last_merit_base;
1244 last_bonus = clone_phenotype.last_bonus;
1245 last_cpu_cycles_used = clone_phenotype.last_cpu_cycles_used;
1246 last_num_errors = clone_phenotype.last_num_errors;
1247 last_num_donates = clone_phenotype.last_num_donates;
1248 last_task_count = clone_phenotype.last_task_count;
1249 last_host_tasks = clone_phenotype.last_host_tasks;
1250 last_para_tasks = clone_phenotype.last_para_tasks;
1251 last_internal_task_count = clone_phenotype.last_internal_task_count;
1252 last_rbins_total = clone_phenotype.last_rbins_total;
1253 last_rbins_avail = clone_phenotype.last_rbins_avail;
1254 last_collect_spec_counts = clone_phenotype.last_collect_spec_counts;
1255 last_reaction_count = clone_phenotype.last_reaction_count;
1256 last_reaction_add_reward = clone_phenotype.last_reaction_add_reward;
1257 last_inst_count = clone_phenotype.last_inst_count;
1258 last_sense_count = clone_phenotype.last_sense_count;
1259 last_fitness = CalcFitness(last_merit_base, last_bonus, gestation_time, last_cpu_cycles_used);
1260 last_child_germline_propensity = clone_phenotype.last_child_germline_propensity;
1261
1262 // Setup other miscellaneous values...
1263 num_divides = 0;
1264 num_divides_failed = 0;
1265 generation = clone_phenotype.generation;
1266 if (m_world->GetConfig().GENERATION_INC_METHOD.Get() != GENERATION_INC_BOTH) generation++;
1267 cpu_cycles_used = 0;
1268 time_used = 0;
1269 num_execs = 0;
1270 age = 0;
1271 fault_desc = "";
1272 neutral_metric = clone_phenotype.neutral_metric + m_world->GetRandom().GetRandNormal();
1273 life_fitness = fitness;
1274 exec_time_born = 0;
1275 birth_update = m_world->GetStats().GetUpdate();
1276 num_new_unique_reactions = clone_phenotype.num_new_unique_reactions;
1277 last_task_id = clone_phenotype.last_task_id;
1278 res_consumed = clone_phenotype.res_consumed;
1279 is_germ_cell = clone_phenotype.is_germ_cell;
1280 last_task_time = clone_phenotype.last_task_time;
1281
1282
1283 num_thresh_gb_donations_last = clone_phenotype.num_thresh_gb_donations_last;
1284 num_thresh_gb_donations = clone_phenotype.num_thresh_gb_donations;
1285 num_quanta_thresh_gb_donations_last = clone_phenotype.num_quanta_thresh_gb_donations_last;
1286 num_quanta_thresh_gb_donations = clone_phenotype.num_quanta_thresh_gb_donations;
1287 num_shaded_gb_donations_last = clone_phenotype.num_shaded_gb_donations_last;
1288 num_shaded_gb_donations = clone_phenotype.num_shaded_gb_donations;
1289 num_donations_locus = clone_phenotype.num_donations_locus;
1290 num_donations_locus_last = clone_phenotype.num_donations_locus_last;
1291
1292 // Setup flags...
1293 is_injected = false;
1294 is_donor_last = clone_phenotype.is_donor_last;
1295 is_donor_cur = clone_phenotype.is_donor_cur;
1296 is_receiver = false;
1297 is_donor_rand_last = clone_phenotype.is_donor_rand_last;
1298 is_donor_rand = clone_phenotype.is_donor_rand;
1299 is_donor_null_last = clone_phenotype.is_donor_null_last;
1300 is_donor_null = clone_phenotype.is_donor_null;
1301 is_donor_kin_last = clone_phenotype.is_donor_kin_last;
1302 is_donor_kin = clone_phenotype.is_donor_kin;
1303 is_donor_edit_last = clone_phenotype.is_donor_edit_last;
1304 is_donor_edit = clone_phenotype.is_donor_edit;
1305 is_donor_gbg_last = clone_phenotype.is_donor_gbg_last;
1306 is_donor_gbg = clone_phenotype.is_donor_gbg;
1307 is_donor_truegb_last = clone_phenotype.is_donor_truegb_last;
1308 is_donor_truegb = clone_phenotype.is_donor_truegb;
1309 is_donor_threshgb_last = clone_phenotype.is_donor_threshgb_last;
1310 is_donor_threshgb = clone_phenotype.is_donor_threshgb;
1311 is_donor_quanta_threshgb_last = clone_phenotype.is_donor_quanta_threshgb_last;
1312 is_donor_quanta_threshgb = clone_phenotype.is_donor_quanta_threshgb;
1313 is_donor_shadedgb_last = clone_phenotype.is_donor_shadedgb_last;
1314 is_donor_shadedgb = clone_phenotype.is_donor_shadedgb;
1315 is_donor_locus_last = clone_phenotype.is_donor_locus_last;
1316 is_donor_locus = clone_phenotype.is_donor_locus;
1317
1318 is_receiver = clone_phenotype.is_receiver;
1319 is_receiver_last = clone_phenotype.is_receiver_last;
1320 is_receiver_rand = clone_phenotype.is_receiver_rand;
1321 is_receiver_kin = clone_phenotype.is_receiver_kin;
1322 is_receiver_kin_last = clone_phenotype.is_receiver_kin_last;
1323 is_receiver_edit = clone_phenotype.is_receiver_edit;
1324 is_receiver_edit_last = clone_phenotype.is_receiver_edit_last;
1325 is_receiver_gbg = clone_phenotype.is_receiver_gbg;
1326 is_receiver_truegb = clone_phenotype.is_receiver_truegb;
1327 is_receiver_truegb_last = clone_phenotype.is_receiver_truegb_last;
1328 is_receiver_threshgb = clone_phenotype.is_receiver_threshgb;
1329 is_receiver_threshgb_last = clone_phenotype.is_receiver_threshgb_last;
1330 is_receiver_quanta_threshgb = clone_phenotype.is_receiver_quanta_threshgb;
1331 is_receiver_quanta_threshgb_last = clone_phenotype.is_receiver_quanta_threshgb_last;
1332 is_receiver_shadedgb = clone_phenotype.is_receiver_shadedgb;
1333 is_receiver_shadedgb_last = clone_phenotype.is_receiver_shadedgb_last;
1334 is_receiver_gb_same_locus = clone_phenotype.is_receiver_gb_same_locus;
1335
1336 is_modifier = false;
1337 is_modified = false;
1338 is_fertile = clone_phenotype.last_child_fertile;
1339 is_mutated = false;
1340 is_multi_thread = clone_phenotype.is_multi_thread;
1341 parent_true = clone_phenotype.copy_true;
1342 parent_sex = clone_phenotype.divide_sex;
1343 parent_cross_num = clone_phenotype.cross_num;
1344 to_die = false;
1345 to_delete = false;
1346 is_energy_requestor = false;
1347 is_energy_donor = false;
1348 is_energy_receiver = false;
1349 has_used_donated_energy = false;
1350 has_open_energy_request = false;
1351
1352 // Setup child info...
1353 copy_true = false;
1354 divide_sex = false;
1355 mate_select_id = 0;
1356 cross_num = 0;
1357 last_child_fertile = is_fertile;
1358 child_fertile = true;
1359 child_copied_size = 0;
1360 permanent_germline_propensity = clone_phenotype.permanent_germline_propensity;
1361
1362 initialized = true;
1363 }
1364
1365
1366
1367
TestInput(tBuffer<int> & inputs,tBuffer<int> & outputs)1368 bool cPhenotype::TestInput(tBuffer<int>& inputs, tBuffer<int>& outputs)
1369 {
1370 assert(initialized == true);
1371 // For the moment, lets not worry about inputs...
1372 return false; // Nothing happened...
1373 }
1374
TestOutput(cAvidaContext & ctx,cTaskContext & taskctx,const tArray<double> & res_in,const tArray<double> & rbins_in,tArray<double> & res_change,tArray<cString> & insts_triggered,bool is_parasite,cContextPhenotype * context_phenotype)1375 bool cPhenotype::TestOutput(cAvidaContext& ctx, cTaskContext& taskctx,
1376 const tArray<double>& res_in, const tArray<double>& rbins_in,
1377 tArray<double>& res_change, tArray<cString>& insts_triggered,
1378 bool is_parasite, cContextPhenotype* context_phenotype)
1379 {
1380 assert(initialized == true);
1381 taskctx.SetTaskStates(&m_task_states);
1382
1383 const cEnvironment& env = m_world->GetEnvironment();
1384 const int num_resources = env.GetResourceLib().GetSize();
1385 const int num_tasks = env.GetNumTasks();
1386 const int num_reactions = env.GetReactionLib().GetSize();
1387
1388 // For refractory period @WRE 03-20-07
1389 const int cur_update_time = m_world->GetStats().GetUpdate();
1390 const double task_refractory_period = m_world->GetConfig().TASK_REFRACTORY_PERIOD.Get();
1391 double refract_factor;
1392
1393 if (!m_reaction_result) m_reaction_result = new cReactionResult(num_resources, num_tasks, num_reactions);
1394 cReactionResult& result = *m_reaction_result;
1395
1396 // Run everything through the environment.
1397 bool found = env.TestOutput(ctx, result, taskctx, eff_task_count, cur_reaction_count, res_in, rbins_in,
1398 is_parasite, context_phenotype); //NEED different eff_task_count and cur_reaction_count for deme resource
1399
1400 // If nothing was found, stop here.
1401 if (found == false) {
1402 result.Invalidate();
1403 res_change.SetAll(0.0);
1404 return false; // Nothing happened.
1405 }
1406
1407 // Update the phenotype with the results...
1408 // Start with updating task and reaction counters
1409 for (int i = 0; i < num_tasks; i++) {
1410 // Calculate refractory period factor @WRE
1411 // Modify TaskQuality amount based on refractory period
1412 // Logistic equation using refractory period
1413 // in update units from configuration file. @WRE 03-20-07, 04-17-07
1414
1415 if (task_refractory_period == 0.0) {
1416 refract_factor = 1.0;
1417 } else {
1418 refract_factor = 1.0 - (1.0 / (1.0 + exp((cur_update_time - cur_task_time[i]) - task_refractory_period * 0.5)));
1419 }
1420
1421 if (result.TaskDone(i) == true) {
1422 cur_task_count[i]++;
1423 eff_task_count[i]++;
1424
1425 // Update parasite/host task tracking appropriately
1426 if (is_parasite) {
1427 cur_para_tasks[i]++;
1428 }
1429 else {
1430 cur_host_tasks[i]++;
1431 }
1432
1433 if (context_phenotype != 0) {
1434 context_phenotype->GetTaskCounts()[i]++;
1435 }
1436 if (result.UsedEnvResource() == false) { cur_internal_task_count[i]++; }
1437
1438 // if we want to generate an age-task histogram
1439 if (m_world->GetConfig().AGE_POLY_TRACKING.Get()) {
1440 m_world->GetStats().AgeTaskEvent(taskctx.GetOrganism()->GetID(), i, time_used);
1441 }
1442 }
1443
1444 if (result.TaskQuality(i) > 0) {
1445 cur_task_quality[i] += result.TaskQuality(i) * refract_factor;
1446 if (result.UsedEnvResource() == false) {
1447 cur_internal_task_quality[i] += result.TaskQuality(i) * refract_factor;
1448 }
1449 }
1450
1451 cur_task_value[i] = result.TaskValue(i);
1452 cur_task_time[i] = cur_update_time; // Find out time from context
1453 }
1454
1455 for (int i = 0; i < num_tasks; i++) {
1456 if (result.TaskDone(i) && !last_task_count[i]) {
1457 m_world->GetStats().AddNewTaskCount(i);
1458 int prev_num_tasks = 0;
1459 int cur_num_tasks = 0;
1460 for (int j=0; j< num_tasks; j++) {
1461 if (last_task_count[j]>0) prev_num_tasks++;
1462 if (cur_task_count[j]>0) cur_num_tasks++;
1463 }
1464 m_world->GetStats().AddOtherTaskCounts(i, prev_num_tasks, cur_num_tasks);
1465 }
1466 }
1467
1468 for (int i = 0; i < num_reactions; i++) {
1469 cur_reaction_add_reward[i] += result.GetReactionAddBonus(i);
1470 if (result.ReactionTriggered(i) && last_reaction_count[i]==0) {
1471 m_world->GetStats().AddNewReactionCount(i);
1472 }
1473 if (result.ReactionTriggered(i) == true) {
1474 if (context_phenotype != 0) {
1475 context_phenotype->GetReactionCounts()[i]++;
1476 }
1477 // If the organism has not performed this task,
1478 // then consider it to be a task switch.
1479 // If applicable, add in the penalty.
1480 switch (m_world->GetConfig().TASK_SWITCH_PENALTY_TYPE.Get()) {
1481 case 0: { // no penalty
1482 break;
1483 }
1484 case 1: { // "learning" cost
1485 int n_react = cur_reaction_count[i] -1;
1486 if (n_react < m_world->GetConfig().LEARNING_COUNT.Get()) {
1487 num_new_unique_reactions += ( m_world->GetConfig().LEARNING_COUNT.Get() - n_react);
1488 }
1489 break;
1490 }
1491 case 2: { // "retooling" cost
1492 if (last_task_id == -1) {
1493 last_task_id = i;
1494 last_task_time = time_used;
1495 } else {
1496 // track time used if applicable
1497 int cur_time_used = time_used - last_task_time;
1498 last_task_time = time_used;
1499 m_world->GetStats().AddTaskSwitchTime(last_task_id, i, cur_time_used);
1500 if (last_task_id != i) {
1501 num_new_unique_reactions++;
1502 last_task_id = i;
1503 }
1504
1505 }
1506 break;
1507 }
1508 case 3: { // centrifuge
1509 // task switching cost is calculated based on
1510 // the distance between the two tasks.
1511
1512 int distance = abs(i - last_task_id);
1513 num_new_unique_reactions += distance;
1514 last_task_id = i;
1515
1516 break;
1517 }
1518 default: {
1519 assert(false);
1520 break;
1521 }
1522 }
1523 }
1524 }
1525
1526 // Update the merit bonus
1527 cur_bonus *= result.GetMultBonus();
1528 cur_bonus += result.GetAddBonus();
1529
1530 // update the germline propensity
1531 cur_child_germline_propensity += result.GetAddGermline();
1532 cur_child_germline_propensity *= result.GetMultGermline();
1533
1534 // Update deme merit (guard against running in the test CPU, where there is
1535 // no deme object. Don't touch deme merit if there is no deme frac component.
1536 cDeme* deme = taskctx.GetOrganism()->GetDeme();
1537 if (deme) {
1538 if (result.GetActiveDeme()) {
1539 double deme_bonus = deme->GetHeritableDemeMerit().GetDouble();
1540 deme_bonus *= result.GetMultDemeBonus();
1541 deme_bonus += result.GetAddDemeBonus();
1542 deme->UpdateHeritableDemeMerit(deme_bonus);
1543 }
1544
1545 //also count tasks/reactions
1546 for (int i = 0; i < num_tasks; i++) {
1547 if (result.TaskDone(i) == true) deme->AddCurTask(i);
1548 }
1549 for (int i = 0; i < num_reactions; i++) {
1550 if (result.ReactionTriggered(i) == true) deme->AddCurReaction(i);
1551 }
1552 }
1553
1554 // Update the energy bonus
1555 cur_energy_bonus += result.GetAddEnergy();
1556
1557 // Denote consumed resources...
1558 for (int i = 0; i < res_in.GetSize(); i++) {
1559 res_change[i] = result.GetProduced(i) - result.GetConsumed(i);
1560 res_consumed += result.GetConsumed(i);
1561 }
1562
1563 // Update rbins as necessary
1564 if (result.UsedEnvResource() == false) {
1565 double rbin_diff;
1566 for (int i = 0; i < num_resources; i++) {
1567 rbin_diff = result.GetInternalConsumed(i) - result.GetInternalProduced(i); ;
1568 cur_rbins_avail[i] -= rbin_diff;
1569 if(rbin_diff != 0) { cur_rbins_total[i] += rbin_diff; }
1570 }
1571 }
1572
1573 // Save the instructions that should be triggered...
1574 insts_triggered = result.GetInstArray();
1575
1576 //Put in detected resources
1577 for (int j = 0; j < res_in.GetSize(); j++) {
1578 if(result.GetDetected(j) != -1.0) {
1579 sensed_resources[j] = result.GetDetected(j);
1580 }
1581 }
1582
1583 //Kill any cells that did lethal reactions
1584 to_die = result.GetLethal();
1585
1586 // Sterilize organisms that have performed a sterilizing task.
1587 if(result.GetSterilize()) {
1588 is_fertile = false;
1589 }
1590
1591 result.Invalidate();
1592 return true;
1593 }
1594
1595
Sterilize()1596 void cPhenotype::Sterilize()
1597 {
1598 is_fertile = false;
1599 }
1600
1601
PrintStatus(ostream & fp) const1602 void cPhenotype::PrintStatus(ostream& fp) const
1603 {
1604 fp << " MeritBase:"
1605 << CalcSizeMerit()
1606 << " Bonus:" << cur_bonus
1607 << " Errors:" << cur_num_errors
1608 << " Donates:" << cur_num_donates
1609 << '\n';
1610
1611 fp << " Task Count (Quality):";
1612 for (int i = 0; i < cur_task_count.GetSize(); i++) {
1613 fp << " " << cur_task_count[i] << " (" << cur_task_quality[i] << ")";
1614 }
1615 fp << '\n';
1616
1617 // if using resoruce bins, print the relevant stats
1618 if (m_world->GetConfig().USE_RESOURCE_BINS.Get()) {
1619 fp << " Used-Internal-Resources Task Count (Quality):";
1620 for (int i = 0; i < cur_internal_task_count.GetSize(); i++) {
1621 fp << " " << cur_internal_task_count[i] << " (" << cur_internal_task_quality[i] << ")";
1622 }
1623 fp << endl;
1624
1625 fp << " Available Internal Resource Bin Contents (Total Ever Collected):";
1626 for(int i = 0; i < cur_rbins_avail.GetSize(); i++) {
1627 fp << " " << cur_rbins_avail[i] << " (" << cur_rbins_total[i] << ")";
1628 }
1629 fp << endl;
1630 }
1631 }
1632
CalcSizeMerit() const1633 int cPhenotype::CalcSizeMerit() const
1634 {
1635 assert(genome_length > 0);
1636 assert(copied_size > 0);
1637
1638 int out_size;
1639
1640 switch (m_world->GetConfig().BASE_MERIT_METHOD.Get()) {
1641 case BASE_MERIT_COPIED_SIZE:
1642 out_size = copied_size;
1643 break;
1644 case BASE_MERIT_EXE_SIZE:
1645 out_size = executed_size;
1646 break;
1647 case BASE_MERIT_FULL_SIZE:
1648 out_size = genome_length;
1649 break;
1650 case BASE_MERIT_LEAST_SIZE:
1651 out_size = genome_length;
1652 if (out_size > copied_size) out_size = copied_size;
1653 if (out_size > executed_size) out_size = executed_size;
1654 break;
1655 case BASE_MERIT_SQRT_LEAST_SIZE:
1656 out_size = genome_length;
1657 if (out_size > copied_size) out_size = copied_size;
1658 if (out_size > executed_size) out_size = executed_size;
1659 out_size = (int) sqrt((double) out_size);
1660 break;
1661 case BASE_MERIT_NUM_BONUS_INST:
1662 if (m_world->GetConfig().FITNESS_VALLEY.Get()){
1663 if (bonus_instruction_count >= m_world->GetConfig().FITNESS_VALLEY_START.Get() &&
1664 bonus_instruction_count <= m_world->GetConfig().FITNESS_VALLEY_STOP.Get()){
1665 out_size = 1;
1666 break;
1667 }
1668 }
1669 if (m_world->GetConfig().MERIT_BONUS_EFFECT.Get()>0) {
1670 out_size = 1 + bonus_instruction_count;
1671 }
1672 else if (m_world->GetConfig().MERIT_BONUS_EFFECT.Get()<0) {
1673 out_size = genome_length - (bonus_instruction_count -1);
1674 }
1675 else {
1676 out_size = 1; // The extra 1 point is so the orgs are not jilted by the scheduler.
1677 }
1678 break;
1679 case BASE_MERIT_GESTATION_TIME:
1680 out_size = cpu_cycles_used;
1681 break;
1682 case BASE_MERIT_CONST:
1683 default:
1684 out_size = m_world->GetConfig().BASE_CONST_MERIT.Get();
1685 break;
1686 }
1687
1688 return out_size;
1689 }
1690
CalcCurrentMerit() const1691 double cPhenotype::CalcCurrentMerit() const
1692 {
1693 int merit_base = CalcSizeMerit();
1694
1695 return merit_base * cur_bonus;
1696 }
1697
1698
CalcFitness(double _merit_base,double _bonus,int _gestation_time,int _cpu_cycles) const1699 double cPhenotype::CalcFitness(double _merit_base, double _bonus, int _gestation_time, int _cpu_cycles) const
1700 {
1701 double out_fitness = 0;
1702 switch (m_world->GetConfig().FITNESS_METHOD.Get()) {
1703 case 0: // Normal
1704 assert(_gestation_time > 0);
1705 out_fitness = _merit_base * _bonus / _gestation_time;
1706 break;
1707
1708 case 1: // Sigmoidal returns (should be used with an additive reward)
1709 {
1710 assert(_gestation_time > 0);
1711 out_fitness = 0;
1712 //Note: this operates on accumulated bonus and ignores the default bonus.
1713 double converted_bonus = (_bonus - m_world->GetConfig().DEFAULT_BONUS.Get()) * m_world->GetConfig().FITNESS_COEFF_2.Get() / (1 + _bonus * m_world->GetConfig().FITNESS_COEFF_2.Get() ) ;
1714 out_fitness = _merit_base * exp(converted_bonus * log(m_world->GetConfig().FITNESS_COEFF_1.Get())) / _gestation_time;
1715 }
1716 break;
1717
1718 case 2: //Activity of one enzyme in pathway altered (with diminishing returns and a cost for each executed instruction)
1719 {
1720 out_fitness = 0;
1721 double net_bonus = _bonus + - m_world->GetConfig().DEFAULT_BONUS.Get();
1722 out_fitness = net_bonus / (net_bonus + 1)* exp (_gestation_time * log(1 - m_world->GetConfig().FITNESS_COEFF_1.Get()));
1723 }
1724 break;
1725
1726 default:
1727 cout << "Unknown FITNESS_METHOD!" << endl;
1728 exit(1);
1729 }
1730
1731 return out_fitness;
1732 }
1733
1734 /* Returns the organism's total tolerance towards immigrants by counting
1735 the total number of dec-tolerance entries within the update window that have been executed.
1736 */
CalcToleranceImmigrants()1737 int cPhenotype::CalcToleranceImmigrants()
1738 {
1739 const int cur_update = m_world->GetStats().GetUpdate();
1740 const int tolerance_max = m_world->GetConfig().MAX_TOLERANCE.Get();
1741
1742 // Check if cached value is up-to-date, return
1743 if (m_intolerances[0].first == cur_update) return tolerance_max - m_intolerances[0].second;
1744
1745 const int update_window = m_world->GetConfig().TOLERANCE_WINDOW.Get();
1746 // Update the tolerance list by getting rid of outdated records
1747 while (m_tolerance_immigrants.GetSize() && *m_tolerance_immigrants.GetLast() < cur_update - update_window)
1748 delete m_tolerance_immigrants.PopRear();
1749
1750 // And prune the list down to MAX_TOLERANCE entries.
1751 while (m_tolerance_immigrants.GetSize() > tolerance_max)
1752 delete m_tolerance_immigrants.PopRear();
1753
1754 const int tolerance = tolerance_max - m_tolerance_immigrants.GetSize();
1755
1756 // Update cached values
1757 m_intolerances[0].first = cur_update;
1758 m_intolerances[0].second = m_tolerance_immigrants.GetSize();
1759 return tolerance;
1760 }
1761
1762 /* Returns the organism's total tolerance towards the organism's own offspring by counting
1763 the total number of dec-tolerance entries within the update window that have been executed.
1764 */
CalcToleranceOffspringOwn()1765 int cPhenotype::CalcToleranceOffspringOwn()
1766 {
1767 const int cur_update = m_world->GetStats().GetUpdate();
1768 const int tolerance_max = m_world->GetConfig().MAX_TOLERANCE.Get();
1769
1770 // If offspring tolerances off, skip calculations returning max
1771 if (m_world->GetConfig().TOLERANCE_VARIATIONS.Get() > 0) return tolerance_max;
1772
1773 // Check if cached value is up-to-date, return
1774 if (m_intolerances[1].first == cur_update) return tolerance_max - m_intolerances[1].second;
1775
1776 const int update_window = m_world->GetConfig().TOLERANCE_WINDOW.Get();
1777
1778 // Update the tolerance list by getting rid of outdated records
1779 while (m_tolerance_offspring_own.GetSize() && *m_tolerance_offspring_own.GetLast() < cur_update - update_window)
1780 delete m_tolerance_offspring_own.PopRear();
1781
1782 // And prune the list down to MAX_TOLERANCE entries.
1783 while (m_tolerance_offspring_own.GetSize() > tolerance_max)
1784 delete m_tolerance_offspring_own.PopRear();
1785
1786 const int tolerance = tolerance_max - m_tolerance_offspring_own.GetSize();
1787
1788 // Update cached values
1789 m_intolerances[1].first = cur_update;
1790 m_intolerances[1].second = m_tolerance_offspring_own.GetSize();
1791 return tolerance;
1792 }
1793
1794 /* Returns the organism's total tolerance towards the offspring of others in the group by counting
1795 the total number of dec-tolerance entries within the update window that have been executed.
1796 */
CalcToleranceOffspringOthers()1797 int cPhenotype::CalcToleranceOffspringOthers()
1798 {
1799 const int cur_update = m_world->GetStats().GetUpdate();
1800 const int tolerance_max = m_world->GetConfig().MAX_TOLERANCE.Get();
1801
1802 // If offspring tolerances off, skip calculations returning max
1803 if (m_world->GetConfig().TOLERANCE_VARIATIONS.Get() > 0) return tolerance_max;
1804
1805 // Check if cached value is up-to-date, return
1806 if (m_intolerances[2].first == cur_update) return tolerance_max - m_intolerances[2].second;
1807
1808 const int update_window = m_world->GetConfig().TOLERANCE_WINDOW.Get();
1809
1810 // Update the tolerance list by getting rid of outdated records
1811 while (m_tolerance_offspring_others.GetSize() && *m_tolerance_offspring_others.GetLast() < cur_update - update_window)
1812 delete m_tolerance_offspring_others.PopRear();
1813
1814 // And prune the list down to MAX_TOLERANCE entries.
1815 while (m_tolerance_offspring_others.GetSize() > tolerance_max)
1816 delete m_tolerance_offspring_others.PopRear();
1817
1818 const int tolerance = tolerance_max - m_tolerance_offspring_others.GetSize();
1819
1820 // Update cached values
1821 m_intolerances[2].first = cur_update;
1822 m_intolerances[2].second = m_tolerance_offspring_others.GetSize();
1823 return tolerance;
1824 }
1825
ReduceEnergy(const double cost)1826 void cPhenotype::ReduceEnergy(const double cost) {
1827 SetEnergy(energy_store - cost);
1828 }
1829
SetEnergy(const double value)1830 void cPhenotype::SetEnergy(const double value) {
1831 energy_store = max(0.0, min(value, m_world->GetConfig().ENERGY_CAP.Get()));
1832 }
1833
DoubleEnergyUsage()1834 void cPhenotype::DoubleEnergyUsage() {
1835 executionRatio *= 2.0;
1836 }
1837
HalveEnergyUsage()1838 void cPhenotype::HalveEnergyUsage() {
1839 executionRatio *= 0.5;
1840 }
1841
DefaultEnergyUsage()1842 void cPhenotype::DefaultEnergyUsage() {
1843 executionRatio = 1.0;
1844 }
1845
DivideFailed()1846 void cPhenotype::DivideFailed() {
1847 num_divides_failed++;
1848 }
1849
1850
1851 /**
1852 Credit organism with energy reward, but only update energy store if APPLY_ENERGY_METHOD = "on task completion" (1)
1853 */
RefreshEnergy()1854 void cPhenotype::RefreshEnergy() {
1855 if(cur_energy_bonus > 0) {
1856 if(m_world->GetConfig().APPLY_ENERGY_METHOD.Get() == 0 || // on divide
1857 m_world->GetConfig().APPLY_ENERGY_METHOD.Get() == 2) { // on sleep
1858 energy_tobe_applied += cur_energy_bonus;
1859 } else if(m_world->GetConfig().APPLY_ENERGY_METHOD.Get() == 1) {
1860 SetEnergy(energy_store + cur_energy_bonus);
1861 m_world->GetStats().SumEnergyTestamentAcceptedByOrganisms().Add(energy_testament);
1862 energy_testament = 0.0;
1863 } else {
1864 cerr<< "Unknown APPLY_ENERGY_METHOD value " << m_world->GetConfig().APPLY_ENERGY_METHOD.Get();
1865 exit(-1);
1866 }
1867 cur_energy_bonus = 0;
1868 }
1869 }
1870
ApplyToEnergyStore()1871 void cPhenotype::ApplyToEnergyStore() {
1872 SetEnergy(energy_store + energy_tobe_applied);
1873 m_world->GetStats().SumEnergyTestamentAcceptedByOrganisms().Add(energy_testament);
1874 energy_testament = 0.0;
1875 energy_tobe_applied = 0.0;
1876 energy_testament = 0.0;
1877 }
1878
EnergyTestament(const double value)1879 void cPhenotype::EnergyTestament(const double value) {
1880 assert(value > 0.0);
1881 energy_tobe_applied += value;
1882 energy_testament += value;
1883 } //! external energy given to organism
1884
1885
ApplyDonatedEnergy()1886 void cPhenotype::ApplyDonatedEnergy() {
1887 double energy_cap = m_world->GetConfig().ENERGY_CAP.Get();
1888
1889 if((energy_store + energy_received_buffer) >= energy_cap) {
1890 IncreaseEnergyApplied(energy_cap - energy_store);
1891 SetEnergy(energy_store + (energy_cap - energy_received_buffer));
1892 } else {
1893 IncreaseEnergyApplied(energy_received_buffer);
1894 SetEnergy(energy_store + energy_received_buffer);
1895 }
1896
1897 IncreaseNumEnergyApplications();
1898 SetHasUsedDonatedEnergy();
1899
1900 energy_received_buffer = 0.0;
1901
1902 } //End AppplyDonatedEnergy()
1903
1904
ReceiveDonatedEnergy(const double donation)1905 void cPhenotype::ReceiveDonatedEnergy(const double donation) {
1906 assert(donation >= 0.0);
1907 energy_received_buffer += donation;
1908 IncreaseEnergyReceived(donation);
1909 SetIsEnergyReceiver();
1910 IncreaseNumEnergyReceptions();
1911 } //End ReceiveDonatedEnergy()
1912
1913
ExtractParentEnergy()1914 double cPhenotype::ExtractParentEnergy() {
1915 assert(m_world->GetConfig().ENERGY_ENABLED.Get() > 0);
1916 // energy model config variables
1917 double energy_given_at_birth = m_world->GetConfig().ENERGY_GIVEN_AT_BIRTH.Get();
1918 double frac_parent_energy_given_at_birth = m_world->GetConfig().FRAC_PARENT_ENERGY_GIVEN_TO_ORG_AT_BIRTH.Get();
1919 double frac_energy_decay_at_birth = m_world->GetConfig().FRAC_ENERGY_DECAY_AT_ORG_BIRTH.Get();
1920 double energy_cap = m_world->GetConfig().ENERGY_CAP.Get();
1921
1922 // apply energy if APPLY_ENERGY_METHOD is set to "on divide" (0)
1923 if(m_world->GetConfig().APPLY_ENERGY_METHOD.Get() == 0) {
1924 RefreshEnergy();
1925 ApplyToEnergyStore();
1926 }
1927
1928 // decay of energy in parent
1929 ReduceEnergy(GetStoredEnergy() * frac_energy_decay_at_birth);
1930
1931 // calculate energy to be given to child
1932 double child_energy = max(0.0, min(GetStoredEnergy() * frac_parent_energy_given_at_birth + energy_given_at_birth, energy_cap));
1933 assert(GetStoredEnergy()>0.0);
1934 // adjust energy in parent
1935 ReduceEnergy(child_energy - 2*energy_given_at_birth); // 2*energy_given_at_birth: 1 in child_energy & 1 for parent
1936
1937 //TODO: add energy_given_at_birth to Stored_energy
1938 cMerit parentMerit(ConvertEnergyToMerit(GetStoredEnergy() * GetEnergyUsageRatio()));
1939 if (parentMerit.GetDouble() > 0.0) SetMerit(parentMerit);
1940 else SetToDie();
1941
1942 return child_energy;
1943 }
1944
1945 // Save the current fitness and reset relevant parts of the phenotype
NewTrial()1946 void cPhenotype::NewTrial()
1947 {
1948 //Return if a complete trial has not occurred.
1949 //(This will happen if CompeteOrganisms was called before in the same update
1950 if (trial_cpu_cycles_used == 0) return;
1951
1952 //Record the merit of this trial
1953 fitness = CalcFitness( GetCurMeritBase(), GetCurBonus() , trial_time_used, trial_cpu_cycles_used); // This is a per-trial fitness @JEB
1954 cur_trial_fitnesses.Push(fitness);
1955 cur_trial_bonuses.Push(GetCurBonus());
1956 cur_trial_times_used.Push(trial_time_used);
1957
1958 //The rest of the function, resets the phenotype like DivideReset(), but without
1959 //incrementing the generation or child statistics.
1960
1961 //Most importantly, this does (below):
1962 // trial_time_used = 0;
1963 // trial_cpu_cycles_used = 0;
1964 // SetCurBonus(m_world->GetConfig().DEFAULT_BONUS.Get());
1965
1966 // Update these values as needed...
1967 int cur_merit_base = CalcSizeMerit();
1968
1969 // If we are resetting the current merit, do it here
1970 // and it will also be propagated to the child
1971 int merit_default_bonus = m_world->GetConfig().MERIT_DEFAULT_BONUS.Get();
1972 if (merit_default_bonus) {
1973 cur_bonus = merit_default_bonus;
1974 }
1975 merit = cur_merit_base * cur_bonus;
1976
1977 // update energy store
1978 energy_store += cur_energy_bonus;
1979 energy_store = m_world->GetConfig().ENERGY_GIVEN_AT_BIRTH.Get(); // We reset to what they had at birth
1980 cur_energy_bonus = 0;
1981 // to be perfectly accurate, this should be from a last_energy value??
1982
1983
1984 // genome_length = _genome.GetSize(); //No child! @JEB
1985 (void) copied_size; // Unchanged
1986 (void) executed_size; // Unchanged
1987 gestation_time = time_used - gestation_start; //Keep gestation referring to actual replication time! @JEB
1988 gestation_start = time_used; //Keep gestation referring to actual replication time! @JEB
1989 // fitness = merit.GetDouble() / gestation_time; //Use fitness measure that is per-trial @JEB
1990
1991 // Lock in cur values as last values.
1992 last_merit_base = cur_merit_base;
1993 last_bonus = cur_bonus;
1994 last_cpu_cycles_used = cpu_cycles_used;
1995 //TODO? last_energy = cur_energy_bonus;
1996 last_num_errors = cur_num_errors;
1997 last_num_donates = cur_num_donates;
1998 last_task_count = cur_task_count;
1999 last_host_tasks = cur_host_tasks;
2000 last_para_tasks = cur_para_tasks;
2001 last_internal_task_count = cur_internal_task_count;
2002 last_task_quality = cur_task_quality;
2003 last_internal_task_quality= cur_internal_task_quality;
2004 last_task_value = cur_task_value;
2005 last_rbins_total = cur_rbins_total;
2006 last_rbins_avail = cur_rbins_avail;
2007 last_collect_spec_counts = cur_collect_spec_counts;
2008 last_reaction_count = cur_reaction_count;
2009 last_reaction_add_reward = cur_reaction_add_reward;
2010 last_inst_count = cur_inst_count;
2011 last_sense_count = cur_sense_count;
2012
2013 // Reset cur values.
2014 cur_bonus = m_world->GetConfig().DEFAULT_BONUS.Get();
2015 cpu_cycles_used = 0;
2016 cur_energy_bonus = 0.0;
2017 cur_num_errors = 0;
2018 cur_num_donates = 0;
2019 cur_task_count.SetAll(0);
2020 cur_host_tasks.SetAll(0);
2021 cur_para_tasks.SetAll(0);
2022 cur_internal_task_count.SetAll(0);
2023 eff_task_count.SetAll(0);
2024 cur_task_quality.SetAll(0);
2025 cur_internal_task_quality.SetAll(0);
2026 cur_task_value.SetAll(0);
2027 cur_rbins_total.SetAll(0);
2028 cur_rbins_avail.SetAll(0);
2029 cur_collect_spec_counts.SetAll(0);
2030 cur_reaction_count.SetAll(0);
2031 first_reaction_cycles.SetAll(-1);
2032 first_reaction_execs.SetAll(-1);
2033 cur_stolen_reaction_count.SetAll(0);
2034 cur_reaction_add_reward.SetAll(0);
2035 cur_inst_count.SetAll(0);
2036 cur_sense_count.SetAll(0);
2037 //cur_trial_fitnesses.Resize(0); Don't throw out the trial fitnesses! @JEB
2038 trial_time_used = 0;
2039 trial_cpu_cycles_used = 0;
2040 m_tolerance_immigrants.Clear();
2041 m_tolerance_offspring_own.Clear();
2042 m_tolerance_offspring_others.Clear();
2043 m_intolerances.SetAll(make_pair(-1, -1));
2044
2045 // Setup other miscellaneous values...
2046 num_divides++;
2047 (void) generation;
2048 (void) time_used;
2049 num_execs = 0;
2050 age = 0;
2051 fault_desc = "";
2052 (void) neutral_metric;
2053 life_fitness = fitness;
2054
2055
2056 num_thresh_gb_donations_last = num_thresh_gb_donations;
2057 num_thresh_gb_donations = 0;
2058 num_quanta_thresh_gb_donations_last = num_quanta_thresh_gb_donations;
2059 num_quanta_thresh_gb_donations = 0;
2060 num_shaded_gb_donations_last = num_shaded_gb_donations;
2061 num_shaded_gb_donations = 0;
2062 num_donations_locus_last = num_donations_locus;
2063 num_donations_locus = 0;
2064
2065 // Leave flags alone...
2066 (void) is_injected;
2067 is_donor_last = is_donor_cur;
2068 is_donor_cur = false;
2069 is_donor_rand_last = is_donor_rand;
2070 is_donor_rand = false;
2071 is_donor_null_last = is_donor_null;
2072 is_donor_null = false;
2073 is_donor_kin_last = is_donor_kin;
2074 is_donor_kin = false;
2075 is_donor_edit_last = is_donor_edit;
2076 is_donor_edit = false;
2077 is_donor_gbg_last = is_donor_gbg;
2078 is_donor_gbg = false;
2079 is_donor_truegb_last = is_donor_truegb;
2080 is_donor_truegb = false;
2081 is_donor_threshgb_last = is_donor_threshgb;
2082 is_donor_threshgb = false;
2083 is_donor_quanta_threshgb_last = is_donor_quanta_threshgb;
2084 is_donor_quanta_threshgb = false;
2085 is_donor_shadedgb_last = is_donor_shadedgb;
2086 is_donor_shadedgb = false;
2087 is_donor_locus_last = is_donor_locus;
2088 is_donor_locus.SetAll(false);
2089
2090 is_receiver_last = is_receiver;
2091 is_receiver = false;
2092 is_receiver_rand = false;
2093 is_receiver_kin_last = is_receiver_kin;
2094 is_receiver_kin = false;
2095 is_receiver_edit_last = is_receiver_edit;
2096 is_receiver_edit = false;
2097 is_receiver_gbg = false;
2098 is_receiver_truegb_last = is_receiver_truegb;
2099 is_receiver_truegb = false;
2100 is_receiver_threshgb_last = is_receiver_threshgb;
2101 is_receiver_threshgb = false;
2102 is_receiver_quanta_threshgb_last = is_receiver_quanta_threshgb;
2103 is_receiver_quanta_threshgb = false;
2104 is_receiver_shadedgb_last = is_receiver_shadedgb;
2105 is_receiver_shadedgb = false;
2106 is_receiver_gb_same_locus_last = is_receiver_gb_same_locus;
2107 is_receiver_gb_same_locus = false;
2108
2109 is_energy_requestor = false;
2110 is_energy_donor = false;
2111 is_energy_receiver = false;
2112 (void) is_modifier;
2113 (void) is_modified;
2114 (void) is_fertile;
2115 (void) is_mutated;
2116 (void) is_multi_thread;
2117 (void) parent_true;
2118 (void) parent_sex;
2119 (void) parent_cross_num;
2120 }
2121
2122 /**
2123 * This function is run to reset an organism whose task counts (etc) have already been moved from cur to last
2124 * by another call (like NewTrial). It is a subset of DivideReset @JEB
2125 **/
2126
TrialDivideReset(const Sequence & _genome)2127 void cPhenotype::TrialDivideReset(const Sequence& _genome)
2128 {
2129 int cur_merit_base = CalcSizeMerit();
2130
2131 // If we are resetting the current merit, do it here
2132 // and it will also be propagated to the child
2133 const int merit_default_bonus = m_world->GetConfig().MERIT_DEFAULT_BONUS.Get();
2134 if (merit_default_bonus) {
2135 cur_bonus = merit_default_bonus;
2136 }
2137 merit = cur_merit_base * cur_bonus;
2138
2139 SetEnergy(energy_store + cur_energy_bonus);
2140 m_world->GetStats().SumEnergyTestamentAcceptedByOrganisms().Add(energy_testament);
2141 energy_testament = 0.0;
2142
2143 genome_length = _genome.GetSize();
2144 gestation_start = time_used;
2145 cur_trial_fitnesses.Resize(0);
2146 cur_trial_bonuses.Resize(0);
2147 cur_trial_times_used.Resize(0);
2148
2149 // Reset child info...
2150 (void) copy_true;
2151 (void) divide_sex;
2152 (void) mate_select_id;
2153 (void) cross_num;
2154 last_child_fertile = child_fertile;
2155 child_fertile = true;
2156 (void) child_copied_size;
2157
2158 // A few final changes if the parent was supposed to be be considered
2159 // a second child on the divide.
2160 if ((m_world->GetConfig().DIVIDE_METHOD.Get() == DIVIDE_METHOD_SPLIT) || (m_world->GetConfig().DIVIDE_METHOD.Get() == DIVIDE_METHOD_BIRTH)) {
2161 gestation_start = 0;
2162 cpu_cycles_used = 0;
2163 time_used = 0;
2164 num_execs = 0;
2165 neutral_metric += m_world->GetRandom().GetRandNormal();
2166 }
2167
2168 if (m_world->GetConfig().DIVIDE_METHOD.Get() == DIVIDE_METHOD_SPLIT) {
2169 m_tolerance_immigrants.Clear();
2170 m_tolerance_offspring_own.Clear();
2171 m_tolerance_offspring_others.Clear();
2172 m_intolerances.SetAll(make_pair(-1,-1));
2173 }
2174
2175 if (m_world->GetConfig().GENERATION_INC_METHOD.Get() == GENERATION_INC_BOTH) generation++;
2176 }
2177
2178 // Arbitrary (but consistant) ordering.
2179 // Return -1 if lhs is "less", +1 is it is "greater", and 0 otherwise.
Compare(const cPhenotype * lhs,const cPhenotype * rhs)2180 int cPhenotype::Compare(const cPhenotype* lhs, const cPhenotype* rhs) {
2181 // Compare first based on merit...
2182 if ( lhs->GetMerit() < rhs->GetMerit() ) return -1;
2183 else if ( lhs->GetMerit() > rhs->GetMerit() ) return 1;
2184
2185 // If merits are equal, compare gestation time...
2186 if ( lhs->GetGestationTime() < rhs->GetGestationTime() ) return -1;
2187 else if ( lhs->GetGestationTime() > rhs->GetGestationTime() ) return 1;
2188
2189 // If gestation times are also equal, compare each task
2190 tArray<int> lhsTasks = lhs->GetLastTaskCount();
2191 tArray<int> rhsTasks = rhs->GetLastTaskCount();
2192 for (int k = 0; k < lhsTasks.GetSize(); k++) {
2193 if (lhsTasks[k] < rhsTasks[k]) return -1;
2194 else if (lhsTasks[k] > rhsTasks[k]) return 1;
2195 }
2196
2197 // Assume they are identical.
2198 return 0;
2199 }
2200
operator ()(const cPhenotype * lhs,const cPhenotype * rhs) const2201 bool cPhenotype::PhenotypeCompare::operator()(const cPhenotype* lhs, const cPhenotype* rhs) const {
2202 return cPhenotype::Compare(lhs, rhs) < 0;
2203 }
2204
2205
2206
2207 // Return an integer classifying the organism's energy level as -1=error,0=low,1=med,2=high
GetDiscreteEnergyLevel() const2208 int cPhenotype::GetDiscreteEnergyLevel() const {
2209 double max_energy = m_world->GetConfig().ENERGY_CAP.Get();
2210 double high_pct = m_world->GetConfig().ENERGY_THRESH_HIGH.Get();
2211 double low_pct = m_world->GetConfig().ENERGY_THRESH_LOW.Get();
2212
2213 assert(max_energy >= 0);
2214 assert(high_pct <= 1);
2215 assert(high_pct >= 0);
2216 assert(low_pct <= 1);
2217 assert(low_pct >= 0);
2218 assert(low_pct <= high_pct);
2219
2220 if (energy_store < (low_pct * max_energy)) {
2221 return ENERGY_LEVEL_LOW;
2222 } else if ( (energy_store >= (low_pct * max_energy)) && (energy_store <= (high_pct * max_energy)) ) {
2223 return ENERGY_LEVEL_MEDIUM;
2224 } else if (energy_store > (high_pct * max_energy)) {
2225 return ENERGY_LEVEL_HIGH;
2226 } else {
2227 return -1;
2228 }
2229
2230 } //End GetDiscreteEnergyLevel()
2231
2232
ConvertEnergyToMerit(double energy) const2233 double cPhenotype::ConvertEnergyToMerit(double energy) const
2234 {
2235 assert(m_world->GetConfig().ENERGY_ENABLED.Get() == 1);
2236
2237 double FIX_METABOLIC_RATE = m_world->GetConfig().FIX_METABOLIC_RATE.Get();
2238 if (FIX_METABOLIC_RATE > 0.0) return 100 * FIX_METABOLIC_RATE;
2239
2240 return 100 * energy / m_world->GetConfig().NUM_CYCLES_EXC_BEFORE_0_ENERGY.Get();
2241 }
2242
2243
2244
GetResourcesConsumed()2245 double cPhenotype::GetResourcesConsumed()
2246 {
2247 double r = res_consumed;
2248 res_consumed =0;
2249 return r;
2250 }
2251
2252 //Deep copy parasite task count
SetLastParasiteTaskCount(tArray<int> oldParaPhenotype)2253 void cPhenotype::SetLastParasiteTaskCount(tArray<int> oldParaPhenotype)
2254 {
2255 assert(initialized == true);
2256
2257 for(int i=0;i<oldParaPhenotype.GetSize();i++)
2258 {
2259 last_para_tasks[i] = oldParaPhenotype[i];
2260 }
2261 }
2262
2263 /* Return the cumulative reaction count if we aren't resetting on divide. */
GetCumulativeReactionCount()2264 tArray<int> cPhenotype::GetCumulativeReactionCount()
2265 {
2266 if (m_world->GetConfig().DIVIDE_METHOD.Get() == 0) {
2267 tArray<int> cum_react;
2268 for (int i=0; i<cur_reaction_count.GetSize(); ++i)
2269 {
2270 cum_react.Push(cur_reaction_count[i] + last_reaction_count[i]);
2271 }
2272 // return (cur_reaction_count + last_reaction_count);
2273 return cum_react;
2274 } else {
2275 return cur_reaction_count;
2276 }
2277 }
2278