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

📄 extrema.cpp

📁 Implementation of genetic algorithm, to search for desired extreme n-variable function.
💻 CPP
📖 第 1 页 / 共 2 页
字号:
{
	ArrayOfGenotyp->clear();
     GenotypyPoczatkowe->clear();

	while(ArrayOfGenotyp->count() < LGenotypow)
     {
          TGenotyp* Genotyp = new TGenotyp(WektorZakresow.get(), PFuncOceny, Precyzja);
		ArrayOfGenotyp->add(Genotyp);
          GenotypyPoczatkowe->add(new TGenotyp(*Genotyp));
     }

}

//--------------------------------------------------------------------------
void __fastcall TPopulacja::Selekcja(void)
{
	// zastosowana selekcja rankingowa
	// wybor osobnik?w zgodnie z przypisana im ranga zale?nej od warto?ci
	// przystosowania

	register double Value;

	// sprawdz, czy drugiego takiego egzemplarza nie ma na licie,
	// jesli jest, usun
	for(register unsigned i = 0; i < ArrayOfGenotyp->count(); i++)
	{
		Value = ArrayOfGenotyp->item(i)->Get_Fitnes();
		for(register unsigned j = ArrayOfGenotyp->count() - 1; j > i; j--)
    			if(Value == ArrayOfGenotyp->item(j)->Get_Fitnes())
               	ArrayOfGenotyp->erase(j);
    	}

	// wyszukaj extremalne wartosci przystosowania dla populacji
	register double Maximum = SzukajMaximum();
	register double Minimum = SzukajMinimum();

     register unsigned Licznik = 0;
	while(ArrayOfGenotyp->count() > LGenotypowDoc && Licznik++ < LGenotypowDoc * 10)
	// przgladaj kolejno liste osobnikow od konca
	for(register int i = ArrayOfGenotyp->count() - 1; i >= 0; i--)
	{
		// pobierz wartosc przystosowania
		register double Value = ArrayOfGenotyp->item(i)->Get_Fitnes();

		// jesli dany fenotyp osobnika poza zakresem poszukiwan
		// usun osobnika, i kontynuuj od poczatku
		if(!SprawdzFenotypy(ArrayOfGenotyp->item(i)))
		{
			ArrayOfGenotyp->erase(i);
			continue;
		}
          // znacznik
          bool DoUsuniecia = false;
		// w zaleznosci od kryterium
		switch(EXT)
		{
			case MAXIMUM:
			{
				// jesli wylosowana liczba jest wieksza
				if(random(100) > ((int) (100 * (Value - Minimum) / (Maximum - Minimum))))
                         DoUsuniecia = true;
			} break;
			case MINIMUM:
			{
				// jesli wylosowana liczba jest mniejsza
                    if(random(100) < ((int) (100 * (Value - Minimum) / (Maximum - Minimum))))
                         DoUsuniecia = true;
			}break;
		}
          if(DoUsuniecia) ArrayOfGenotyp->erase(i);
	}
}
//--------------------------------------------------------------------------
void __fastcall TPopulacja::Mutacja(void)
{
	// pobierz liczbe genotypow
	register int LiczbaGenotypow = ArrayOfGenotyp->count();
	// pobierz liczbe chromosomow genotypu
	register int LiczbaChromosomow = WektorZakresow->count();
	// przegladaj liste genotypow
	for(register int i = LiczbaGenotypow - 1; i >= 0; i--)
	{
		// losuj liczbe, jesli mniejsza od prawdopodobienstwa
		// mutacji, dokonaj mutacji bezacego osobnika (genotypu)
		if(PMutacji >= (unsigned)random(100))
		{
			// losuj chromosom do mutacji
			register int Index = random(LiczbaChromosomow);
			// pobierz sygnature chromosomu 'X,Y,...'
			register char Sign = WektorZakresow->item(Index)->Sign;
			// dokonaj mutacji i pobierz nowe geny
			// utworz nowy genotyp na bazie uzyskanych genow i dodaj do listy
			ArrayOfGenotyp->add(new TGenotyp(PFuncOceny,
							    ArrayOfGenotyp->item(i)->Mutacja(Sign), Precyzja));
		}
	}
}

//--------------------------------------------------------------------------
void __fastcall TPopulacja::Krzyzowanie(void)
{

	// pobierz liczbe osobnikow
	register int LiczbaGenotypow = ArrayOfGenotyp->count();
	// liczba genow w genotypie
	register int LiczbaGenow = LiczbaWspolrzednych;

	// jesli liczba genow wynosi zero, wroc
	if(LiczbaGenow <= 0) return;

	WektorTablic->clear();
	for(register int i = LiczbaGenotypow - 1; i >= 0; i--)
		if((unsigned)random(100) < PKrzyzowania)
		{
			// pobierz wskaznik do wektora genow kolejnego genotypu
			register TTab* Tablica = new TTab();
			for(register int j = 0; j < LiczbaGenow; j++)
				Tablica->add(ArrayOfGenotyp->item(i)->Get_Geny()->item(j));
			WektorTablic->push_back(Tablica);
		}

	// liczba wylosowanych genotypow
	int LiczbaWylosowanych = WektorTablic->size();


	// jesli liczba wylosowanych genotypow mniejsza lub rowna
	// jeden, wroc
	if(LiczbaWylosowanych <= 1) return;
	// jesli liczba nieparzysta ( czyli Size parzyste), usun ostatni
	if(LiczbaWylosowanych % 2) WektorTablic->pop_back();
	LiczbaWylosowanych = WektorTablic->size();

	// kolejno, dobierajac wektory genow w pary dokonaj krzyzowania
	for(register int i = 0; i < LiczbaWylosowanych - 1; i += 2)
	{
		// kolejno indeksy grup genow
          for(register int Index = 0; Index < LiczbaGenow; Index++)
          {
		     // pobierz wartosci chromosomow
		     // genotyp pierwszy
		     register TTab* Tablica = WektorTablic->at(i);

		     register int Znak = Tablica->at(Index)->Znak;
		     register char Sign = Tablica->at(Index)->Znak;

		     register TBinary BinaryC1 = Tablica->at(Index)->BinaryC;
		     register TBinary BinaryU1 = Tablica->at(Index)->BinaryU;

		     // genotyp drugi
		     Tablica = WektorTablic->at(i + 1);
		     register TBinary BinaryC2 = Tablica->at(Index)->BinaryC;
		     register TBinary BinaryU2 = Tablica->at(Index)->BinaryU;

		     // dzielimy lancuchy w losowo wybranych miejscach i wymieniamy podlancuchy
		     register unsigned LocusC = random(BinaryC1.size());
		     if(LocusC >= BinaryC2.size()) LocusC = BinaryC2.size() - 1;
		     register unsigned LocusU = random(PozycjaLocus);
		     if(LocusU >= BinaryU2.size()) LocusU = BinaryU2.size() - 1;
               register TBinary BinaryC = BinaryC1;
               if(random(100) % 2)
		     BinaryC = BinaryC1.substr(0, LocusC) +
                    BinaryC2.substr(LocusC + 1, BinaryC2.size() - 1 - LocusC);
		     register TBinary BinaryU = BinaryU1.substr(0, LocusU) +
                    BinaryU2.substr(LocusU + 1, BinaryU2.size() - 1 - LocusU);

		     WektorGenow->clear();
		     for(register int j = 0; j < LiczbaGenow; j++)
		     {
			     if(j == Index)
			     	WektorGenow->add(new TGeny(BinaryC, BinaryU, Znak, Sign));
			     else
			     	WektorGenow->add(new TGeny(Tablica->at(j)));
		     }
		     ArrayOfGenotyp->add(new TGenotyp(PFuncOceny, WektorGenow.get(), Precyzja));
          }
	}

	for(register unsigned i = 0; i < WektorTablic->size(); i++)
		delete WektorTablic->at(i);
}

//---------------------------------------------------------------------------
void __fastcall TPopulacja::WykonajCykle(void)
{
	for(register unsigned i = 0; i < LCykli; i++)
	{
		Selekcja();
		Mutacja();
		Krzyzowanie();
	}
}

//---------------------------------------------------------------------------
inline void __fastcall TPopulacja::Wysegreguj(void)
{
     int LiczbaWybranych = ArrayOfGenotyp->count() * ((double)Sigma / 100);
     switch(EXT)
     {
          case MAXIMUM:
          {
               for(int i = ArrayOfGenotyp->count() - 1; i > LiczbaWybranych; i--)
               ArrayOfGenotyp->erase(i);
          } break;
          case MINIMUM:
          {
               for(int i = LiczbaWybranych; i >= 0; i--)
                    ArrayOfGenotyp->erase(i);
          } break;
     }
}

//---------------------------------------------------------------------------
double __fastcall TPopulacja::SzukajMaximum(void)
{
	register int Count = ArrayOfGenotyp->count();
	register double Max = ArrayOfGenotyp->item(0)->Get_Fitnes();
	for(int i = 0; i < Count; i++)
		if(Max < ArrayOfGenotyp->item(i)->Get_Fitnes())
			Max = ArrayOfGenotyp->item(i)->Get_Fitnes();
	return Max;
}

//---------------------------------------------------------------------------
double __fastcall TPopulacja::SzukajMinimum(void)
{
	register int Count = ArrayOfGenotyp->count();
	register double Min = ArrayOfGenotyp->item(0)->Get_Fitnes();
	for(int i = 0; i < Count; i++)
		if(Min > ArrayOfGenotyp->item(i)->Get_Fitnes())
			Min = ArrayOfGenotyp->item(i)->Get_Fitnes();
	return Min;
}

//---------------------------------------------------------------------------
inline bool __fastcall TPopulacja::SprawdzFenotypy(TGenotyp* Genotyp)
{
	for(register unsigned i = 0; i < LiczbaWspolrzednych; i++)
	{
		if((Genotyp->Get_Fenotyp(i) < WektorZakresow->item(i)->Begin) ||
		   (Genotyp->Get_Fenotyp(i) > WektorZakresow->item(i)->End)     )
			return false;
	}
	return true;
}

//---------------------------------------------------------------------------
__fastcall TPopulacja::TPopulacja(std::vector<TZakres> const& W, TPFuncOceny PFO, TEXTREMUM E)
				   :
				   PFuncOceny(PFO), EXT(E),
				   ArrayOfGenotyp(new TArrayOfGenotyp()),
                       GenotypyPoczatkowe(new TArrayOfGenotyp()),
				   WektorGenow(new TWektorGenow()),
				   WektorZakresow(new TWektorZakresow()),
				   WektorTablic(new TWektorTablic())
{
	PFuncS = Selekcja;
	PFuncM = Mutacja;
	PFuncK = Krzyzowanie;

	int Count = W.size();
	for(int i = 0; i < Count; i++)
		WektorZakresow->add(new TZakres(W.at(i)));

     Precyzja = CPRECYZJA;
     LGenotypowDoc = CL_GENOTYPOW_DOC;
	PMutacji = CP_MUTACJI;
	PKrzyzowania = CP_KRZYZOWANIA;
     Sigma = CSIGMA;
	LGenotypow = CL_GENOTYPOW_POCZ;
	LCykli = CL_CYKLI;

	LiczbaWspolrzednych = W.size();
}

//---------------------------------------------------------------------------
__fastcall TPopulacja::~TPopulacja(void) {}

//---------------------------------------------------------------------------
void __fastcall TPopulacja::Set_PMutacji(int PM) {PMutacji = PM;}

//---------------------------------------------------------------------------
void __fastcall TPopulacja::Set_PKrzyzowania(int PK) {PKrzyzowania = PK;}

//---------------------------------------------------------------------------
void __fastcall TPopulacja::Set_PRECYZJA(TPRECYZJA PRECYZJA) {Precyzja = PRECYZJA;}

//---------------------------------------------------------------------------
void __fastcall TPopulacja::Set_LGenotypow(int LG) {LGenotypow = LG;}

//---------------------------------------------------------------------------
void __fastcall TPopulacja::Set_Sigma(int Value) {Sigma = Value;}

//---------------------------------------------------------------------------
void __fastcall TPopulacja::Set_LCykli(int LC) {LCykli = LC;}

//---------------------------------------------------------------------------
void __fastcall TPopulacja::Set_PopulacjaDocelowa(int Value) {LGenotypowDoc = Value;}

//---------------------------------------------------------------------------
void __fastcall TPopulacja::Execute(void)
{
	Algorytm();
}

//---------------------------------------------------------------------------
TArrayOfGenotyp* __fastcall TPopulacja::Get_Array(void) {return ArrayOfGenotyp.get();}

//---------------------------------------------------------------------------
TArrayOfGenotyp* __fastcall TPopulacja::Get_GenotypyPoczatkowe(void) {return GenotypyPoczatkowe.get();}

/////////////////////////////////////////////////////////////////////////////
// koniec pliku 'extrema.cpp'

⌨️ 快捷键说明

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