// 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();
}
Пример #2
0
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);
}
Пример #3
0
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);
	}
}
Пример #4
0
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;
}