353 lines
14 KiB
C++
353 lines
14 KiB
C++
#include "solver.h"
|
|
#include "iostream"
|
|
#include <QTextStream>
|
|
|
|
Solver::Solver(QObject *parent) :
|
|
QObject(parent)
|
|
{
|
|
|
|
}
|
|
|
|
Solver::~Solver()
|
|
{
|
|
|
|
}
|
|
|
|
|
|
//calculates function values and puts it into vectors(predatorSolveVal, preySolveVal)
|
|
void Solver::solveModel(float c1, float c2, float c3, float c4, float c5, float sigC1, float sigC2, float sigC3, float sigC4, float sigC5,
|
|
float e, float sigE, float sigX0, float delX0, float sigX, float Xopt, int popSize, int maxSteps, int N, int flag, int iter, int modelCount){
|
|
|
|
itersFlag = flag;
|
|
newIters = iter;
|
|
modCount = modelCount;
|
|
int k = 0;
|
|
|
|
if (itersFlag == 0)
|
|
{
|
|
popVect.clear();
|
|
singleModelHistory.clear();
|
|
for (int i = 0; i < modelCount; i++)
|
|
{
|
|
k++;
|
|
|
|
withFeedbackVect.clear();
|
|
withoutFeedbackVect.clear();
|
|
firstXVect.clear();
|
|
maxWithFeedVal = 0;
|
|
maxWithoutFeedVal = 0;
|
|
//firstXVect.clear();
|
|
|
|
meanE.clear();
|
|
meanF.clear();
|
|
meanC2.clear();
|
|
individ.clear();
|
|
individFeedback.clear();
|
|
|
|
int POP_SIZE = popSize;
|
|
int MAX_STEPS = maxSteps;
|
|
addSteps = maxSteps;
|
|
//float DELTA_Xopt = 0.0f;
|
|
float DELTA_Xopt = delX0;
|
|
//float DELTA_Xopt = 0.4f;
|
|
//float DELTA_Xopt = 0.5f;
|
|
//float DELTA_Xopt = 1.0f;
|
|
N_forFeedback = N;
|
|
population.resize(POP_SIZE);
|
|
popVect.push_back(population);
|
|
//Individ::initConstants();
|
|
Individ::initConstantsFromGUI(c1, c2, c3, c4, c5, Xopt, sigX, sigE, sigC1, sigC2, sigC3, sigC4, sigC5);
|
|
initialization(popVect[i], N_forFeedback);
|
|
|
|
// Îñíîâíîé öèêë ýâîëþöèè
|
|
for(int steps = 0; steps < MAX_STEPS; steps++) {
|
|
//mutationSimple(population); // 1) Ìóòàöèîííûé ïðîöåññ
|
|
mutationComplex(popVect[i]);
|
|
selection(popVect[i], 0.02f); // 2) Îòáîð
|
|
printStatistics(popVect[i], i, 0, steps);
|
|
firstXVect.push_back(steps);
|
|
maxWithFeedVal = qMax(withFeedbackVect[steps], maxWithFeedVal);
|
|
maxWithoutFeedVal = qMax(withoutFeedbackVect[steps], maxWithoutFeedVal);
|
|
Individ::Xopt += DELTA_Xopt;
|
|
} // (END) Îñíîâíîé öèêë ýâîëþöèè
|
|
|
|
lastXopt = Individ::Xopt;
|
|
|
|
vectors.withFeedbackVect = withFeedbackVect;
|
|
vectors.withoutFeedbackVect = withoutFeedbackVect;
|
|
vectors.individ = individ;
|
|
vectors.individFeedback = individFeedback;
|
|
vectors.meanE = meanE;
|
|
vectors.meanC2 = meanC2;
|
|
vectors.meanF = meanF;
|
|
vectors.xRange = firstXVect;
|
|
vectors.maxWithFeedVal = maxWithFeedVal;
|
|
vectors.maxWithoutFeedVal = maxWithoutFeedVal;
|
|
|
|
singleModelHistory.push_back(vectors);
|
|
|
|
emit sendItersForProgressBar(i);
|
|
|
|
}
|
|
if (k == modelCount)
|
|
{
|
|
for (int m = 0; m < withFeedbackVectAvg.size(); m++)
|
|
{
|
|
withFeedbackVectAvg[m] /= modCount;
|
|
withoutFeedbackVectAvg[m] /= modCount;
|
|
individAvg[m] /= modCount;
|
|
individFeedbackAvg[m] /= modCount;
|
|
meanC2Avg[m] /= modCount;
|
|
meanEAvg[m] /= modCount;
|
|
meanFAvg[m] /= modCount;
|
|
|
|
}
|
|
vectors.withFeedbackVect = withFeedbackVectAvg;
|
|
vectors.withoutFeedbackVect = withoutFeedbackVectAvg;
|
|
vectors.individ = individAvg;
|
|
vectors.individFeedback = individFeedbackAvg;
|
|
vectors.meanE = meanEAvg;
|
|
vectors.meanC2 = meanC2Avg;
|
|
vectors.meanF = meanFAvg;
|
|
singleModelHistory.push_back(vectors);
|
|
|
|
emit sendItersForProgressBar(modCount);
|
|
|
|
}
|
|
|
|
emit sendHistory(singleModelHistory, addSteps);
|
|
}
|
|
if (itersFlag == 1)
|
|
{
|
|
int n = 0;
|
|
float DELTA_Xopt = delX0;
|
|
for (int i = 0; i < modelCount; i++)
|
|
{
|
|
n++;
|
|
Individ::Xopt = lastXopt;
|
|
//std::cout << Individ::Xopt << std::endl;
|
|
N_forFeedback = N;
|
|
|
|
// Îñíîâíîé öèêë ýâîëþöèè
|
|
for(int steps = addSteps; steps < addSteps + newIters; steps++) {
|
|
//mutationSimple(population); // 1) Ìóòàöèîííûé ïðîöåññ
|
|
mutationComplex(popVect[i]);
|
|
selection(popVect[i], 0.02f); // 2) Îòáîð
|
|
printStatistics(popVect[i], i, 1, steps);
|
|
if (i == 0)
|
|
{
|
|
firstXVect.push_back(steps);
|
|
}
|
|
Individ::Xopt += DELTA_Xopt;
|
|
maxWithFeedVal = qMax(withFeedbackVect[steps], maxWithFeedVal);
|
|
maxWithoutFeedVal = qMax(withoutFeedbackVect[steps], maxWithoutFeedVal);
|
|
|
|
} // (END) Îñíîâíîé öèêë ýâîëþöèè
|
|
|
|
singleModelHistory[i].xRange = firstXVect;
|
|
singleModelHistory[i].maxWithFeedVal = maxWithFeedVal;
|
|
singleModelHistory[i].maxWithoutFeedVal = maxWithoutFeedVal;
|
|
emit sendItersForProgressBar(i);
|
|
|
|
}
|
|
if (n == modCount) // index n - for last struct in history for averages
|
|
{
|
|
for (int m = addSteps; m < addSteps + newIters; m++)
|
|
{
|
|
singleModelHistory[modCount].withFeedbackVect[m] /= modCount;
|
|
singleModelHistory[modCount].withoutFeedbackVect[m] /= modCount;
|
|
singleModelHistory[modCount].individ[m] /= modCount;
|
|
singleModelHistory[modCount].individFeedback[m] /= modCount;
|
|
singleModelHistory[modCount].meanC2[m] /= modCount;
|
|
singleModelHistory[modCount].meanE[m] /= modCount;
|
|
singleModelHistory[modCount].meanF[m] /= modCount;
|
|
}
|
|
|
|
singleModelHistory[modCount].xRange = firstXVect;
|
|
}
|
|
lastXopt = Individ::Xopt;
|
|
addSteps += newIters;
|
|
emit sendItersForProgressBar(modCount);
|
|
emit sendHistory(singleModelHistory, addSteps);
|
|
|
|
}
|
|
}
|
|
|
|
void Solver::mutationSimple(std::vector<Individ*>& population){
|
|
boost::normal_distribution<> norm(0.0, Individ::sigmaE);
|
|
boost::mt19937 rng;
|
|
boost::variate_generator<boost::mt19937&, boost::normal_distribution<> >
|
|
generator(rng, norm); // glues randomness with mapping
|
|
|
|
for(int i = 0; i < population.size(); i++){
|
|
float deltaE = generator();
|
|
//std::cout<<deltaE<<std::endl;
|
|
population.at(i)->mutate(deltaE);
|
|
}
|
|
}
|
|
|
|
void Solver::mutationComplex(std::vector<Individ*>& population){
|
|
boost::normal_distribution<> normE(0.0, Individ::sigmaE);
|
|
boost::normal_distribution<> normC2(0.0, Individ::sigmaC2);
|
|
boost::mt19937 rng;
|
|
boost::variate_generator<boost::mt19937&, boost::normal_distribution<> >
|
|
generatorE(rng, normE);
|
|
boost::variate_generator<boost::mt19937&, boost::normal_distribution<> >
|
|
generatorC2(rng, normC2);
|
|
|
|
for(int i = 0; i < population.size(); i++){
|
|
float flag = generatorE();
|
|
if(flag >= 0.0f){
|
|
float deltaE = generatorE();
|
|
population.at(i)->mutate(deltaE);
|
|
}
|
|
else{
|
|
float deltaC2 = generatorC2();
|
|
population.at(i)->mutateC2(deltaC2);
|
|
}
|
|
}
|
|
}
|
|
|
|
void Solver::selection(std::vector<Individ*>& population, float renewRate){
|
|
std::sort(population.begin(),population.end(), compareOnFitness);
|
|
int inds = population.size();
|
|
float deathRate = renewRate;
|
|
float birthRate = renewRate; //Settings::BirthRate;//0.02f;
|
|
int toDie = int (inds* deathRate);
|
|
std::vector<Individ*>::iterator start = population.begin();
|
|
std::vector<Individ*>::iterator end = population.begin()+toDie;
|
|
|
|
for(std::vector<Individ*>::iterator it = start; it != end; it++){
|
|
delete *it;
|
|
}
|
|
population.erase(start, end);
|
|
|
|
// Ðîæàåì íîâûõ îñîáåé
|
|
int toBorn = int (inds * birthRate);
|
|
inds = population.size();
|
|
srand((unsigned int)time(NULL));
|
|
for(int i = 0; i < toBorn; i++) {
|
|
int parent = rand() % inds;
|
|
Individ* ind;
|
|
if(population.at(parent)->hasFeedBack()){
|
|
ind = new IndividFeedBack(population.at(parent)->getE());
|
|
ind->setC2(population.at(parent)->getC2());
|
|
}
|
|
else{
|
|
ind = new Individ(population.at(parent)->getE());
|
|
}
|
|
// Çäåñü ïî íåîáõîäèìîñòè äîáàâëÿåì íàñòðîéêè ñðåäû è ò.ä.
|
|
population.push_back(ind);
|
|
}
|
|
} // (END) void selection(std::vector<Individ*>& population, float renewRate)
|
|
|
|
void Solver::initialization(std::vector<Individ*>& population, int N_feedback){
|
|
// Èíèöèàëèçàöèÿ
|
|
int POP_SIZE = population.size();
|
|
float E = Individ::getOptimalE();// Xopt*Individ::c[2]/Individ::c[0] - Individ::c[3];
|
|
|
|
for(int i = 0; i < N_feedback; i++){
|
|
Individ* ind = new Individ(E);
|
|
population.at(i) = ind;
|
|
}
|
|
E = IndividFeedBack::getOptimalE();
|
|
for(int i = N_feedback; i < POP_SIZE; i++){
|
|
Individ* ind = new IndividFeedBack(E);
|
|
population.at(i) = ind;
|
|
}
|
|
|
|
} // (END) void initialization(std::vector<Individ*>& population){
|
|
|
|
|
|
|
|
void Solver::printStatistics(const std::vector<Individ*>& population, int i, int iters, int currentStep){
|
|
// Ñòàòèñòèêà
|
|
|
|
withFeedback = 0.f;
|
|
withoutFeedback = 0.f;
|
|
meanC2Feedback = 0.f;
|
|
meanEFeedBack = 0.f;
|
|
meanENonFeedBack = 0.f;
|
|
for(int i = 0; i < population.size(); i++){
|
|
if(population.at(i)->hasFeedBack()){
|
|
withFeedback++;
|
|
meanC2Feedback += population.at(i)->getC2();
|
|
meanEFeedBack += population.at(i)->getE();
|
|
}
|
|
else{
|
|
withoutFeedback++;
|
|
meanENonFeedBack += population.at(i)->getE();
|
|
}
|
|
}
|
|
|
|
if (iters == 1) //count average for additional iters
|
|
{
|
|
singleModelHistory[i].withFeedbackVect.push_back(withFeedback);
|
|
singleModelHistory[i].withoutFeedbackVect.push_back(withoutFeedback);
|
|
singleModelHistory[i].individ.push_back(Individ::getOptimalE());
|
|
singleModelHistory[i].individFeedback.push_back(IndividFeedBack::getOptimalE());
|
|
singleModelHistory[i].meanE.push_back(meanENonFeedBack/withoutFeedback);
|
|
singleModelHistory[i].meanC2.push_back(meanC2Feedback/withFeedback);
|
|
singleModelHistory[i].meanF.push_back(meanEFeedBack/withFeedback);
|
|
|
|
if (i == 0)
|
|
{
|
|
singleModelHistory[modCount].withFeedbackVect.push_back(withFeedback);
|
|
singleModelHistory[modCount].withoutFeedbackVect.push_back(withoutFeedback);
|
|
singleModelHistory[modCount].meanE.push_back(meanENonFeedBack/withoutFeedback);
|
|
singleModelHistory[modCount].meanF.push_back(meanEFeedBack/withFeedback);
|
|
singleModelHistory[modCount].meanC2.push_back(meanC2Feedback/withFeedback);
|
|
singleModelHistory[modCount].individ.push_back(Individ::getOptimalE());
|
|
singleModelHistory[modCount].individFeedback.push_back(IndividFeedBack::getOptimalE());
|
|
}
|
|
else
|
|
{
|
|
singleModelHistory[modCount].withFeedbackVect[currentStep] += withFeedback;
|
|
singleModelHistory[modCount].withoutFeedbackVect[currentStep] += withoutFeedback;
|
|
singleModelHistory[modCount].meanE[currentStep] += meanENonFeedBack/withoutFeedback;
|
|
singleModelHistory[modCount].meanF[currentStep] += meanEFeedBack/withFeedback;
|
|
singleModelHistory[modCount].meanC2[currentStep] += meanC2Feedback/withFeedback;
|
|
singleModelHistory[modCount].individ[currentStep] += Individ::getOptimalE();
|
|
singleModelHistory[modCount].individFeedback[currentStep] += IndividFeedBack::getOptimalE();
|
|
}
|
|
}
|
|
|
|
if (i == 0 && iters == 0) // count average for new calc
|
|
{
|
|
withFeedbackVectAvg.push_back(withFeedback);
|
|
withoutFeedbackVectAvg.push_back(withoutFeedback);
|
|
meanEAvg.push_back(meanENonFeedBack/withoutFeedback);
|
|
meanFAvg.push_back(meanEFeedBack/withFeedback);
|
|
meanC2Avg.push_back(meanC2Feedback/withFeedback);
|
|
individAvg.push_back(Individ::getOptimalE());
|
|
individFeedbackAvg.push_back(IndividFeedBack::getOptimalE());
|
|
}
|
|
else if (iters == 0)
|
|
{
|
|
withFeedbackVectAvg[currentStep] += withFeedback;
|
|
withoutFeedbackVectAvg[currentStep] += withoutFeedback;
|
|
meanEAvg[currentStep] += meanENonFeedBack/withoutFeedback;
|
|
meanFAvg[currentStep] += meanEFeedBack/withFeedback;
|
|
meanC2Avg[currentStep] += meanC2Feedback/withFeedback;
|
|
individAvg[currentStep] += Individ::getOptimalE();
|
|
individFeedbackAvg[currentStep] += IndividFeedBack::getOptimalE();
|
|
}
|
|
//add vectors for first calc
|
|
withFeedbackVect.push_back(withFeedback);
|
|
withoutFeedbackVect.push_back(withoutFeedback);
|
|
meanE.push_back(meanENonFeedBack/withoutFeedback);
|
|
meanF.push_back(meanEFeedBack/withFeedback);
|
|
meanC2.push_back(meanC2Feedback/withFeedback);
|
|
individ.push_back(Individ::getOptimalE());
|
|
individFeedback.push_back(IndividFeedBack::getOptimalE());
|
|
|
|
// std::cout<<"W/o fb\t"<<withoutFeedback<<"\tW/fb\t"<<withFeedback;
|
|
// std::cout<<"\tOptE(w/o/fb)\t"<<Individ::getOptimalE();
|
|
// std::cout<<"\tmE(w/o/fb)\t"<<meanENonFeedBack/withoutFeedback;
|
|
// std::cout<<"\tOptE(w/fb)\t"<<IndividFeedBack::getOptimalE();
|
|
// std::cout<<"\tmE(w/fb)\t"<<meanEFeedBack/withFeedback;
|
|
// std::cout<<"\tmC2(w/fb)\t"<<meanC2Feedback/withFeedback;
|
|
// std::cout<<std::endl;
|
|
}
|
|
|