Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Stats managers #63

Merged
merged 53 commits into from
Jun 1, 2016
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
53 commits
Select commit Hold shift + click to select a range
2164781
Last commit before I completely overhaul OEE.h
emilydolson Apr 6, 2016
eba2749
Merge branch 'master' of github.com:devosoft/Empirical
emilydolson Apr 8, 2016
d70eea3
Merge branch 'master' of github.com:devosoft/Empirical
emilydolson Apr 19, 2016
4e615bc
Adding update signal
emilydolson Apr 22, 2016
24aa95f
Merge branch 'master' of github.com:devosoft/Empirical
emilydolson Apr 22, 2016
0ebbf5c
Complexity and Ecology work
emilydolson May 11, 2016
b787d67
Fixed merge conflict
emilydolson May 11, 2016
2c7be2f
Merge branch 'master' of github.com:devosoft/Empirical
emilydolson May 11, 2016
6ae3880
All metrics work
emilydolson May 11, 2016
2abc7e5
All metrics work
emilydolson May 12, 2016
fdd1819
All metrics work, skeletonization streamlined
emilydolson May 13, 2016
570aab4
Separate generations deduction works now
emilydolson May 13, 2016
e718cf2
Merge branch 'master' of github.com:devosoft/Empirical
emilydolson May 13, 2016
24e903a
Cleaned up OEE.h, added comments
emilydolson May 13, 2016
de8731e
Added example for OEE tracker
emilydolson May 14, 2016
7481633
Fixed bug in change deque length, added fitness tracking
emilydolson May 14, 2016
bcb6fa9
Merge branch 'master' of github.com:devosoft/Empirical
emilydolson May 14, 2016
86fe09b
Added print statement to verify settings
emilydolson May 14, 2016
88b491e
Added template specializations to appease std::vector
emilydolson May 15, 2016
8aac649
Made template specialization of ShannonDiversity to take a World
emilydolson May 18, 2016
1c525dc
Worlds are iterable
emilydolson May 18, 2016
7c51aeb
Fixing merge conflict
emilydolson May 18, 2016
779a6f4
Use world iterator in stats
emilydolson May 19, 2016
89150a8
Merge branch 'master' of github.com:devosoft/Empirical into nullorgs
emilydolson May 19, 2016
e6629c8
Fixed tournament selection to only choose from valid orgs
emilydolson May 19, 2016
229d7d9
NK_OEE now uses const landscapes
emilydolson May 19, 2016
39d792d
Lineage tracker does everything automatically with signals
emilydolson May 19, 2016
b119b08
Made ids actually propagate correctly
emilydolson May 19, 2016
295fd66
Elite selection is null org safe
emilydolson May 19, 2016
7795f83
GetValidOrgIndices actually works now
emilydolson May 19, 2016
0303f20
Merge in Jake and Stevens addition to Stats.h
emilydolson May 20, 2016
c41f784
Merge in null org handling
emilydolson May 20, 2016
a740eb6
Base stats manager functionality works
emilydolson May 20, 2016
f331839
StatsManagers handle output locations
emilydolson May 22, 2016
b718da7
Worlditerator uses pointers
emilydolson May 22, 2016
a848858
Added error message for invalid file
emilydolson May 22, 2016
b68dba6
Created default stats manager, made header
emilydolson May 23, 2016
14a5af0
Merge branch 'master' of github.com:devosoft/Empirical
emilydolson May 23, 2016
261a9f3
Added comments, cleaned up types
emilydolson May 23, 2016
49744de
OEE stats manager uses base output
emilydolson May 23, 2016
09fdf57
Stats managers have config files
emilydolson May 23, 2016
34198f6
Fixed possible null dereference in tournament fitness calculation
emilydolson May 23, 2016
db2c17d
Guard against null dereference in MutatePop
emilydolson May 23, 2016
39ae05f
StatsManagers can be passed as template arguments
emilydolson May 27, 2016
eb645f2
LineageTracker and OEEStats now follow general StatsManager format
emilydolson May 29, 2016
2149343
LineageTracker and OEEStats now follow general StatsManager format
emilydolson May 29, 2016
4fd1544
Merge branch 'master' of github.com:emilydolson/Empirical
emilydolson May 29, 2016
0a6b803
Lineage tracker automatically hooks up to OEE stats
emilydolson May 29, 2016
97f0ffb
Automatic lineage tracker construction works
emilydolson May 29, 2016
adadaac
Made stats generic and moved them to tools
emilydolson May 29, 2016
a92e954
Merge branch 'master' of github.com:devosoft/Empirical
emilydolson May 30, 2016
a80244f
Fixed g++ compilation bug
emilydolson May 31, 2016
a6897a1
Stats Manager headers + assorted cleanup
emilydolson Jun 1, 2016
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Lineage tracker does everything automatically with signals
  • Loading branch information
emilydolson committed May 19, 2016
commit 39d792d7074e77cd6fdc76f49e221b667d5c08a3
108 changes: 93 additions & 15 deletions evo/LineageTracker.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,40 +15,118 @@ namespace evo{
// Class to keep track of lineages
// Maintains record of all genomes that ever existed, which organisms
// they belonged to, and which organisms were the parents of which
template <typename GENOME>
template <typename ORG, typename... MANAGERS>
class LineageTracker {
private:
using pop_manager_type = AdaptTemplate< typename SelectPopManager<MANAGERS..., PopBasic>::type, ORG>;
static constexpr bool separate_generations = pop_manager_type::emp_has_separate_generations;
public:
std::set<GENOME> genomes;
std::map<int, GENOME*> org_to_genome;
std::set<ORG> genomes;
std::map<int, ORG*> org_to_genome;
std::map<int, int> parents;
int next = 0; //-1 indicates no parent

LineageTracker() {
this->parents[-1] = 0;
int next = 1; //0 indicates no parent
int next_parent_id = -1;
int next_org_id = 1;
emp::vector<int> generation_since_update;
emp::vector<int> prev_generation;

LineageTracker(){;}

LineageTracker(World<ORG, MANAGERS...> * world) {

//Create std::function objects for all the callbacks. It seems like
//this maybe shouldn't be necessary (or at least shouldn't need to happen
//in the constructor), but for now it is or the compiler throws
//internal errors
std::function<void(int)> RecordParentFun = [this] (int id){
RecordParent(id);
};

std::function<void(int)> TrackPlacementFun = [this] (int pos){
TrackPlacement(pos);
};

std::function<void(ORG *)> TrackOffspringFun = [this] (ORG * org){
TrackOffspring(org);
};

std::function<void(ORG *)> TrackInjectedOffspringFun = [this] (ORG * org){
TrackInjectedOffspring(org);
};

std::function<void(int)> UpdateFun = [this] (int ud){
Update(ud);
};

world->OnBeforeRepro(RecordParentFun);
world->OnOffspringReady(TrackOffspringFun);
world->OnInjectReady(TrackInjectedOffspringFun);
world->OnOrgPlacement(TrackPlacementFun);
world->OnUpdate(UpdateFun);
}

~LineageTracker() {
//for (GENOME g : genomes) delete &g;
}

//Put newly born organism into the lineage tracker

void Update(int i) {
prev_generation = generation_since_update;
if (separate_generations) {
//TODO: This isn't sufficient - need to add signals for any
//population change event
generation_since_update.resize(0);
}
}

void TrackOffspring(ORG * org) {
next_org_id = this->AddOrganism(*org, next_parent_id);
}

//Put newly injected organism into the lineage tracker
void TrackInjectedOffspring(ORG * org) {
next_org_id = this->AddOrganism(*org, 0);
}

//Keep track of location of all orgs in the population so that
//we can translate their ids from the World to ids within the lineage
//tracker
void TrackPlacement(int pos) {
if (pos >= generation_since_update.size()) {
generation_since_update.resize(pos+1);
}
generation_since_update[pos] = next_org_id;
}

//Record the org that's about to have an offspring, so we can know
//who the parent of the next org is.
void RecordParent(int id) {
if (separate_generations){
next_parent_id = prev_generation[id];
} else {
next_parent_id = generation_since_update[id];
}
}

// Add an organism to the tracker - org is the genome of the organism
// and parent is the id of the parent. The lineage tracker is in charge
// of assigning ids, and will return an int representing the id of the
// organism you added
int AddOrganism(GENOME org, int parent) {
int AddOrganism(ORG org, int parent) {
int id = this->next++;
std::pair<typename std::set<GENOME>::iterator, bool> ret;
std::pair<typename std::set<ORG>::iterator, bool> ret;
ret = genomes.insert(org);
typename std::set<GENOME>::iterator it = ret.first;
GENOME* genome = (GENOME*)&(*it);
typename std::set<ORG>::iterator it = ret.first;
ORG* genome = (ORG*)&(*it);
this->org_to_genome[id] = genome;
this->parents[id] = parent;

return id;
}

// Return a vector containing the genomes of an organism's ancestors
emp::vector<GENOME*> TraceLineage(int org_id) {
emp::vector<GENOME*> lineage;
emp::vector<ORG*> TraceLineage(int org_id) {
emp::vector<ORG*> lineage;

while(org_id) {
lineage.push_back(this->org_to_genome[org_id]);
Expand All @@ -61,7 +139,7 @@ namespace evo{

//Return a vector containing the IDs of an oraganism's ancestors
emp::vector<int> TraceLineageIDs(int org_id) {
emp::vector<GENOME*> lineage;
emp::vector<ORG*> lineage;

while(org_id) {
lineage.push_back(org_id);
Expand Down
80 changes: 9 additions & 71 deletions evo/OEE.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,25 +33,19 @@ namespace evo{
static constexpr bool separate_generations = pop_manager_type::emp_has_separate_generations;
static constexpr bool emp_is_stats_manager = true;
//TODO: Make this use existing lineage tracker if there is one
LineageTracker<ORG> lineage;
std::set<skeleton_type > novel;

// The generation we're currently working with - we need this to
// track lineage
emp::vector<int> generation_since_update;
std::set<skeleton_type > novel;

// Historical generations needed to count stats. We only need these in
// proportion to resolution.
int generations = 50; //How far back do we look for persistance?
int resolution = 10; //With what frequency do we record data?
std::deque<emp::vector<int> > past_snapshots;

//int update = 0;
int next_parent_id = -1;
int next_org_id;

public:

LineageTracker<ORG, MANAGERS...> * lineage;

OEEStatsManager(World<ORG, MANAGERS...>* world){
// This isn't going to work if generations aren't a multiple of resolution
emp_assert(generations % resolution == 0 &&
Expand All @@ -63,70 +57,20 @@ namespace evo{
//this maybe shouldn't be necessary (or at least shouldn't need to happen
//in the constructor), but for now it is or the compiler throws
//internal errors
std::function<void(int)> RecordParentFun = [this] (int id){
RecordParent(id);
};

std::function<void(int)> TrackPlacementFun = [this] (int pos){
TrackPlacement(pos);
};

std::function<void(ORG *)> TrackOffspringFun = [this] (ORG * org){
TrackOffspring(org);
};

std::function<void(ORG *)> TrackInjectedOffspringFun = [this] (ORG * org){
TrackInjectedOffspring(org);
};

std::function<void(int)> UpdateFun = [this] (int ud){
Update(ud);
};


//Setup signal callbacks
world->OnBeforeRepro(RecordParentFun);
world->OnOffspringReady(TrackOffspringFun);
world->OnInjectReady(TrackInjectedOffspringFun);
world->OnUpdate(UpdateFun);
world->OnOrgPlacement(TrackPlacementFun);
//lineage = LineageTracker<ORG, MANAGERS...>(world);

//TODO: Figure out how to make this work automatically
//fit_fun = world->GetFitFun();
}

//Put newly born organism into the lineage tracker
std::function<double(ORG * org)> fit_fun;
void TrackOffspring(ORG * org) {
next_org_id = lineage.AddOrganism(*org, next_parent_id);

}

//Put newly injected organism into the lineage tracker
void TrackInjectedOffspring(ORG * org) {
//std::cout << "Track Injected" << std::endl;
next_org_id = lineage.AddOrganism(*org, -1);

}

//Keep track of location of all orgs in the population so that
//we can translate their ids from the World to ids within the lineage
//tracker
void TrackPlacement(int pos) {
if (pos >= generation_since_update.size()) {
generation_since_update.resize(pos+1);
}
generation_since_update[pos] = next_org_id;
}

//Record the org that's about to have an offspring, so we can know
//who the parent of the next org is.
void RecordParent(int id) {
if (separate_generations){
next_parent_id = past_snapshots.back()[id];
} else {
next_parent_id = generation_since_update[id];
}
}

//Update callback function handles calculating stats
void Update(int update) {
Expand All @@ -138,11 +82,11 @@ namespace evo{
if (update % resolution == 0) {

emp::vector<skeleton_type > persist_skeletons = Skeletonize(
GetPersistLineage(&lineage,
GetPersistLineage(lineage,
past_snapshots[0],
past_snapshots[generations/resolution]));
emp::vector<skeleton_type > prev_persist_skeletons = Skeletonize(
GetPersistLineage(&lineage,
GetPersistLineage(lineage,
past_snapshots[generations/resolution],
past_snapshots[2*generations/resolution]));

Expand All @@ -158,17 +102,11 @@ namespace evo{
int nulls = std::count(skel.begin(), skel.end(), -1);
return (double)(skel.size() - nulls);
});
fittest = MaxFitness(fit_fun, IDsToGenomes(&lineage, past_snapshots[0]));
fittest = MaxFitness(fit_fun, IDsToGenomes(lineage, past_snapshots[0]));
}
std::cout << "Update: " << update << ", Change: " << change << ", Novelty: " << novelty << ", Ecology: " << ecology << ", Complexity: " << complexity << ", MaxFitness: " << fittest << std::endl;
past_snapshots.pop_back();
past_snapshots.push_front(generation_since_update);
}

if (separate_generations) {
//TODO: This isn't sufficient - need to add signals for any
//population change event
generation_since_update.resize(0);
past_snapshots.push_front(lineage->generation_since_update);
}
}

Expand Down
8 changes: 5 additions & 3 deletions examples/evo/NK_OEE.cc
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@
#include "../../tools/Random.h"

constexpr int K = 3;
constexpr int N = 20;
constexpr int N = 10;

constexpr int POP_SIZE = 200;
constexpr int UD_COUNT = 5000;
constexpr int POP_SIZE = 20;
constexpr int UD_COUNT = 500;
constexpr int TOURNAMENT_SIZE = 15;

using BitOrg = emp::BitSet<N>;
Expand All @@ -29,6 +29,8 @@ int main()
emp::evo::NKLandscapeConst<N,K> landscape(random);
emp::evo::World<BitOrg> pop(random);
emp::evo::OEEStatsManager<BitOrg, N> oee_stats(&pop);
emp::evo::LineageTracker<BitOrg> lineage(&pop);
oee_stats.lineage = &lineage;

// Build a random initial population
for (int i = 0; i < POP_SIZE; i++) {
Expand Down