diff --git a/Genetic-Algorithm.vcxproj b/Genetic-Algorithm.vcxproj
index aa45fa0..3733113 100644
--- a/Genetic-Algorithm.vcxproj
+++ b/Genetic-Algorithm.vcxproj
@@ -119,11 +119,19 @@
+
+
+
+
+
+
+
+
diff --git a/Genetic-Algorithm.vcxproj.filters b/Genetic-Algorithm.vcxproj.filters
index bc1d5b1..2c07236 100644
--- a/Genetic-Algorithm.vcxproj.filters
+++ b/Genetic-Algorithm.vcxproj.filters
@@ -18,8 +18,28 @@
Source Files
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
\ No newline at end of file
diff --git a/include/CubicEquation.h b/include/CubicEquation.h
new file mode 100644
index 0000000..da6f36b
--- /dev/null
+++ b/include/CubicEquation.h
@@ -0,0 +1,15 @@
+#pragma once
+
+#include
+
+class CubicEquation {
+public:
+ CubicEquation(const std::array& coefficients);
+ std::array solve();
+ std::array getRoots() const;
+ std::array getCoefficients() const;
+
+private:
+ std::array coefficients_;
+ std::array roots_;
+};
diff --git a/include/Entity.h b/include/Entity.h
new file mode 100644
index 0000000..765eeb6
--- /dev/null
+++ b/include/Entity.h
@@ -0,0 +1,26 @@
+#pragma once
+
+#include
+
+class Entity {
+public:
+ //
+ Entity();
+ Entity(const std::array& coefficients);
+
+ //
+ std::array getCoefficients() const;
+ std::array getRoots() const;
+
+ //
+ void mutate();
+ Entity crossover(const Entity& other) const;
+ void printEquation();
+ void printEntity();
+
+private:
+ std::array coefficients;
+ std::array roots;
+ void printFormattedNumber(int num);
+};
+
diff --git a/include/Population.h b/include/Population.h
new file mode 100644
index 0000000..6bb9a54
--- /dev/null
+++ b/include/Population.h
@@ -0,0 +1,24 @@
+#pragma once
+
+#include "Entity.h"
+#include
+
+class Population {
+public:
+ //
+ Population();
+ Population(std::array newPopulation);
+
+ const std::array& getPopulation() const;
+
+ void printPopulation();
+ std::array calculateFitness(std::array targetRoots);
+ std::array Population::selection();
+ std::array Population::evolve(); //
+
+private:
+ int generationNumber;
+ std::array sellist;
+ std::array fitness;
+ std::array population_;
+};
diff --git a/main.cpp b/main.cpp
index 118a02b..257ed3d 100644
--- a/main.cpp
+++ b/main.cpp
@@ -1,175 +1,10 @@
#include
#include
-#include
-#include
-#include
-
-// Вывод числа в формате с отступами
-void printFormattedNumber(int num) {
- if (num == 100)
- std::cout << num << " ";
- else if (num < 10)
- std::cout << " " << num << " ";
- else if (num >= 10 && num < 100)
- std::cout << " " << num << " ";
-}
-
-// Вывод текущей популяции
-void printPopulation(int Generation_Number, std::array, 10> new_popul) {
-
- std::cout << "\nGeneration " << Generation_Number << std::endl;
- std::cout << " Chromosome " << " a b c d " << "\n\n";
-
- for (int i = 0; i < 10; i++) {
- std::cout << "Individual " << i << " ";
-
- for (int j = 0; j < 4; j++) {
- printFormattedNumber(new_popul[i][j]);
- }
-
- std::cout << std::endl;
- }
-}
-
-// Генерация начальной популяции с случайными коэффициентами
-std::array, 10> initial_population() {
- std::array, 10> new_popul;
-
- for (int i = 0; i < 10; i++) {
- for (int j = 0; j < 4; j++) {
- new_popul[i][j] = rand() % 101;
- }
- }
-
- return new_popul;
-}
-
-// Решение кубического уравнения
-std::array solveCubicEquation(const std::array& coefficients) {
- double a = coefficients[0];
- double b = coefficients[1];
- double c = coefficients[2];
- double d = coefficients[3];
-
- // Calculate discriminants and intermediate values
- double discriminant = 18 * a * b * c * d - 4 * b * b * b * d + b * b * c * c - 4 * a * c * c * c - 27 * a * a * d * d;
- double delta0 = b * b - 3 * a * c;
- double delta1 = 2 * b * b * b - 9 * a * b * c + 27 * a * a * d;
-
- // Calculate roots
- std::array roots;
-
- if (discriminant > 0) {
- double C = cbrt((delta1 + sqrt(discriminant)) / 2.0);
- double D = cbrt((delta1 - sqrt(discriminant)) / 2.0);
- roots[0] = (-b + C + D) / (3 * a);
- }
- else if (discriminant == 0) {
- roots[0] = -b / (3 * a);
- }
- else {
- double phi = acos(delta1 / (2 * sqrt(-delta0 * delta0 * delta0)));
- double magnitude = 2 * sqrt(-delta0);
- const double pi = 3.14159265358979323846; // Число π
- roots[0] = magnitude * cos(phi / 3) - b / (3 * a);
- roots[1] = magnitude * cos((phi + 2 * pi) / 3) - b / (3 * a);
- roots[2] = magnitude * cos((phi + 4 * pi) / 3) - b / (3 * a);
- }
-
- return roots;
-}
-
-// Оценка приспособленности особей (близость к корням)
-std::array fitness_evaluation(const std::array, 10>& population,
- const std::array& target_roots) {
- std::array fitness;
-
- for (int i = 0; i < 10; i++) {
- double total_distance = 0.0;
-
- for (int j = 0; j < 3; j++) {
- std::array roots = solveCubicEquation(population[i]);
- for (int k = 0; k < 3; k++) {
- double distance = std::abs(roots[k] - target_roots[j]);
- total_distance += distance;
- }
- }
-
- fitness[i] = 1.0 / total_distance;
- }
-
- return fitness;
-}
-
-// Выбор особей для следующего поколения
-std::array selection(const std::array& fitness) {
- std::array sellist;
-
- for (int i = 0; i < 5; i++) {
- int maxIndex = 0;
- double maxFitness = -1.0;
-
- for (int j = 0; j < 10; j++) {
- if (fitness[j] > maxFitness) {
- bool isAlreadySelected = false;
- for (int k = 0; k < i; k++) {
- if (sellist[k] == j) {
- isAlreadySelected = true;
- break;
- }
- }
-
- if (!isAlreadySelected) {
- maxIndex = j;
- maxFitness = fitness[j];
- }
- }
- }
-
- sellist[i] = maxIndex;
- }
-
- return sellist;
-}
-
-// Создание новой популяции на основе выбранных особей
-std::array, 10> createNewPopulation(const std::array, 10>& old_popul, const std::array& sellist) {
- std::array, 10> new_popul;
-
- // Копирование выбранных особей в новую популяцию
- for (int i = 0; i < 5; i++) {
- new_popul[i] = old_popul[sellist[i]];
- }
-
- // Генерация новых особей (потомков) через скрещивание
- for (int i = 5; i < 10; i++) {
- int parent1Index = rand() % 5; // Выбор случайного родителя из выбранных особей
- int parent2Index = rand() % 5; // Выбор еще одного случайного родителя из выбранных особей
-
- // Производим скрещивание (можно использовать простое скрещивание с одной точкой)
- int crossoverPoint = rand() % 4; // Выбор случайной точки скрещивания
-
- for (int j = 0; j < 4; j++) {
- if (j < crossoverPoint) {
- new_popul[i][j] = old_popul[sellist[parent1Index]][j];
- }
- else {
- new_popul[i][j] = old_popul[sellist[parent2Index]][j];
- }
- }
-
- // Производим мутацию
- int mutationGeneIndex = rand() % 4; // Выбор случайного гена для мутации
- new_popul[i][mutationGeneIndex] = rand() % 101; // Мутируем ген случайным значением
- }
-
- return new_popul;
-}
-
+#include "include/CubicEquation.h"
+#include "include/Entity.h"
+#include "include/Population.h"
int main() {
- srand(time(NULL));
-
const int MAX_GENERATIONS = 100; // Максимальное количество поколений
std::cout << "New Genetic Algorithm for Cubic Equation\n\n";
@@ -182,46 +17,44 @@ int main() {
std::cin >> coefficients[i];
}
- std::array roots = solveCubicEquation(coefficients); // Корни кубического уравнения
-
-
- std::cout << std::endl << "Cubic Equation: " << coefficients[0] << "x^3 + "
- << coefficients[1] << "x^2 + " << coefficients[2] << "x + " << coefficients[3] << " = 0" << std::endl;
+ Entity targetEquation(coefficients);
+ targetEquation.printEquation();
- std::cout << "Equation Roots: " << roots[0] << ", " << roots[1] << ", " << roots[2] << std::endl;
+ std::array roots = targetEquation.getRoots();
+
+ Population newPopul;
+ newPopul.printPopulation();
int Generation_Number = 1;
- std::array sellist; // Массив наиболее приспособленных.
+ std::array new_popul = newPopul.getPopulation();
- std::array, 10> new_popul = initial_population();
- printPopulation(Generation_Number, new_popul);
+ std::array sellist; // Массив наиболее приспособленных.
// Основной цикл генетического алгоритма
while (true) {
// Оценка приспособленности
- std::array fitness_values = fitness_evaluation(new_popul, roots);
+ newPopul.calculateFitness(roots);
// Выбор особей для следующего поколения
- sellist = selection(fitness_values);
-
- /*По логике будет 5 прислпособленнейших и генерироваться 5 новых.
- Также мутация будет менят некоторыхе хромосомы в некоторых особях, которое будет выбираться рандомом.*/
+ sellist = newPopul.selection();
// Создание новой популяции на основе выбранных особей
- new_popul = createNewPopulation(new_popul, sellist);
+ new_popul = newPopul.evolve();
Generation_Number++;
// После определенного количества поколений, выводим наилучшее уравнение
if (Generation_Number == MAX_GENERATIONS) {
int bestIndividualIndex = sellist[0]; // Индекс самой приспособленной особи
- std::array bestCoefficients = new_popul[bestIndividualIndex]; // Коэффициенты этой особи
+ std::array bestCoefficients = new_popul[bestIndividualIndex].getCoefficients(); // Коэффициенты этой особи
std::cout << "\nBest Equation after " << MAX_GENERATIONS << " Generations:\n";
std::cout << "Cubic Equation: " << bestCoefficients[0] << "x^3 + "
<< bestCoefficients[1] << "x^2 + " << bestCoefficients[2] << "x + " << bestCoefficients[3] << " = 0" << std::endl;
- std::array bestRoots = solveCubicEquation(bestCoefficients); // Корни уравнения
+ CubicEquation bestEntity(bestCoefficients);
+ ;
+ std::array bestRoots = bestEntity.solve(); // Корни уравнения
std::cout << "Equation Roots: " << bestRoots[0] << ", " << bestRoots[1] << ", " << bestRoots[2] << std::endl;
break; // Завершаем цикл после вывода результата
diff --git a/scr/CubicEquation.cpp b/scr/CubicEquation.cpp
new file mode 100644
index 0000000..47ab2c4
--- /dev/null
+++ b/scr/CubicEquation.cpp
@@ -0,0 +1,45 @@
+#include "../include/CubicEquation.h"
+#include
+
+CubicEquation::CubicEquation(const std::array& coefficients)
+ : coefficients_(coefficients), roots_{ 0.0, 0.0, 0.0 } {}
+
+std::array CubicEquation::solve() {
+ double a = coefficients_[0];
+ double b = coefficients_[1];
+ double c = coefficients_[2];
+ double d = coefficients_[3];
+
+ // Calculate discriminants and intermediate values
+ double discriminant = 18 * a * b * c * d - 4 * b * b * b * d + b * b * c * c - 4 * a * c * c * c - 27 * a * a * d * d;
+ double delta0 = b * b - 3 * a * c;
+ double delta1 = 2 * b * b * b - 9 * a * b * c + 27 * a * a * d;
+
+ // Calculate roots
+ if (discriminant > 0) {
+ double C = cbrt((delta1 + sqrt(discriminant)) / 2.0);
+ double D = cbrt((delta1 - sqrt(discriminant)) / 2.0);
+ roots_[0] = (-b + C + D) / (3 * a);
+ }
+ else if (discriminant == 0) {
+ roots_[0] = -b / (3 * a);
+ }
+ else {
+ double phi = acos(delta1 / (2 * sqrt(-delta0 * delta0 * delta0)));
+ double magnitude = 2 * sqrt(-delta0);
+ const double pi = 3.14159265358979323846;
+ roots_[0] = magnitude * cos(phi / 3) - b / (3 * a);
+ roots_[1] = magnitude * cos((phi + 2 * pi) / 3) - b / (3 * a);
+ roots_[2] = magnitude * cos((phi + 4 * pi) / 3) - b / (3 * a);
+ }
+
+ return roots_;
+}
+
+std::array CubicEquation::getRoots() const {
+ return roots_;
+}
+
+std::array CubicEquation::getCoefficients() const{
+ return coefficients_;
+}
\ No newline at end of file
diff --git a/scr/Entity.cpp b/scr/Entity.cpp
new file mode 100644
index 0000000..2e3594b
--- /dev/null
+++ b/scr/Entity.cpp
@@ -0,0 +1,75 @@
+#include "../include/Entity.h"
+#include "../include/CubicEquation.h"
+#include
+#include
+#include
+
+Entity::Entity() {
+ srand(time(NULL));
+
+ for (int i = 0; i < 4; i++) {
+ coefficients[i] = rand() % 101;
+ }
+
+ CubicEquation equation(coefficients);
+ roots = equation.solve();
+}
+
+Entity::Entity(const std::array& coefficients) {
+ this->coefficients = coefficients;
+
+ CubicEquation equation(coefficients);
+ roots = equation.solve();
+}
+
+std::array Entity::getCoefficients() const {
+ return coefficients;
+}
+
+std::array Entity::getRoots() const {
+ return roots;
+}
+
+void Entity::mutate() {
+ int geneIndex = rand() % 4;
+ coefficients[geneIndex] = rand() % 101;
+}
+
+Entity Entity::crossover(const Entity& other) const {
+ int crossoverPoint = rand() % 4;
+ std::array newCoefficients;
+
+ for (int i = 0; i < 4; i++) {
+ if (i < crossoverPoint) {
+ newCoefficients[i] = coefficients[i];
+ }
+ else {
+ newCoefficients[i] = other.coefficients[i];
+ }
+ }
+
+ return Entity(newCoefficients);
+}
+
+void Entity::printEquation() {
+ std::cout << std::endl << "Equation: " << coefficients[0] << "x^3 + "
+ << coefficients[1] << "x^2 + " << coefficients[2] << "x + " << coefficients[3] << " = 0" << std::endl;
+
+ std::cout << "Equation Roots: " << roots[0] << ", " << roots[1] << ", " << roots[2] << std::endl;
+}
+
+void Entity::printEntity() {
+ for (int i = 0; i < 4; i++) {
+ printFormattedNumber(coefficients[i]);
+ }
+}
+
+//
+void Entity::printFormattedNumber(int num) {
+ if (num == 100)
+ std::cout << num << " ";
+ else if (num < 10)
+ std::cout << " " << num << " ";
+ else if (num >= 10 && num < 100)
+ std::cout << " " << num << " ";
+}
\ No newline at end of file
diff --git a/scr/Population.cpp b/scr/Population.cpp
new file mode 100644
index 0000000..6fe745d
--- /dev/null
+++ b/scr/Population.cpp
@@ -0,0 +1,110 @@
+#include "../include/Population.h"
+#include "../include/Entity.h"
+#include
+#include
+#include
+#include
+
+//
+Population::Population() {
+ generationNumber = 1;
+
+ for (int i = 0; i < 10; i++) {
+
+ population_[i] = Entity::Entity();
+ }
+}
+
+Population::Population(std::array newPopulation) {
+ generationNumber = 1;
+ population_ = newPopulation;
+}
+
+const std::array& Population::getPopulation() const {
+ return population_;
+}
+
+//
+std::array Population::evolve() {
+ std::array new_popul;
+
+ //
+ for (int i = 0; i < 5; i++) {
+ new_popul[i] = population_[sellist[i]];
+ }
+
+ // ()
+ for (int i = 5; i < 10; i++) {
+ new_popul[i] = Entity::Entity();
+ }
+
+ for (int i = 0; i < 10; i++) {
+ population_[i] = new_popul[i];
+ }
+
+ return population_;
+}
+
+// ( )
+std::array Population::calculateFitness(std::array target_roots) {
+ for (int i = 0; i < 10; i++) {
+ double total_distance = 0.0;
+
+ for (int j = 0; j < 3; j++) {
+ std::array roots = population_[i].getRoots();
+
+ for (int k = 0; k < 3; k++) {
+ double distance = std::abs(roots[k] - target_roots[j]);
+ total_distance += distance;
+ }
+ }
+
+ fitness[i] = 1.0 / total_distance;
+ }
+
+ return fitness;
+}
+
+//
+std::array Population::selection() {
+ std::array sellist;
+
+ for (int i = 0; i < 5; i++) {
+ int maxIndex = 0;
+ double maxFitness = -1.0;
+
+ for (int j = 0; j < 10; j++) {
+ if (fitness[j] > maxFitness) {
+ bool isAlreadySelected = false;
+ for (int k = 0; k < i; k++) {
+ if (sellist[k] == j) {
+ isAlreadySelected = true;
+ break;
+ }
+ }
+
+ if (!isAlreadySelected) {
+ maxIndex = j;
+ maxFitness = fitness[j];
+ }
+ }
+ }
+
+ sellist[i] = maxIndex;
+ }
+
+ return sellist;
+}
+
+//
+void Population::printPopulation() {
+
+ std::cout << "\nGeneration " << generationNumber << std::endl;
+ std::cout << " Chromosome " << " a b c d " << "\n\n";
+
+ for (int i = 0; i < 10; i++) {
+ std::cout << "Individual " << i << " ";
+ population_[i].printEntity();
+ std::cout << std::endl;
+ }
+}
\ No newline at end of file