diff --git a/source/Evolve/OEE.h b/source/Evolve/OEE.h index 24be487a47..688c44ce92 100644 --- a/source/Evolve/OEE.h +++ b/source/Evolve/OEE.h @@ -16,8 +16,8 @@ namespace emp { template struct oee_data : public no_data { - SKEL_TYPE skeleton = NULL; - bool oee_calculated = false; + Ptr skeleton = nullptr; + ~oee_data(){if(skeleton){skeleton.Delete();}} }; }; @@ -36,6 +36,7 @@ namespace emp { }; std::deque> snapshots; + std::deque snapshot_times; Ptr> systematics_manager; std::map prev_coal_set; @@ -88,8 +89,11 @@ namespace emp { void SetResolution(int r) {resolution = r;} void SetGenerationInterval(int g) {generation_interval = g;} - void Update(size_t ud) { - if (Mod((int)ud, resolution) == 0) { + void Update(size_t gen, int ud = -1) { + if (Mod((int)gen, resolution) == 0) { + if (ud == -1) { + ud = gen; + } auto & sys_active = systematics_manager->GetActive(); emp::vector active(sys_active.size()); @@ -100,7 +104,10 @@ namespace emp { i++; } snapshots.push_back(active); + snapshot_times.push_back(ud); if ((int)snapshots.size() > generation_interval/resolution + 1) { + systematics_manager->RemoveBefore(snapshot_times.front() - 1); + snapshot_times.pop_front(); snapshots.pop_front(); } CalcStats(ud); @@ -162,7 +169,7 @@ namespace emp { return res; } - std::set> extant_canopy_roots = systematics_manager->GetCanopyExtantRoots(ud-generation_interval); + std::set> extant_canopy_roots = systematics_manager->GetCanopyExtantRoots(snapshot_times.front()); // std::cout << "exteant canpoy roots: "; // for (auto t : extant_canopy_roots) { // std::cout << t->GetInfo() << " "; @@ -171,14 +178,13 @@ namespace emp { for ( snapshot_info_t & t : snapshots.front()) { if (Has(extant_canopy_roots, t.taxon)) { // std::cout << t.taxon->GetInfo() << " Survived filter" << std::endl; - if (!t.taxon->GetData().oee_calculated) { - t.taxon->GetData().skeleton = skeleton_fun(t.taxon->GetInfo()); - t.taxon->GetData().oee_calculated = true; + if (!t.taxon->GetData().skeleton) { + t.taxon->GetData().skeleton.New(skeleton_fun(t.taxon->GetInfo())); } - if (Has(res, t.taxon->GetData().skeleton)) { - res[t.taxon->GetData().skeleton] += t.count; + if (Has(res, *(t.taxon->GetData().skeleton))) { + res[*(t.taxon->GetData().skeleton)] += t.count; } else { - res[t.taxon->GetData().skeleton] = t.count; + res[*(t.taxon->GetData().skeleton)] = t.count; } } } diff --git a/source/Evolve/Systematics.h b/source/Evolve/Systematics.h index 18fdd26610..da0529484d 100644 --- a/source/Evolve/Systematics.h +++ b/source/Evolve/Systematics.h @@ -147,6 +147,7 @@ namespace emp { /// Retrieve a pointer to the parent Taxon. Ptr GetParent() const { return parent; } + void NullifyParent() {parent = nullptr;} /// Get the number of living organisms currently associated with this Taxon. size_t GetNumOrgs() const { return num_orgs; } @@ -993,7 +994,68 @@ namespace emp { return depth; } + void RemoveBefore(int ud) { + + // @ELD: This would be such a nice way to do it + // but we can't because we need to notify offspring + // when there parents are un-tracked + // std::set> to_remove; + // for (Ptr tax : ancestor_taxa) { + // if (tax->GetDestructionTime() < ud) { + // to_remove.insert(tax); + // } + // } + + // for (Ptr tax : to_remove) { + // ancestor_taxa.erase(tax); + // tax.Delete(); + // } + + std::map, std::set>> to_remove; + for (Ptr tax : active_taxa) { + Ptr curr = tax; + + while (curr && !CanRemove(curr->GetParent(), ud)) { + curr = curr->GetParent(); + } + + if (curr) { + Ptr next = curr->GetParent(); + while (next) { + to_remove[next].insert(curr); + curr = next; + next = next->GetParent(); + } + } + } + // std::cout << "About to remove " << to_remove.size() << " orgs" << std::endl; + for (std::pair, std::set>> el : to_remove) { + emp_assert(el.first->GetDestructionTime() < ud, el.first->GetDestructionTime(), ud); + if (el.first->GetNumOff() == el.second.size()) { + // Everything is account for + for (auto tax : el.second) { + tax->NullifyParent(); + } + ancestor_taxa.erase(el.first); + el.first.Delete(); + } + } + + } + + bool CanRemove(Ptr t, int ud) { + if (!t) { + return false; + } + while (t) { + if (t->GetNumOrgs() > 0 || t->GetDestructionTime() >= ud) { + return false; + } + t = t->GetParent(); + } + return true; + } /// Request a pointer to the Most-Recent Common Ancestor for the population. Ptr GetMRCA() const;