10 #ifndef EMP_EVO_WORLD_SELECT_H 11 #define EMP_EVO_WORLD_SELECT_H 16 #include "../base/array.h" 17 #include "../base/assert.h" 18 #include "../base/vector.h" 19 #include "../base/macros.h" 20 #include "../tools/IndexMap.h" 21 #include "../tools/Random.h" 22 #include "../tools/vector_utils.h" 26 template<
typename ORG>
class World;
33 template<
typename ORG>
39 std::multimap<double, size_t> fit_map;
40 for (
size_t id = 0;
id < world.
GetSize();
id++) {
43 fit_map.insert( std::make_pair(cur_fit,
id) );
48 auto m = fit_map.rbegin();
49 for (
size_t i = 0; i < e_count; i++) {
50 const size_t repro_id = m->second;
60 template<
typename ORG>
68 for (
size_t i = 0; i < r_count; i++) {
85 template<
typename ORG>
87 emp_assert(t_size > 0,
"Cannot have a tournament with zero organisms.", t_size, world.
GetNumOrgs());
92 for (
size_t T = 0; T < tourny_count; T++) {
98 size_t best_id = entries[0];
101 for (
size_t i = 1; i < t_size; i++) {
103 if (cur_fit > best_fit) {
105 best_id = entries[i];
119 template<
typename ORG>
127 for (
size_t id = 0;
id < world.
GetSize();
id++) {
131 for (
size_t n = 0; n < count; n++) {
132 const double fit_pos = random.
GetDouble(fitness_index.GetWeight());
133 const size_t parent_id = fitness_index.Index(fit_pos);
134 const size_t offspring_id = world.
DoBirth( world.
GetGenomeAt(parent_id), parent_id ).GetIndex();
136 fitness_index.Adjust(offspring_id, world.
CalcFitnessID(offspring_id));
142 EMP_CREATE_OPTIONAL_METHOD(TriggerOnLexicaseSelect, TriggerOnLexicaseSelect);
150 template<
typename ORG>
152 const emp::vector< std::function<
double(ORG &)> > & fit_funs,
153 size_t repro_count=1,
161 std::map<typename ORG::genome_t, int> genotype_counts;
166 for (
size_t org_id = 0; org_id < world.
GetSize(); org_id++) {
169 if (
emp::Has(genotype_counts, gen)) {
170 genotype_lists[genotype_counts[gen]].
push_back(org_id);
172 genotype_counts[gen] = genotype_lists.
size();
180 for (
size_t i = 0; i < genotype_lists.
size(); i++) {
184 if (!max_funs) max_funs = fit_funs.
size();
188 for (
size_t fit_id = 0; fit_id < fit_funs.size(); ++fit_id) {
189 fitnesses[fit_id].
resize(genotype_counts.size());
192 for (
auto & gen : genotype_lists) {
193 fitnesses[fit_id][id] = fit_funs[fit_id](world.
GetOrg(gen[0]));
202 for (
size_t repro = 0; repro < repro_count; ++repro) {
207 if (max_funs == fit_funs.size()) {
218 for (
size_t fit_id : order) {
225 double max_fit = fitnesses[fit_id][cur_gens[0]];
226 next_gens.push_back(cur_gens[0]);
228 for (
size_t gen_id : cur_gens) {
230 const double cur_fit = fitnesses[fit_id][gen_id];
232 if (cur_fit > max_fit) {
235 next_gens.push_back(gen_id);
238 else if (cur_fit == max_fit) {
239 next_gens.push_back(gen_id);
244 std::swap(cur_gens, next_gens);
247 if (cur_gens.size() == 1)
break;
251 emp_assert(cur_gens.size() > 0, cur_gens.size(), fit_funs.size(), all_gens.size());
253 for (
size_t gen : cur_gens) {
254 options += genotype_lists[gen].
size();
259 for (
size_t gen : cur_gens) {
260 if (winner < genotype_lists[gen].size()) {
261 repro_id = (int) genotype_lists[gen][winner];
264 winner -= genotype_lists[gen].
size();
266 emp_assert(repro_id != -1, repro_id, winner, options);
272 TriggerOnLexicaseSelect(world, used, repro_id);
281 template<
typename ORG>
299 for (
size_t i=0; i < extra_funs.size(); i++) {
304 for (
size_t org_id = 0; org_id < world.
GetSize(); org_id++) {
306 for (
size_t ex_id = 0; ex_id < extra_funs.size(); ex_id++) {
307 double cur_fit = extra_funs[ex_id](world.
GetOrg(org_id));
308 extra_fitnesses[ex_id][org_id] = cur_fit;
309 if (cur_fit > max_extra_fit[ex_id]) {
310 max_extra_fit[ex_id] = cur_fit;
311 max_count[ex_id] = 1;
313 else if (cur_fit == max_extra_fit[ex_id]) {
320 for (
size_t ex_id = 0; ex_id < extra_funs.size(); ex_id++) {
321 if (max_count[ex_id] == 0)
continue;
324 const double cur_bonus = pool_sizes[ex_id] / max_count[ex_id];
330 for (
size_t org_id = 0; org_id < world.
GetSize(); org_id++) {
332 if (extra_fitnesses[ex_id][org_id] == max_extra_fit[ex_id]) {
333 base_fitness[org_id] += cur_bonus;
340 for (
size_t T = 0; T < tourny_count; T++) {
344 double best_fit = base_fitness[entries[0]];
345 size_t best_id = entries[0];
348 for (
size_t i = 1; i < t_size; i++) {
349 const double cur_fit = base_fitness[entries[i]];
350 if (cur_fit > best_fit) {
352 best_id = entries[i];
362 template<
typename ORG>
364 double pool_sizes,
size_t t_size,
size_t tourny_count=1)
367 EcoSelect(world, extra_funs, pools, t_size, tourny_count);
void Adjust(size_t id, const double new_weight)
Definition: IndexMap.h:176
Random & GetRandom()
Return a reference to the random number generator currently being used by world.
Definition: World.h:770
WorldPosition DoBirth(const genome_t &mem, size_t parent_pos, size_t copy_count=1)
Place one or more copies of an offspring into population; return position of last placed...
Definition: World.h:1244
A versatile and non-patterned pseudo-random-number generator (Mersenne Twister).
Definition: ce_random.h:52
bool IsSynchronous() const
Definition: World.h:284
void push_back(PB_Ts &&...args)
Definition: vector.h:189
Setup a World with a population of organisms that can evolve or deal with ecological effects...
Definition: World.h:94
size_t size() const
Definition: vector.h:151
void emplace_back(ARGS &&...args)
Definition: vector.h:219
constexpr uint32_t GetUInt(const uint32_t max)
Definition: ce_random.h:191
void TournamentSelect(World< ORG > &world, size_t t_size, size_t tourny_count=1)
Definition: World_select.h:86
void RouletteSelect(World< ORG > &world, size_t count=1)
Definition: World_select.h:120
void LexicaseSelect(World< ORG > &world, const emp::vector< std::function< double(ORG &)> > &fit_funs, size_t repro_count=1, size_t max_funs=0)
Definition: World_select.h:151
size_t GetSize() const
How many organisms can fit in the world?
Definition: World.h:245
bool IsCacheOn() const
Are we currently caching fitness values?
Definition: World.h:280
constexpr double GetDouble()
Definition: ce_random.h:166
emp::vector< T > Slice(emp::vector< T > vec, int start, int stop)
Definition: vector_utils.h:101
const genome_t & GetGenomeAt(size_t id)
Retrive the genome corresponding to the organism at the specified position.
Definition: World.h:342
bool Has(const MAP_T &in_map, const KEY_T &key)
Take any map type, and run find to determine if a key is present.
Definition: map_utils.h:21
void resize(size_t new_size)
Definition: vector.h:161
void ClearCache(size_t id)
Clear the cache value at the specified position.
Definition: World.h:195
std::function< double(ORG &)> fun_calc_fitness_t
Function type for calculating fitness.
Definition: World.h:108
void RandomSelect(World< ORG > &world, size_t r_count=1, size_t copy_count=1)
Definition: World_select.h:61
void EliteSelect(World< ORG > &world, size_t e_count=1, size_t copy_count=1)
Definition: World_select.h:34
ORG & GetOrg(size_t id)
Definition: World.h:316
If we are in emscripten, make sure to include the header.
Definition: array.h:37
size_t GetRandomOrgID()
Get the id of a random occupied cell.
Definition: World.h:1274
double CalcFitnessID(size_t id)
Use the configured fitness function on the organism at the specified position.
Definition: World.h:1187
#define emp_assert(...)
Definition: assert.h:199
emp::vector< size_t > GetPermutation(Random &random, size_t size)
Return an emp::vector<int> numbered 0 through size-1 in a random order.
Definition: random_utils.h:40
size_t GetNumOrgs() const
How many organisms are currently in the world?
Definition: World.h:248
Definition: IndexMap.h:23
fun_calc_fitness_t GetFitFun()
Get the fitness function currently in use.
Definition: World.h:400
void EcoSelect(World< ORG > &world, const emp::vector< std::function< double(ORG &)> > &extra_funs, const emp::vector< double > &pool_sizes, size_t t_size, size_t tourny_count=1)
Definition: World_select.h:282
bool IsOccupied(WorldPosition pos) const
Does the specified cell ID have an organism in it?
Definition: World.h:277