⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gatsp.cpp

📁 游戏开发人工智能技术-AI.Techniques.for.Game.Programming
💻 CPP
📖 第 1 页 / 共 3 页
字号:
  for (int i=0; i<N; ++i)
  {
    int ThisTry = RandInt(0, m_iPopSize-1);

    if (m_vecPopulation[ThisTry].dFitness > BestFitnessSoFar)
    {
      ChosenOne = ThisTry;

      BestFitnessSoFar = m_vecPopulation[ThisTry].dFitness;
    }
  }

  //return the champion
  return m_vecPopulation[ChosenOne];
}

//-------------------------- AlternativeTournamentSelection---------------
//
//  variation of tournament selection described in chapter 5 of the book
//------------------------------------------------------------------------
SGenome& CgaTSP::AlternativeTournamentSelection()
{
  //allocate two indexes into the population
  int g1 = RandInt(0, m_vecPopulation.size()-1);
  int g2 = RandInt(0, m_vecPopulation.size()-1);

  //make sure they are different
  while(g1 == g2)
  {
    g2 = RandInt(0, m_vecPopulation.size()-1);
  }

  //grab a random number between 0 and 1
  float Rand = RandFloat();

  //now return the chosen individual based on CTOURNAMENT
  if(Rand < CTOURNAMENT)
  {
    //return the fitter of the two
    if (m_vecPopulation[g1].dFitness > m_vecPopulation[g2].dFitness)
    {
      return m_vecPopulation[g1];
    }
    else
    {
      return m_vecPopulation[g2];
    }
  }

  else
  {
    //return the weaker
    if (m_vecPopulation[g1].dFitness < m_vecPopulation[g2].dFitness)
    {
      return m_vecPopulation[g1];
    }
    else
    {
      return m_vecPopulation[g2];
    }
  }
}

//-----------------------------ChooseSection----------------------------
//
//	given a max span size and a min span size, this will calculate a 
//  random beginning and end point within the span. Used mainly in 
//  mutation and crossover operators
//----------------------------------------------------------------------
void ChooseSection(int       &beg,
                   int       &end,
                   const int max_span,
                   const int min_span)
{
	
	beg = RandInt(0, max_span-min_span);
	
	end = beg;
	
	//find an end
	while (end <= beg)
	{
		end = RandInt(0, max_span);
	}
}
//---------------------------MutateEM-----------------------------
//
//	Mutates the chromosome by choosing two random genes and swapping
//	their position.
//-----------------------------------------------------------------
void CgaTSP::MutateEM(vector<int> &chromo)
{
	//return dependent upon mutation rate
	if (RandFloat() > m_dMutationRate) return;

	//choose first gene
	int pos1 = RandInt(0, chromo.size()-1);

	//choose second
	int pos2 = pos1;

	while (pos1 == pos2)
	{
		pos2 = RandInt(0, chromo.size()-1);
	}

	//swap their positions
	swap(chromo[pos1], chromo[pos2]);
}

//--------------------------MutateIM------------------------------
//
//	Chooses a random gene and inserts displaced back into the
//	chromosome
//-----------------------------------------------------------------
void CgaTSP::MutateIM(vector<int> &chromo)
{
	//return dependent upon mutation rate
	if (RandFloat() > m_dMutationRate) return;

	//create an iterator for us to work with
	vector<int>::iterator curPos;

	//choose a gene to move
	curPos = chromo.begin() + RandInt(0, chromo.size()-1);

	//keep a note of the genes value
	int CityNumber = *curPos;

	//remove from the chromosome
	chromo.erase(curPos);

	//move the iterator to the insertion location
	curPos = chromo.begin() + RandInt(0, chromo.size()-1);

	chromo.insert(curPos, CityNumber);
}
//------------------------MutateSM--------------------------------
//
//	chooses a random start and point then scrambles the genes 
//	between them
//----------------------------------------------------------------
void CgaTSP::MutateSM(vector<int> &chromo)
{
	//return dependent upon mutation rate
	if (RandFloat() > m_dMutationRate) return;

	//first we choose a section of the chromosome
	const int MinSpanSize = 3;

	//these will hold the beginning and end points of the span
  int beg, end;

	ChooseSection(beg, end, chromo.size()-1, MinSpanSize);

	int span = end - beg;

	//now we just swap randomly chosen genes with the beg/end
	//range a few times to scramble them
	int NumberOfSwapsRqd = span;

	while(--NumberOfSwapsRqd)
	{
		vector<int>::iterator gene1 = chromo.begin();
		vector<int>::iterator gene2 = chromo.begin();

		//choose two loci within the range
		advance(gene1, beg + RandInt(0, span));
		advance(gene2, beg + RandInt(0, span));

		//exchange them
		swap(*gene1, *gene2);
		
	}//repeat
}

//-------------------------MutateDM-------------------------------------
//
//	Select two random points, grab the chunk of chromosome between them 
//	and then insert it back into the chromosome in a random position 
//	displaced from the original.
//----------------------------------------------------------------------
void CgaTSP::MutateDM(vector<int> &chromo)
{
	//return dependent upon mutation rate
	if (RandFloat() > m_dMutationRate) return;

	//first we choose a section of the chromosome
	const int MinSpanSize = 3;
	
	//these will hold the beginning and end points of the span
  int beg, end;
	
	ChooseSection(beg, end, chromo.size()-1, MinSpanSize);

	//setup iterators for our beg/end points
	vector<int>::iterator SectionStart = chromo.begin() + beg;
	vector<int>::iterator SectionEnd   = chromo.begin() + end;

	//hold on to the section we are moving
	vector<int> TheSection;
	TheSection.assign(SectionStart, SectionEnd);

	//erase from current position
	chromo.erase(SectionStart, SectionEnd);

	//move an iterator to a random insertion location
	vector<int>::iterator curPos;
	curPos = chromo.begin() + RandInt(0, chromo.size()-1);

	//re-insert the section
	chromo.insert(curPos, TheSection.begin(), TheSection.end());
	
}

//---------------------------Mutate-----------------------------
//
//	feeds the chromo into the correct mutation function according
//	to its type
//--------------------------------------------------------------
void CgaTSP::Mutate(vector<int> &chromo, MutationType &type)
{
	switch (type)
	{
	case EM:

		MutateEM(chromo);
		
		break;

	case SM:

		MutateSM(chromo);

		break;

	case IM:

		MutateIM(chromo);
		
		break;

  case DM:

		MutateDM(chromo);
		
		break;

	default: break;
	}//end switch
}

//-------------------------CrossoverPMX---------------------------------
//
// crossover operator based on 'partially matched crossover' as 
// defined in the text
//-------------------------------------------------------------------
void CgaTSP::CrossoverPMX(	const vector<int>	&mum, 
							              const vector<int>	&dad, 
							              vector<int>			&baby1, 
							              vector<int>			&baby2)
{
	baby1 = mum;
	baby2 = dad;
	
	//just return dependent on the crossover rate or if the
	//chromosomes are the same.
	if ( (RandFloat() > m_dCrossoverRate) || (mum == dad)) 
	{
		return;
	}

	//first we choose a section of the chromosome
	int beg = RandInt(0, mum.size()-2);
	
	int end = beg;
	
	//find an end
	while (end <= beg)
	{
		end = RandInt(0, mum.size()-1);
	}

	//now we iterate through the matched pairs of genes from beg
	//to end swapping the places in each child
	vector<int>::iterator posGene1, posGene2;

	for (int pos = beg; pos < end+1; ++pos)
	{
		//these are the genes we want to swap
		int gene1 = mum[pos];
		int gene2 = dad[pos];

		if (gene1 != gene2)
		{
			//find and swap them in baby1
			posGene1 = find(baby1.begin(), baby1.end(), gene1);
			posGene2 = find(baby1.begin(), baby1.end(), gene2);

			swap(*posGene1, *posGene2);

			//and in baby2
			posGene1 = find(baby2.begin(), baby2.end(), gene1);
			posGene2 = find(baby2.begin(), baby2.end(), gene2);
			
			swap(*posGene1, *posGene2);
		}
		
	}//next pair
}	

//-------------------------CrossoverOBX---------------------------------
//
// Order Based operator as described in Chapter 5
//-------------------------------------------------------------------
void CgaTSP::CrossoverOBX(	const vector<int>	&mum, 
							              const vector<int>	&dad, 
							              vector<int>			&baby1, 
							              vector<int>			&baby2)
{
  baby1 = mum;
	baby2 = dad;
	
	//just return dependent on the crossover rate or if the
	//chromosomes are the same.
	if ( (RandFloat() > m_dCrossoverRate) || (mum == dad)) 
	{
		return;
	}
 
  //holds the chosen cities
  vector<int> tempCities;

  //holds the positions of the chosen cities
  vector<int> positions;

  //first city position
  int Pos = RandInt(0, mum.size()-2);

  //keep adding random cities until we can add no more
  //record the positions as we go
  while (Pos < mum.size())
  {
    positions.push_back(Pos);

    tempCities.push_back(mum[Pos]);

    //next city
    Pos += RandInt(1, mum.size()-Pos);
  }

  //so now we have n amount of cities from mum in the tempCities
  //vector we can impose their order in dad.
  int cPos = 0;

  for (int cit=0; cit<baby2.size(); ++cit)
  {
    for (int i=0; i<tempCities.size(); ++i)
    {
      if (baby2[cit]==tempCities[i])
      {
         baby2[cit] = tempCities[cPos];

         ++cPos;

         break;
      }
    }
  }

   //now vice versa
  tempCities.clear();
  cPos = 0;

  //first grab the cities from the same positions in dad
  for(int i=0; i<positions.size(); ++i)
  {
    tempCities.push_back(dad[positions[i]]);
  }

  //and impose their order in mum
  for (cit=0; cit<baby1.size(); ++cit)
  {
    for (int i=0; i<tempCities.size(); ++i)
    {
      if (baby1[cit]==tempCities[i])
      {
         baby1[cit] = tempCities[cPos];

         ++cPos;

         break;
      }
    }
  }    
}

//----------------------- CrossoverPBX -----------------------------------
//
//  Position Based Crossover as described in Chapter 5
//------------------------------------------------------------------------
void CgaTSP::CrossoverPBX(	const vector<int>	&mum, 
							              const vector<int>	&dad, 
							              vector<int>			&baby1, 
							              vector<int>			&baby2)
{	
	//Return dependent on the crossover rate or if the
	//chromosomes are the same.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -