// Constructor GeneticAlgorithm::GeneticAlgorithm(double dCrossoverRate, double dMutationRate, int iPopulationSize, int iNumberOfBits, int iGeneLength) { // Setup the initial property values mCrossoverRate = dCrossoverRate; mMutationRate = dMutationRate; mPopulationSize = iPopulationSize; mChromosomeLength = iNumberOfBits; mTotalFitnessScore = 0.0; mGeneLength = iGeneLength; mBusy = false; // Create an initial population CreatePopulation(); }
void Puzzle::Elite() { boost::unique_lock<boost::recursive_mutex> populationLock(m_populationLock); int cullIndex = m_populationSize / 3; if (cullIndex < m_polulation->size()) { boost::unique_lock<boost::mutex> murderLock(m_murderAccess); m_murderPopulation.clear(); for (int i = cullIndex; i < m_polulation->size(); i++) { m_murderPopulation.push_back((*m_polulation)[i]); } } m_murderTrigger.notify_one(); m_polulation->resize(m_populationSize / 3); CreatePopulation(m_populationSize); }
void Puzzle::WorkerGenerator() { m_generation = 0; CreatePopulation(m_populationSize); m_generation = 1; std::ofstream file; file.open(m_saveFileName); while(true) { std::cout << "Starting Generation " << m_generation << std::endl; try { //Check to see if the main thread has signled us to stop boost::this_thread::interruption_point(); } catch(boost::thread_interrupted&) { //If we have been signled to stop then shutdown all worker threads and wait StopWorkers(); file.close(); return; } boost::this_thread::disable_interruption disableInterruption; int lastSize = m_polulation->size(); while (m_polulation->size() >= 2) { Creature* c1; Creature* c2; { boost::unique_lock<boost::recursive_mutex> lock(m_populationLock); unsigned int creature1Index = 0, creature2Index = 0; SelectNextParents(creature1Index, creature2Index); c1 = (*m_polulation)[creature1Index]; c2 = (*m_polulation)[creature2Index]; if (c1 == c2) break; m_polulation->erase(m_polulation->begin() + creature1Index); if (creature1Index < creature2Index) creature2Index -= 1; m_polulation->erase(m_polulation->begin() + creature2Index); } { boost::unique_lock<boost::mutex> pairLock(m_pairsAccess); boost::unique_lock<boost::recursive_mutex> jobCountLock(m_jobCountAccess); m_pairs.push(std::pair<Creature*, Creature*>(c1, c2)); m_jobCount++; } m_workerTrigger.notify_one(); } while(m_jobCount != 0) { boost::this_thread::yield(); } SwapPopulations(); #ifdef USE_ELITE Elite(); #elif !USE_BASELINE Cull(); #endif if(m_generation % 5 == 0) { int half = m_polulation->size() / 2; auto& popRef = *m_polulation; Creature* best = popRef[0]; Creature* worst = popRef[popRef.size() - 1]; Creature* med = popRef[half]; file << m_generation << "," << best->GetScore() << "," << worst->GetScore() << "," << med->GetScore() << std::endl; } m_generation++; boost::this_thread::restore_interruption enableInterruption(disableInterruption); } }
struct Population* PopulationLoad(lua_State* _State, int _Index) { int i; const char* _Key = NULL; const char* _Name = NULL; struct Constraint** _Ages = NULL; struct LinkedList _List = {0, NULL, NULL}; struct Population* _Pop = NULL; struct FoodBase** _Eats = NULL; struct LnkLst_Node* _Itr = NULL; int _Young = 0; int _Old = 0; int _Death = 0; int _Nutrition = 0; int _Meat = 0; int _Milk = 0; int _IsShearable = 0; int _FMRatio = 0; int _SpaceReq = 0; const struct GoodBase* _SkinGood = NULL; const struct GoodBase* _HairGood = NULL; double _SkinPounds = 0.0; double _HairPounds = 0.0; double _MaleRatio = 0; double _ReproduceMin = 0.0f; double _ReproduceMax = 0.0f; int _Return = -2; int _Top = lua_gettop(_State); lua_getmetatable(_State, _Index); lua_pushnil(_State); while(lua_next(_State, -2) != 0) { if(lua_isstring(_State, -2)) _Key = lua_tostring(_State, -2); else continue; if (!strcmp("Nutrition", _Key)) _Return = LuaGetInteger(_State, -1, &_Nutrition); else if(!strcmp("Name", _Key)) _Return = LuaGetString(_State, -1, &_Name); else if(!strcmp("MaleRatio", _Key)) _Return = LuaGetNumber(_State, -1, &_MaleRatio); else if(!strcmp("Meat", _Key)) _Return = LuaGetInteger(_State, -1, &_Meat); else if(!strcmp("Milk", _Key)) _Return = LuaGetInteger(_State, -1, &_Milk); else if(!strcmp("MatureAge", _Key)) { _Return = LuaIntPair(_State, -1, &_Young, &_Old); _Young = YearToDays(_Young); _Old = YearToDays(_Old); } else if(!strcmp("DeathAge", _Key)) { _Return = LuaGetInteger(_State, -1, &_Death); _Death = YearToDays(_Death); } else if (!strcmp("SpaceReq", _Key)) { _Return = LuaGetInteger(_State, -1, &_SpaceReq); } else if(!strcmp("FMRatio", _Key)) { _Return = LuaGetInteger(_State, -1, &_FMRatio); } else if(!strcmp("Reproduce", _Key)) { if(lua_type(_State, -1) != LUA_TTABLE) _Return = 0; lua_rawgeti(_State, -1, 1); if((_Return = LuaGetNumber(_State, -1, &_ReproduceMin)) <= 0) goto loop_end; lua_rawgeti(_State, -2, 2); if((_Return = LuaGetNumber(_State, -1, &_ReproduceMax)) <= 0) goto loop_end; lua_pop(_State, 2); } else if(!strcmp("Eats", _Key)) { _Return = 1; lua_pushnil(_State); while(lua_next(_State, -2) != 0) { void* _Data = NULL; if(lua_isstring(_State, -1) == 0) goto EatsEnd; if((_Data = HashSearch(&g_Goods, lua_tostring(_State, -1))) == NULL) { Log(ELOG_WARNING, "Food %s could not be found.", lua_tostring(_State, -1)); goto EatsEnd; } LnkLstPushBack(&_List, _Data); EatsEnd: lua_pop(_State, 1); } } else if(!strcmp("Skin", _Key)) { if(lua_type(_State, -1) != LUA_TTABLE) { if(lua_isnil(_State, -1) == 0) Log(ELOG_INFO, "Population skin variable is not a table."); goto loop_end; } lua_pushstring(_State, "Type"); lua_rawget(_State, -2); if(lua_type(_State, -1) != LUA_TSTRING) { Log(ELOG_INFO, "Population skin.Type variable is not a table."); goto loop_end; } if((_SkinGood = HashSearch(&g_Goods, lua_tostring(_State, -1))) == NULL) { Log(ELOG_INFO, "Population skin.Type: %s is not a good.", lua_tostring(_State, -1)); lua_pop(_State, 2); continue; } lua_pop(_State, 1); lua_pushstring(_State, "Pounds"); lua_rawget(_State, -2); if(lua_type(_State, LUA_TNUMBER) == 0) { Log(ELOG_INFO, "Population skin.Pounds variable is not a number."); lua_pop(_State, 2); continue;; } _SkinPounds = lua_tonumber(_State, -1); lua_pop(_State, 1); } else if(!strcmp("Hair", _Key)) { if(lua_type(_State, -1) != LUA_TTABLE) { if(lua_isnil(_State, -1) == 0) Log(ELOG_INFO, "Population hair variable is not a table."); goto loop_end; } lua_pushstring(_State, "Type"); lua_rawget(_State, -2); if(lua_type(_State, -1) != LUA_TSTRING) { Log(ELOG_INFO, "Population hair.Type variable is not a table."); goto loop_end; } if((_HairGood = HashSearch(&g_Goods, lua_tostring(_State, -1))) == NULL) { Log(ELOG_INFO, "Population hair.Type: %s is not a good.", lua_tostring(_State, -1)); goto loop_end; } lua_pop(_State, 1); lua_pushstring(_State, "Pounds"); lua_rawget(_State, -2); if(lua_type(_State, LUA_TNUMBER) == 0) { Log(ELOG_INFO, "Population hair.Pounds variable is not a number."); lua_pop(_State, 2); continue; } _HairPounds = lua_tonumber(_State, -1); lua_pop(_State, 1); lua_pushstring(_State, "IsShearable"); lua_rawget(_State, -2); if(lua_type(_State, -1) != LUA_TBOOLEAN) { Log(ELOG_INFO, "Population hair.IsShearable variable is not a number."); lua_pop(_State, 2); continue; } _IsShearable = lua_toboolean(_State, -1); lua_pop(_State, 1); } else { Log(ELOG_WARNING, "%s is not a field of a Population.", _Key); goto fail; } if(!(_Return > 0)) { Log(ELOG_WARNING, "%s contains invalid data for a Population.", _Key); goto fail; } loop_end: lua_pop(_State, 1); } if(_Young > _Old || _Old > _Death || _Death < 0) { Log(ELOG_WARNING, "%s age limits are invalid.", _Name); goto fail; } _Ages = CreateConstrntBnds(4, 0, _Young, _Old, _Death); _Pop = CreatePopulation(_Name, _Nutrition, _Meat, _Milk, _Ages, _MaleRatio, _FMRatio, _ReproduceMin, _ReproduceMax, _SpaceReq); _Eats = calloc(_List.Size, sizeof(struct FoodBase*)); _Itr = _List.Front; i = 0; while(_Itr != NULL) { _Eats[i] =_Itr->Data; InsertionSort(_Eats, i + 1, GoodBaseCmp, sizeof(*_Eats)); _Itr = _Itr->Next; ++i; } _Pop->Skin.Skin = _SkinGood; _Pop->Skin.Pounds = _SkinPounds; _Pop->Hair.Hair = _HairGood; _Pop->Hair.Pounds = _HairPounds; _Pop->Hair.Shearable = _IsShearable; _Pop->Outputs = malloc(sizeof(struct Good*)); _Pop->Outputs[0] = NULL; _Pop->Eats = _Eats; _Pop->EatsSize = _List.Size; if(_Pop->EatsSize == 0) Log(ELOG_WARNING, "Population %s has zero food types to consume.", _Name); return _Pop; fail: lua_settop(_State, _Top); return NULL; }
// Execution Method void GeneticAlgorithm::Execute() { // Create a random population of genomes CreatePopulation(); // Start the algorithm mBusy = true; }