📄 extrema.cpp
字号:
{
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 + -