Skip to content

Commit e6d5007

Browse files
Merge pull request #270 from K-Johnson-Horrigan/complex-syms-clean
Preferential ousting
2 parents 8f62f38 + d8b9a06 commit e6d5007

5 files changed

Lines changed: 330 additions & 2 deletions

File tree

source/sgp_mode/SGPConfigSetup.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ EMP_EXTEND_CONFIG(SymConfigSGP, SymConfigBase,
2525
VALUE(DIFFERENT_TASK_VALUES, bool, 0, "Should tasks have different values (2, 4, 6, 8, 10)? If false, all will be 5"),
2626
VALUE(HOST_MIN_CYCLES_BEFORE_REPRO, size_t, 0, "How many CPU cycles must a host execute before it can reproduce?"),
2727
VALUE(SYM_MIN_CYCLES_BEFORE_REPRO, size_t, 0, "How many CPU cycles must a symbiont execute before it can reproduce?"),
28+
VALUE(PREFERENTIAL_OUSTING, size_t, 0, "Should preferential ousting be on, and if so how? (0 = no preferential ousting, 1 = the incoming symbiont must have an equal or better match than the current symbiont in order to oust, 2 = the incoming symbiont must have a strictly better match than the current symbiont in order to oust)"),
2829

2930
GROUP(STRESS, "Stress Settings"),
3031
VALUE(EXTINCTION_FREQUENCY, size_t, 2000, "How often should extinction events occur (in updates)?"),

source/sgp_mode/SGPWorld.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,7 @@ class SGPWorld : public SymWorld {
140140
emp::WorldPosition SymDoBirth(emp::Ptr<Organism> sym_baby, emp::WorldPosition parent_pos) override;
141141
int GetNeighborHost(size_t id, emp::Ptr<Organism> symbiont);
142142
bool TaskMatchCheck(emp::Ptr<Organism> sym_parent, emp::Ptr<Organism> host_parent);
143+
bool PreferentialOustingAllowed(emp::Ptr<Organism> sym_parent, emp::Ptr<Organism> host);
143144

144145
// Prototypes for sym transfering
145146
emp::WorldPosition SymFindHost(emp::Ptr<Organism> symbiont, emp::WorldPosition cur_pos);

source/sgp_mode/SGPWorldSetup.cc

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,12 @@ emp::WorldPosition SGPWorld::SymDoBirth(emp::Ptr<Organism> sym_baby, emp::WorldP
166166
emp::Ptr<Organism> parent = GetOrgPtr(i)->GetSymbionts()[parent_pos.GetIndex()-1];
167167
int new_host_pos = GetNeighborHost(i, parent);
168168
if (new_host_pos > -1) { //-1 means no living neighbors
169+
if(sgp_config->OUSTING() && sgp_config->PREFERENTIAL_OUSTING() && (int)pop[new_host_pos]->GetSymbionts().size() == sgp_config->SYM_LIMIT()){
170+
if(!PreferentialOustingAllowed(parent, pop[new_host_pos])){
171+
sym_baby.Delete();
172+
return emp::WorldPosition();
173+
}
174+
}
169175
int new_index = pop[new_host_pos]->AddSymbiont(sym_baby);
170176
if(new_index > 0){ //sym successfully infected
171177
return emp::WorldPosition(new_index, new_host_pos);
@@ -193,6 +199,12 @@ emp::WorldPosition SGPWorld::SymDoBirth(emp::Ptr<Organism> sym_baby, emp::WorldP
193199
size_t i = cur_pos.GetPopID();
194200
int new_host_pos = GetNeighborHost(i, symbiont);
195201
if (new_host_pos > -1) { //-1 means no living neighbors
202+
if(sgp_config->OUSTING() && sgp_config->PREFERENTIAL_OUSTING() && (int)pop[new_host_pos]->GetSymbionts().size() == sgp_config->SYM_LIMIT()){
203+
if(!PreferentialOustingAllowed(symbiont, pop[new_host_pos])){
204+
symbiont.Delete();
205+
return emp::WorldPosition();
206+
}
207+
}
196208
int new_index = pop[new_host_pos]->AddSymbiont(symbiont);
197209
if(new_index > 0){ //sym successfully infected
198210
return emp::WorldPosition(new_index, new_host_pos);
@@ -204,4 +216,45 @@ emp::WorldPosition SGPWorld::SymDoBirth(emp::Ptr<Organism> sym_baby, emp::WorldP
204216
return emp::WorldPosition();
205217
}
206218
}
219+
220+
221+
/**
222+
* Input: Pointers to a symbiont and a host.
223+
*
224+
* Output: Returns a bool if the incoming symbiont should be allowed to oust
225+
*
226+
* Purpose: Caclulate preferential ousting success
227+
*/
228+
bool SGPWorld::PreferentialOustingAllowed(emp::Ptr<Organism> sym_parent, emp::Ptr<Organism> host){
229+
emp::Ptr<SGPSymbiont> incoming_symbiont = sym_parent.DynamicCast<SGPSymbiont>();
230+
231+
emp::BitSet<CPU_BITSET_LENGTH> host_tasks = (sgp_config->TRACK_PARENT_TASKS()) ?
232+
(*host.DynamicCast<SGPHost>()->GetCPU().state.tasks_performed).OR(*host.DynamicCast<SGPHost>()->GetCPU().state.parent_tasks_performed) :
233+
*host.DynamicCast<SGPHost>()->GetCPU().state.tasks_performed;
234+
235+
emp::BitSet<CPU_BITSET_LENGTH> incoming_sym_tasks = (sgp_config->TRACK_PARENT_TASKS()) ?
236+
(*sym_parent.DynamicCast<SGPSymbiont>()->GetCPU().state.tasks_performed).OR(*sym_parent.DynamicCast<SGPSymbiont>()->GetCPU().state.parent_tasks_performed) :
237+
*sym_parent.DynamicCast<SGPSymbiont>()->GetCPU().state.tasks_performed;
238+
239+
for(emp::Ptr<Organism> sym : host->GetSymbionts()){
240+
emp::BitSet<CPU_BITSET_LENGTH> target_sym_tasks = (sgp_config->TRACK_PARENT_TASKS()) ?
241+
(*sym.DynamicCast<SGPSymbiont>()->GetCPU().state.tasks_performed).OR(*sym.DynamicCast<SGPSymbiont>()->GetCPU().state.parent_tasks_performed) :
242+
*sym.DynamicCast<SGPSymbiont>()->GetCPU().state.tasks_performed;
243+
244+
if(sgp_config->PREFERENTIAL_OUSTING() == 1){
245+
// if has worse task match with any hosted sym, fail
246+
if(host_tasks.AND(incoming_sym_tasks).CountOnes() < host_tasks.AND(target_sym_tasks).CountOnes()){
247+
return false;
248+
}
249+
}
250+
else if(sgp_config->PREFERENTIAL_OUSTING() == 2){
251+
// if has equal or worse task match with any hosted sym, fail
252+
if(host_tasks.AND(incoming_sym_tasks).CountOnes() <= host_tasks.AND(target_sym_tasks).CountOnes()){
253+
return false;
254+
}
255+
}
256+
}
257+
258+
return true;
259+
}
207260
#endif

source/test/default_mode_test/Host.test.cc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -523,6 +523,7 @@ TEST_CASE("RemoveSymbiont", "[default]") {
523523
REQUIRE(symbiont->GetHost() == nullptr);
524524
REQUIRE(removed_sym == symbiont);
525525
}
526+
removed_sym.Delete();
526527
}
527528

528529
WHEN("RemoveSymbiont is called with invalid index") {
@@ -544,7 +545,9 @@ TEST_CASE("RemoveSymbiont", "[default]") {
544545
REQUIRE(null_sym == nullptr);
545546
}
546547
}
548+
host.Delete();
547549
}
550+
random.Delete();
548551
}
549552

550553
TEST_CASE("AddSymbiont", "[default]"){

0 commit comments

Comments
 (0)