Example #1
0
//-------------------------------CreatePhenotype--------------------------
//
//	Creates a neural network based upon the information in the genome.
//	Returns a pointer to the newly created ANN
//------------------------------------------------------------------------
CNeuralNet* CGenome::CreatePhenotype()
{
	//first make sure there is no existing phenotype for this genome
	DeletePhenotype();

	//this will hold all the neurons required for the phenotype
	vector<SNeuron*>  vecNeurons;

	//first, create all the required neurons
	for (int i=0; i<m_vecNeurons.size(); i++)
	{
		SNeuron* pNeuron = new SNeuron(m_vecNeurons[i].NeuronType,
			m_vecNeurons[i].iID,
			m_vecNeurons[i].dSplitY,
			m_vecNeurons[i].dSplitX,
			m_vecNeurons[i].dActivationResponse);

		vecNeurons.push_back(pNeuron);
	}

	//now to create the links. 
	for (int cGene=0; cGene<m_vecLinks.size(); ++cGene)
	{
		//make sure the link gene is enabled before the connection is created
		if (m_vecLinks[cGene].bEnabled)
		{
			//get the pointers to the relevant neurons
			int element         = GetElementPos(m_vecLinks[cGene].FromNeuron);
			SNeuron* FromNeuron = vecNeurons[element];

			element           = GetElementPos(m_vecLinks[cGene].ToNeuron);
			SNeuron* ToNeuron = vecNeurons[element];

			//create a link between those two neurons and assign the weight stored
			//in the gene
			SLink tmpLink(m_vecLinks[cGene].dWeight,
				FromNeuron,
				ToNeuron,
				m_vecLinks[cGene].bRecurrent);

			//add new links to neuron
			FromNeuron->vecLinksOut.push_back(tmpLink);
			ToNeuron->vecLinksIn.push_back(tmpLink);
		}
	}

	//now the neurons contain all the connectivity information, a neural
	//network may be created from them.
	m_pPhenotype = new CNeuralNet(vecNeurons, m_iNetDepth);

	return m_pPhenotype;
}
Example #2
0
bool BContainer::DeleteChildren(BItem* currentProperty)
{
	BItem* el;
	UINT parentOffset = 0;
	int i;
	i = GetElementPos(currentProperty);
	if(i < 0)
		return false;
	//am gasit elementul, vad daca are copii
	int j = i+1;
	parentOffset = currentProperty->offset;
	while(j<vElements.GetSize())
	{
		el = (BItem*)vElements.GetPointer(j);
		if(el->offset > parentOffset)
		{
			el->ShowWindow(SW_HIDE);
			vElements.Delete(j);
		}
		else
			break;
	}
	el = GetElement(i);
	el->collapsed = ITEM_NO_COLLAPSE;
		
	return true;
}
Example #3
0
bool BContainer::MoveElement(BItem* el, unsigned int newPos)
{
	BItem* oldParent,*newParent;
	BItem* nextEl;
	bool foundChild = false;
	int i = GetElementPos(el);	
	


	if( i>= newPos)
		i+=1;
	if(!vElements.Insert(&el,newPos))
		return false;

	//verifica daca vechiul parinte mai are copii
	oldParent  = GetParent(i);

	if(vElements.Delete(i)==false)
		return false;
	//verific daca vechiul parinte mai are copii pentru a-i seta starea de collapse
	
	if(oldParent == NULL)
		return true;
	if( i <vElements.GetSize())
	{
		nextEl = (BItem*)vElements.GetPointer(i);
		if(nextEl->offset > oldParent->offset)
			foundChild = true;
		else
			foundChild = false;
	}
	if(!foundChild)
		oldParent->collapsed = ITEM_NO_COLLAPSE;
	else
		oldParent->collapsed = ITEM_COLLAPSED;
	
	
	//verific daca in urma introducerii elementului a aparut un parinte pentru noul element
	newParent = GetParent(newPos);
	if(newParent != NULL)
		newParent->collapsed = ITEM_COLLAPSED;
	return true;

}
Example #4
0
bool BContainer::DeleteElement(BItem* currentProperty)
{
	BItem* el;
	BItem* parent;
	UINT parentOffset = 0;
	int i;
	i = GetElementPos(currentProperty);
	if(i < 0)
		return false;
	int j = i+1;
	parentOffset = currentProperty->offset;

	while(j<vElements.GetSize())
	{
		el = (BItem*)vElements.GetPointer(j);
		if(el->offset > parentOffset)
		{
			el->ShowWindow(SW_HIDE);
			vElements.Delete(j);
		}
		else
			break;
	}

	el = (BItem*)vElements.GetPointer(i);
	el->ShowWindow(SW_HIDE);
	
	parent = this->GetParent(i);		
	vElements.Delete(i);

	if(!HasChildren(parent))
		parent->collapsed = ITEM_NO_COLLAPSE;
	
	return true;
	

}
Example #5
0
 /// \brief
 ///   Indicates whether the passed handler is registered to this callback
 /// 
 /// \param pHandler
 ///   A handler to test
 /// 
 /// \return
 ///   \c TRUE if handler is registered in this callback; \c FALSE if not
 /// 
 /// \sa VCallback::RegisterCallback
 /// \sa VCallback::TriggerCallbacks
 /// \sa class IVisCallbackHandler_cl
 inline BOOL IsRegistered(IVisCallbackHandler_cl *pHandler) {VASSERT(pHandler);return GetElementPos(pHandler)>=0;}
Example #6
0
//---------------------------------AddNeuron------------------------------
//
//	this function adds a neuron to the genotype by examining the network, 
//	splitting one of the links and inserting the new neuron.
//------------------------------------------------------------------------
void CGenome::AddNeuron(double MutationRate, CInnovation &innovations, int NumTrysToFindOldLink) {
	//just return dependent on mutation rate
	if (RandFloat() > MutationRate) return;

	//if a valid link is found into which to insert the new neuron
	//this value is set to true.
	bool bDone = false;

	//this will hold the index into m_vecLinks of the chosen link gene
	int  ChosenLink = 0;

	//first a link is chosen to split. If the genome is small the code makes 
	//sure one of the older links is split to ensure a chaining effect does
	//not occur. Here, if the genome contains less than 5 hidden neurons it
	//is considered to be too small to select a link at random
	const int SizeThreshold = m_iNumInputs + m_iNumOutPuts + 10;

	if (m_vecLinks.size() < SizeThreshold)
	{    
		while(NumTrysToFindOldLink--)
		{
			//choose a link with a bias towards the older links in the genome 
			ChosenLink = RandInt(0, NumGenes()-1-(int)sqrt((double)NumGenes()));

			//make sure the link is enabled and that it is not a recurrent link 
			//or has a bias input
			int FromNeuron = m_vecLinks[ChosenLink].FromNeuron;

			if ( (m_vecLinks[ChosenLink].bEnabled)    && 
				(!m_vecLinks[ChosenLink].bRecurrent) &&
				(m_vecNeurons[GetElementPos(FromNeuron)].NeuronType != bias)) 
			{
				bDone = true;

				NumTrysToFindOldLink = 0;
			}
		}

		if (!bDone)
		{
			//failed to find a decent link
			return;
		}
	}

	else
	{
		//the genome is of sufficient size for any link to be acceptable
		while (!bDone)
		{
			ChosenLink = RandInt(0, NumGenes()-1);

			//make sure the link is enabled and that it is not a recurrent link 
			//or has a BIAS input
			int FromNeuron = m_vecLinks[ChosenLink].FromNeuron;

			if ( (m_vecLinks[ChosenLink].bEnabled) && 
				(!m_vecLinks[ChosenLink].bRecurrent) &&
				(m_vecNeurons[GetElementPos(FromNeuron)].NeuronType != bias)) 
			{
				bDone = true;
			}
		}
	}

	// Get the type of the neuron to add - hidden or modulatory
	neuron_type type = hidden;
	if (CParams::bAdaptable && RandFloat() < CParams::dModulatoryChance) {
		type = modulatory;
	}

	//disable this gene
	m_vecLinks[ChosenLink].bEnabled = false;

	//grab the weight from the gene (we want to use this for the weight of
	//one of the new links so that the split does not disturb anything the 
	//NN may have already learned...
	double OriginalWeight = m_vecLinks[ChosenLink].dWeight;

	//identify the neurons this link connects
	int from =  m_vecLinks[ChosenLink].FromNeuron;
	int to   =  m_vecLinks[ChosenLink].ToNeuron;

	//calculate the depth and width of the new neuron. We can use the depth
	//to see if the link feeds backwards or forwards
	double NewDepth = (m_vecNeurons[GetElementPos(from)].dSplitY + 
		m_vecNeurons[GetElementPos(to)].dSplitY) /2;

	double NewWidth = (m_vecNeurons[GetElementPos(from)].dSplitX + 
		m_vecNeurons[GetElementPos(to)].dSplitX) /2;

	//Now to see if this innovation has been created previously by
	//another member of the population
	int id = innovations.CheckInnovation(from,
		to,
		new_neuron);

	/*it is possible for NEAT to repeatedly do the following:

	1. Find a link. Lets say we choose link 1 to 5
	2. Disable the link,
	3. Add a new neuron and two new links
	4. The link disabled in Step 2 may be re-enabled when this genome
	is recombined with a genome that has that link enabled.
	5  etc etc

	Therefore, this function must check to see if a neuron ID is already 
	being used. If it is then the function creates a new innovation
	for the neuron. */
	if (id >= 0)
	{
		int NeuronID = innovations.GetNeuronID(id);

		if (AlreadyHaveThisNeuronID(NeuronID))
		{
			id = -1;
		}
	}

	if (id < 0)
	{
		//add the innovation for the new neuron
		int NewNeuronID = innovations.CreateNewInnovation(from,
			to,
			new_neuron,
			type,
			NewWidth,
			NewDepth);

		//create the new neuron gene and add it.
		m_vecNeurons.push_back(SNeuronGene(type,
			NewNeuronID,
			NewDepth,
			NewWidth));

		//Two new link innovations are required, one for each of the 
		//new links created when this gene is split.

		//-----------------------------------first link

		//get the next innovation ID
		int idLink1 = innovations.NextNumber();

		//create the new innovation
		innovations.CreateNewInnovation(from,
			NewNeuronID,
			new_link);

		//create the new link gene
		SLinkGene link1(from,
			NewNeuronID,
			true,
			idLink1,
			1.0);

		m_vecLinks.push_back(link1);

		//-----------------------------------second link

		//get the next innovation ID
		int idLink2 = innovations.NextNumber();

		//create the new innovation
		innovations.CreateNewInnovation(NewNeuronID,
			to,
			new_link);

		//create the new gene
		SLinkGene link2(NewNeuronID,
			to,
			true,
			idLink2,
			OriginalWeight);

		m_vecLinks.push_back(link2);
	}

	else
	{
		//this innovation has already been created so grab the relevant neuron 
		//and link info from the innovation database
		int NewNeuronID = innovations.GetNeuronID(id);

		//get the innovation IDs for the two new link genes.
		int idLink1 = innovations.CheckInnovation(from, NewNeuronID, new_link);
		int idLink2 = innovations.CheckInnovation(NewNeuronID, to, new_link);

		//this should never happen because the innovations *should* have already 
		//occurred
		if ( (idLink1 < 0) || (idLink2 < 0) )
		{
			MessageBox(NULL, "Error in CGenome::AddNeuron", "Problem!", MB_OK);

			return;
		}

		//now we need to create 2 new genes to represent the new links
		SLinkGene link1(from, NewNeuronID, true, idLink1, 1.0);
		SLinkGene link2(NewNeuronID, to, true, idLink2, OriginalWeight);

		m_vecLinks.push_back(link1);
		m_vecLinks.push_back(link2);

		//create the new neuron
		SNeuronGene NewNeuron(type, NewNeuronID, NewDepth, NewWidth);

		//and add it
		m_vecNeurons.push_back(NewNeuron);		
	}

	return;
}
Example #7
0
//--------------------------------AddLink---------------------------------
//
// create a new link with the probability of CParams::dChanceAddLink
//------------------------------------------------------------------------
void CGenome::AddLink(double       MutationRate,
	double       ChanceOfLooped,
	CInnovation  &innovation,
	int          NumTrysToFindLoop,
	int          NumTrysToAddLink)
{
	//just return dependent on the mutation rate
	if (RandFloat() > MutationRate) return;

	//define holders for the two neurons to be linked. If we have find two 
	//valid neurons to link these values will become >= 0.
	int ID_neuron1 = -1;
	int ID_neuron2 = -1;

	//flag set if a recurrent link is selected (looped or normal)
	bool bRecurrent = false;

	//first test to see if an attempt shpould be made to create a 
	//link that loops back into the same neuron
	if (RandFloat() < ChanceOfLooped)
	{
		//YES: try NumTrysToFindLoop times to find a neuron that is not an
		//input or bias neuron and that does not already have a loopback
		//connection
		while(NumTrysToFindLoop--)
		{      
			//grab a random neuron
			int NeuronPos = RandInt(m_iNumInputs+1, m_vecNeurons.size()-1);

			//check to make sure the neuron does not already have a loopback 
			//link and that it is not an input or bias neuron
			if (!m_vecNeurons[NeuronPos].bRecurrent && 
				(m_vecNeurons[NeuronPos].NeuronType != bias) && 
				(m_vecNeurons[NeuronPos].NeuronType != input))
			{
				ID_neuron1 = ID_neuron2 = m_vecNeurons[NeuronPos].iID;

				m_vecNeurons[NeuronPos].bRecurrent = true;

				bRecurrent = true;

				NumTrysToFindLoop = 0;
			}
		}
	}

	else
	{		
		//No: try to find two unlinked neurons. Make NumTrysToAddLink
		//attempts
		while(NumTrysToAddLink--)
		{
			//choose two neurons, the second must not be an input or a bias
			ID_neuron1 = m_vecNeurons[RandInt(0, m_vecNeurons.size()-1)].iID;

			ID_neuron2 =
				m_vecNeurons[RandInt(m_iNumInputs+1, m_vecNeurons.size()-1)].iID;

			if (ID_neuron2 == 2)
			{
				continue;
			}

			//make sure these two are not already linked and that they are
			//not the same neuron
			if (DuplicateLink(ID_neuron1, ID_neuron2) ||
				(ID_neuron1 == ID_neuron2))
			{

				ID_neuron1 = -1;
				ID_neuron2 = -1;
			}

			else
			{
				NumTrysToAddLink = 0;
			}
		}
	}

	//return if unsuccessful in finding a link
	if ( (ID_neuron1 < 0) || (ID_neuron2 < 0) )
	{
		return;
	}

	//check to see if we have already created this innovation
	int id = innovation.CheckInnovation(ID_neuron1, ID_neuron2, new_link);

	//is this link recurrent?
	if (m_vecNeurons[GetElementPos(ID_neuron1)].dSplitY > 
		m_vecNeurons[GetElementPos(ID_neuron2)].dSplitY)
	{
		bRecurrent = true;
	}

	if ( id < 0)
	{
		//we need to create a new innovation
		innovation.CreateNewInnovation(ID_neuron1, ID_neuron2, new_link);

		//then create the new gene
		int id = innovation.NextNumber() - 1;

		SLinkGene NewGene(ID_neuron1,
			ID_neuron2,
			true,
			id,
			RandomClamped(),
			bRecurrent);

		m_vecLinks.push_back(NewGene);
	}

	else
	{
		//the innovation has already been created so all we need to
		//do is create the new gene using the existing innovation ID
		SLinkGene NewGene(ID_neuron1,
			ID_neuron2,
			true,
			id,
			RandomClamped(),
			bRecurrent);

		m_vecLinks.push_back(NewGene);
	}

	return;
}