From e4bf96fd183951afed2ffb2d692b2350c32a188f Mon Sep 17 00:00:00 2001
From: fbhou <1816118394@qq.com>
Date: Sat, 12 Dec 2020 21:25:36 +0800
Subject: [PATCH 1/4] Added evolution.h and evolution.cpp
---
LinearAlgebra/LinearAlgebra.vcxproj | 2 ++
LinearAlgebra/LinearAlgebra.vcxproj.filters | 6 ++++++
2 files changed, 8 insertions(+)
diff --git a/LinearAlgebra/LinearAlgebra.vcxproj b/LinearAlgebra/LinearAlgebra.vcxproj
index cf21a9d..005d004 100644
--- a/LinearAlgebra/LinearAlgebra.vcxproj
+++ b/LinearAlgebra/LinearAlgebra.vcxproj
@@ -140,6 +140,7 @@
+
@@ -147,6 +148,7 @@
+
diff --git a/LinearAlgebra/LinearAlgebra.vcxproj.filters b/LinearAlgebra/LinearAlgebra.vcxproj.filters
index 4552c9f..6f824dd 100644
--- a/LinearAlgebra/LinearAlgebra.vcxproj.filters
+++ b/LinearAlgebra/LinearAlgebra.vcxproj.filters
@@ -26,6 +26,9 @@
源文件
+
+ 源文件
+
@@ -40,5 +43,8 @@
头文件
+
+ 头文件
+
\ No newline at end of file
From dd7ac9fca6a6a11cdf08af82b32f18ea05e1b605 Mon Sep 17 00:00:00 2001
From: fbhou <1816118394@qq.com>
Date: Sat, 12 Dec 2020 21:31:12 +0800
Subject: [PATCH 2/4] Added evolution.h and evolution.cpp
---
LinearAlgebra/evolution.cpp | 107 ++++++++++++++++++++++++++++++++++++
LinearAlgebra/evolution.h | 45 +++++++++++++++
2 files changed, 152 insertions(+)
create mode 100644 LinearAlgebra/evolution.cpp
create mode 100644 LinearAlgebra/evolution.h
diff --git a/LinearAlgebra/evolution.cpp b/LinearAlgebra/evolution.cpp
new file mode 100644
index 0000000..763402a
--- /dev/null
+++ b/LinearAlgebra/evolution.cpp
@@ -0,0 +1,107 @@
+#include"linearvector.h"
+#include"matrix.h"
+#include"QuetionA.h"
+#include"evolution.h"
+
+/*
+source: The Matrix object you want to solve;
+size: Number of individuals in the species (200 in the article);
+max_generation: Maximum iteration times (1000 in the article);
+cross_pos: Possibility of crossing (0.6 in the article);
+cross_rate: Degree of crossing (0.66 in the article);
+mutate_pos: Possibility of mutation (0.05 in the article);
+mutate_rate: Dependence of mutation degree on the generation times (0.8 in the article);
+*/
+Eigenvalue::Eigenvalue(const Matrix& source, const int& size, const int& max_generation, const double& cross_pos, const double& cross_rate, const double& mutate_pos, const double& mutate_rate) {
+ this->source = source;
+ this->size = size;
+ this->max_generation = max_generation;
+ this->cross_pos = cross_pos;
+ this->cross_rate = cross_rate;
+ this->mutate_pos = mutate_pos;
+ this->mutate_rate = mutate_rate;
+}
+
+void initiallize(Eigenvalue e) {
+ e.generation = 0;
+ e.parents.clear(); e.children.clear();
+ e.eigenpolyval.clear(); e.sum_cost.clear();
+ e.upper_bound = 0.0;
+ for (int i = 0; i < e.source.get_row(); i++) {
+ for (int j = 0; j < e.source.get_column(); j++) {
+ e.upper_bound += std::fabs(e.source(i,j));
+ }
+ }
+ e.lower_bound = -e.upper_bound;
+ e.answers.clear();
+}
+double Eigenvalue::solve_eigenpolyval(double lam) {
+ tmp = source;
+ for (int i = 0; i < source.get_row(); i++) {
+ tmp(i, i) -= lam;
+ }
+ return std::fabs(tmp.determinant());
+}
+void solve_total(Eigenvalue e) {
+ double max_eigenpolyval = 0.0;
+ e.eigenpolyval.clear(); e.sum_cost.clear();
+ for (int i = 0; i < e.size; i++) {
+ e.eigenpolyval.push_back(e.solve_eigenpolyval(e.parents[i]));
+ if (e.eigenpolyval[i] > max_eigenpolyval) max_eigenpolyval = e.eigenpolyval[i];
+ }
+ e.sum_cost.push_back(e.eigenpolyval[0]);
+ for (int i = 1; i < e.size; i++) {
+ e.sum_cost.push_back(max_eigenpolyval-e.eigenpolyval[i]);
+ }
+}
+int Eigenvalue::choose(double proportion) {
+ for (int i = 0; i < size; i++) if (sum_cost[i] > proportion * sum_cost[size - 1]) return i;
+}
+void mutate(Eigenvalue e, int idx, bool opt, double ran) {
+ double tmp = e.children[idx];
+ if (opt) {
+ e.children[idx] += (e.upper_bound - tmp) * (1.0 - std::pow(ran, e.mutate_rate * (double)e.generation / e.max_generation));
+ }
+ else {
+ e.children[idx] += (tmp - e.lower_bound) * (1.0 - std::pow(ran, e.mutate_rate * (double)e.generation / e.max_generation));
+ }
+}
+void crossover(Eigenvalue e, int ida, int idb, bool opt) {
+ if (opt) {
+ e.children.push_back(e.cross_rate * e.parents[idb] + (1.0 - e.cross_rate) * e.parents[ida]);
+ e.children.push_back(e.cross_rate * e.parents[ida] + (1.0 - e.cross_rate) * e.parents[idb]);
+ }
+ else {
+ e.children.push_back(e.parents[ida]);
+ e.children.push_back(e.parents[idb]);
+ }
+}
+void produce_next(Eigenvalue e, std::mt19937 gen, std::uniform_real_distribution u) {
+ e.children.clear();
+ e.generation++;
+ solve_total(e);
+ int ida, idb;
+ for (int i = 0; i < (e.size >> 1); i++) {
+ ida = e.choose(u(gen));
+ idb = e.choose(u(gen));
+ crossover(e, ida, idb, u(gen) u(0.0, 1.0);
+ if (source.get_column() != source.get_row()) {
+ std::cerr << "Baka!! Non-square matrices have no eigenvalue!!" << std::endl;
+ return;
+ }
+ initiallize(*this);
+ std::sort(parents.begin(), parents.end());
+ answers.push_back(parents[0]);
+ for (int i = 1; i < size; i++) if(parents[i]-*answers.end() > eps){
+ answers.push_back(parents[i]);
+ }
+}
\ No newline at end of file
diff --git a/LinearAlgebra/evolution.h b/LinearAlgebra/evolution.h
new file mode 100644
index 0000000..8e46bb6
--- /dev/null
+++ b/LinearAlgebra/evolution.h
@@ -0,0 +1,45 @@
+#pragma once
+#ifndef EVOLUTION_H
+#define EVOLUTION_H
+#include"linearvector.h"
+#include"matrix.h"
+#include"QuetionA.h"
+#include
+#include
+#include
+#include
+#include
+#include
+
+class Eigenvalue {
+private:
+ Matrix source;
+ Matrix tmp;
+ int size,generation,max_generation;
+ std::vector parents;
+ std::vector children;
+ std::vector eigenpolyval;
+ std::vector sum_cost;
+ double cross_pos, cross_rate, mutate_pos, mutate_rate;
+ double eps = 1e-6;
+public:
+
+ double upper_bound, lower_bound;
+ std::vector answers;
+
+ Eigenvalue(const Matrix&, const int&, const int&, const double&, const double&, const double&, const double&);
+ ~Eigenvalue()=default;
+
+ friend void initiallize(Eigenvalue);
+ double solve_eigenpolyval(double x);
+ friend void solve_total(Eigenvalue);
+ int choose(double);
+ friend void mutate(Eigenvalue, int, bool, double);
+ friend void crossover(Eigenvalue, int, int, bool);
+ friend void produce_next(Eigenvalue, std::mt19937, std::uniform_real_distribution);
+ void solve_eigenvalue();
+};
+
+
+#endif
+
From cbe9413132523258397b384df08419864c84a2ed Mon Sep 17 00:00:00 2001
From: fbhou <1816118394@qq.com>
Date: Sun, 13 Dec 2020 01:55:13 +0800
Subject: [PATCH 3/4] Bug in evolution.cpp fixed
---
LinearAlgebra/evolution.cpp | 104 +++++++++++++++++++-----------------
LinearAlgebra/evolution.h | 12 ++---
LinearAlgebra/main.cpp | 19 +++++--
3 files changed, 74 insertions(+), 61 deletions(-)
diff --git a/LinearAlgebra/evolution.cpp b/LinearAlgebra/evolution.cpp
index 763402a..d3a4e4f 100644
--- a/LinearAlgebra/evolution.cpp
+++ b/LinearAlgebra/evolution.cpp
@@ -22,86 +22,90 @@ Eigenvalue::Eigenvalue(const Matrix& source, const int& size, const int& max_gen
this->mutate_rate = mutate_rate;
}
-void initiallize(Eigenvalue e) {
- e.generation = 0;
- e.parents.clear(); e.children.clear();
- e.eigenpolyval.clear(); e.sum_cost.clear();
- e.upper_bound = 0.0;
- for (int i = 0; i < e.source.get_row(); i++) {
- for (int j = 0; j < e.source.get_column(); j++) {
- e.upper_bound += std::fabs(e.source(i,j));
+void Eigenvalue::initiallize(std::mt19937 gen, std::uniform_real_distribution u) {
+ generation = 0;
+ parents.clear(); children.clear();
+ eigenpolyval.clear(); sum_cost.clear();
+ upper_bound = 0.0;
+ for (int i = 0; i < source.get_row(); i++) {
+ for (int j = 0; j < source.get_column(); j++) {
+ upper_bound += std::fabs(source(i,j));
}
}
- e.lower_bound = -e.upper_bound;
- e.answers.clear();
+ lower_bound = -upper_bound;
+ answers.clear();
+ for (int i = 0; i < size; i++) {
+ parents.push_back(u(gen)*(upper_bound-lower_bound)+lower_bound);
+ }
}
double Eigenvalue::solve_eigenpolyval(double lam) {
- tmp = source;
- for (int i = 0; i < source.get_row(); i++) {
- tmp(i, i) -= lam;
- }
- return std::fabs(tmp.determinant());
+ return std::fabs((source-lam*identity_matrix(source.get_column())).determinant());
}
-void solve_total(Eigenvalue e) {
+void Eigenvalue::solve_total() {
double max_eigenpolyval = 0.0;
- e.eigenpolyval.clear(); e.sum_cost.clear();
- for (int i = 0; i < e.size; i++) {
- e.eigenpolyval.push_back(e.solve_eigenpolyval(e.parents[i]));
- if (e.eigenpolyval[i] > max_eigenpolyval) max_eigenpolyval = e.eigenpolyval[i];
+ eigenpolyval.clear(); sum_cost.clear();
+ for (int i = 0; i < size; i++) {
+ eigenpolyval.push_back(solve_eigenpolyval(parents[i]));
+ if (eigenpolyval[i] > max_eigenpolyval) max_eigenpolyval = eigenpolyval[i];
}
- e.sum_cost.push_back(e.eigenpolyval[0]);
- for (int i = 1; i < e.size; i++) {
- e.sum_cost.push_back(max_eigenpolyval-e.eigenpolyval[i]);
+ sum_cost.push_back(max_eigenpolyval - eigenpolyval[0]);
+ for (int i = 1; i < size; i++) {
+ sum_cost.push_back(sum_cost[i-1] + max_eigenpolyval - eigenpolyval[i]);
}
}
int Eigenvalue::choose(double proportion) {
- for (int i = 0; i < size; i++) if (sum_cost[i] > proportion * sum_cost[size - 1]) return i;
+ for (int i = 0; i < size; i++) {
+ if (sum_cost[i] > proportion * sum_cost[size - 1]) return i;
+ }
}
-void mutate(Eigenvalue e, int idx, bool opt, double ran) {
- double tmp = e.children[idx];
+void Eigenvalue::mutate(int idx, bool opt, double ran) {
+ double tmp = children[idx];
if (opt) {
- e.children[idx] += (e.upper_bound - tmp) * (1.0 - std::pow(ran, e.mutate_rate * (double)e.generation / e.max_generation));
+ children[idx] += (upper_bound - tmp) * (1.0 - std::pow(ran, mutate_rate * (double)generation / max_generation));
}
else {
- e.children[idx] += (tmp - e.lower_bound) * (1.0 - std::pow(ran, e.mutate_rate * (double)e.generation / e.max_generation));
+ children[idx] -= (tmp - lower_bound) * (1.0 - std::pow(ran, mutate_rate * (double)generation / max_generation));
}
}
-void crossover(Eigenvalue e, int ida, int idb, bool opt) {
+void Eigenvalue::crossover(int ida, int idb, bool opt) {
if (opt) {
- e.children.push_back(e.cross_rate * e.parents[idb] + (1.0 - e.cross_rate) * e.parents[ida]);
- e.children.push_back(e.cross_rate * e.parents[ida] + (1.0 - e.cross_rate) * e.parents[idb]);
+ children.push_back(cross_rate * parents[idb] + (1.0 - cross_rate) * parents[ida]);
+ children.push_back(cross_rate * parents[ida] + (1.0 - cross_rate) * parents[idb]);
}
else {
- e.children.push_back(e.parents[ida]);
- e.children.push_back(e.parents[idb]);
+ children.push_back(parents[ida]);
+ children.push_back(parents[idb]);
}
}
-void produce_next(Eigenvalue e, std::mt19937 gen, std::uniform_real_distribution u) {
- e.children.clear();
- e.generation++;
- solve_total(e);
+void Eigenvalue::produce_next(std::mt19937 gen, std::uniform_real_distribution u) {
+ children.clear();
+ generation++;
+ solve_total();
int ida, idb;
- for (int i = 0; i < (e.size >> 1); i++) {
- ida = e.choose(u(gen));
- idb = e.choose(u(gen));
- crossover(e, ida, idb, u(gen)> 1); i++) {
+ ida = choose(u(gen));
+ idb = choose(u(gen));
+ crossover(ida, idb, u(gen) u(0.0, 1.0);
if (source.get_column() != source.get_row()) {
- std::cerr << "Baka!! Non-square matrices have no eigenvalue!!" << std::endl;
+ std::cerr << "[ERROR]Non-square matrices have no eigenvalue!!" << std::endl;
return;
}
- initiallize(*this);
+ initiallize(gen,u);
+ for (int i = 0; i < max_generation; i++) {
+ produce_next(gen, u);
+ }
std::sort(parents.begin(), parents.end());
- answers.push_back(parents[0]);
- for (int i = 1; i < size; i++) if(parents[i]-*answers.end() > eps){
- answers.push_back(parents[i]);
+
+ for (int i = 0; i < size; i++) {
+ if (solve_eigenpolyval(parents[i]) < eps2&&(answers.empty()||parents[i]-*(answers.end()-1)>eps)) answers.push_back(parents[i]);
}
-}
\ No newline at end of file
+}
diff --git a/LinearAlgebra/evolution.h b/LinearAlgebra/evolution.h
index 8e46bb6..74ccfdd 100644
--- a/LinearAlgebra/evolution.h
+++ b/LinearAlgebra/evolution.h
@@ -21,7 +21,7 @@ class Eigenvalue {
std::vector eigenpolyval;
std::vector sum_cost;
double cross_pos, cross_rate, mutate_pos, mutate_rate;
- double eps = 1e-6;
+ double eps = 1e-3, eps2=1e-3;
public:
double upper_bound, lower_bound;
@@ -30,13 +30,13 @@ class Eigenvalue {
Eigenvalue(const Matrix&, const int&, const int&, const double&, const double&, const double&, const double&);
~Eigenvalue()=default;
- friend void initiallize(Eigenvalue);
+ void initiallize(std::mt19937, std::uniform_real_distribution);
double solve_eigenpolyval(double x);
- friend void solve_total(Eigenvalue);
+ void solve_total();
int choose(double);
- friend void mutate(Eigenvalue, int, bool, double);
- friend void crossover(Eigenvalue, int, int, bool);
- friend void produce_next(Eigenvalue, std::mt19937, std::uniform_real_distribution);
+ void mutate(int, bool, double);
+ void crossover(int, int, bool);
+ void produce_next(std::mt19937, std::uniform_real_distribution);
void solve_eigenvalue();
};
diff --git a/LinearAlgebra/main.cpp b/LinearAlgebra/main.cpp
index 5d4bc71..61fc774 100644
--- a/LinearAlgebra/main.cpp
+++ b/LinearAlgebra/main.cpp
@@ -1,12 +1,21 @@
#include
#include"QuetionA.h"
#include"QuetionB.h"
+#include"evolution.h"
int main()
{
- std::cout<<"////////////////////////////////////////QUETION1////////////////////////////////////////"<
Date: Tue, 15 Dec 2020 22:13:23 +0800
Subject: [PATCH 4/4] Renamed evolution.cpp/.h as GA.cpp/.h, in consistence
with common habits
---
LinearAlgebra/{evolution.cpp => GA.cpp} | 2 +-
LinearAlgebra/{evolution.h => GA.h} | 2 +-
LinearAlgebra/LinearAlgebra.vcxproj | 4 ++--
LinearAlgebra/LinearAlgebra.vcxproj.filters | 4 ++--
LinearAlgebra/main.cpp | 4 ++--
5 files changed, 8 insertions(+), 8 deletions(-)
rename LinearAlgebra/{evolution.cpp => GA.cpp} (99%)
rename LinearAlgebra/{evolution.h => GA.h} (97%)
diff --git a/LinearAlgebra/evolution.cpp b/LinearAlgebra/GA.cpp
similarity index 99%
rename from LinearAlgebra/evolution.cpp
rename to LinearAlgebra/GA.cpp
index d3a4e4f..318e56c 100644
--- a/LinearAlgebra/evolution.cpp
+++ b/LinearAlgebra/GA.cpp
@@ -1,7 +1,7 @@
#include"linearvector.h"
#include"matrix.h"
#include"QuetionA.h"
-#include"evolution.h"
+#include"GA.h"
/*
source: The Matrix object you want to solve;
diff --git a/LinearAlgebra/evolution.h b/LinearAlgebra/GA.h
similarity index 97%
rename from LinearAlgebra/evolution.h
rename to LinearAlgebra/GA.h
index 74ccfdd..9bd1fa3 100644
--- a/LinearAlgebra/evolution.h
+++ b/LinearAlgebra/GA.h
@@ -21,7 +21,7 @@ class Eigenvalue {
std::vector eigenpolyval;
std::vector sum_cost;
double cross_pos, cross_rate, mutate_pos, mutate_rate;
- double eps = 1e-3, eps2=1e-3;
+ double eps = 1e-3, eps2=1e-2;
public:
double upper_bound, lower_bound;
diff --git a/LinearAlgebra/LinearAlgebra.vcxproj b/LinearAlgebra/LinearAlgebra.vcxproj
index 005d004..bfc297e 100644
--- a/LinearAlgebra/LinearAlgebra.vcxproj
+++ b/LinearAlgebra/LinearAlgebra.vcxproj
@@ -140,7 +140,7 @@
-
+
@@ -148,7 +148,7 @@
-
+
diff --git a/LinearAlgebra/LinearAlgebra.vcxproj.filters b/LinearAlgebra/LinearAlgebra.vcxproj.filters
index 6f824dd..3c6a97f 100644
--- a/LinearAlgebra/LinearAlgebra.vcxproj.filters
+++ b/LinearAlgebra/LinearAlgebra.vcxproj.filters
@@ -26,7 +26,7 @@
源文件
-
+
源文件
@@ -43,7 +43,7 @@
头文件
-
+
头文件
diff --git a/LinearAlgebra/main.cpp b/LinearAlgebra/main.cpp
index 61fc774..c7280dd 100644
--- a/LinearAlgebra/main.cpp
+++ b/LinearAlgebra/main.cpp
@@ -1,7 +1,7 @@
#include
#include"QuetionA.h"
#include"QuetionB.h"
-#include"evolution.h"
+#include"GA.h"
int main()
{
// std::cout<<"////////////////////////////////////////QUETION1////////////////////////////////////////"<