You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

357 lines
9.2 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#include<cmath>
#include<ctime>
#include<iostream>
#include<cstdlib>
using namespace std;
const int Length{ 50 };//染色体长度。使精度可以达到0.01
const int population_size{ 30 };//种群大小
const int double_size{ 2 * population_size };//方便选择函数的操作
const int numbers{ 3 };
const int trilength{ 3 * Length };//交叉函数
const double Error = 1e-6;
double coefficients[numbers][numbers];
double constants[numbers];
class individual;
class Population;
class chromosome
{
private:
double* Chromosome;
public:
friend void exchange(chromosome& c1, chromosome& c2, int j);//染色体交换
chromosome() {
Chromosome = new double[Length];
for (int i = 0; i < Length; ++i)
{
Chromosome[i] = rand() % 2;
}
}
~chromosome()
{
if (!Chromosome)
delete[] Chromosome;
}
double transform()
{
double x = 0;
for (int i = 0; i < Length - 2; ++i) {
x += Chromosome[Length - 1 - i] * pow(2.0, i);
}
if (Chromosome[0] == 1) x = -x; // 处理最高位的符号
return x * 0.000000001; // 转换到实际数值范围
}//转换成十进制
void print_chromosome()
{
for (int i{ 0 }; i < Length; ++i)
{
cout << Chromosome[i];
}
cout << '\n';
};
void print_value()
{
cout << transform() << '\n';
}
void copy_chromosome(const chromosome& c1)
{
delete[]Chromosome;
Chromosome = new double[Length];
for (int i{ 0 }; i < Length; ++i)
{
Chromosome[i] = c1.Chromosome[i];
}
}
friend class individual;
friend class Population;
};
void exchange(chromosome& c1, chromosome& c2, int j)
{
double useless{ 0 };
useless = c1.Chromosome[j];
c1.Chromosome[j] = c2.Chromosome[j];
c2.Chromosome[j] = useless;
//cout << "第" << j + 1 << "条染色体" << endl;
}
class individual
{
private:
chromosome individual_chromosomes[numbers];//染色体
double fitness;//适应度
double error;//代入方程的误差
public:
individual();//初始化
~individual()
{
if (!individual_chromosomes)
delete[]individual_chromosomes;
}
void calculate_error()//求误差
{
double error1{ Error };
for (int i = 0; i < numbers; ++i)
{
double a = coefficients[i][0] * individual_chromosomes[0].transform() + coefficients[i][1] * individual_chromosomes[1].transform() + coefficients[i][2] * individual_chromosomes[2].transform();
error1 += pow(constants[i] - a, 2);
}
error = error1;
}
//求适应度
double calculate_fitness()
{
calculate_error();
double log = std::log(error);
if (log < 0)
{
fitness = 100 - pow(10, log) * 10;
}
else
{
fitness = 90 - 10 * log;
}
return fitness;
}
void print_chromosomes()
{
for (int i{ 0 }; i < numbers; ++i)
{
cout << "" << i + 1 << "条染色体为:";
individual_chromosomes[i].print_chromosome();
}
}
void print_values()
{
for (int i{ 0 }; i < numbers; ++i)
{
cout << "" << i + 1 << "个未知数为:";
individual_chromosomes[i].print_value();
}
}
void copy_individual(const individual& i1)
{
for (int i{ 0 }; i < numbers; ++i)
{
individual_chromosomes[i].copy_chromosome(i1.individual_chromosomes[i]);
}
fitness = i1.fitness;
error = i1.error;
}
double get_fitness()
{
return fitness;
}
friend class Population;
friend void exchange(individual& i1, individual& i2);
};
individual::individual()
{
for (int i{ 0 }; i < numbers; ++i)
{
individual_chromosomes[i] = chromosome();
}
calculate_error();
fitness = calculate_fitness();
}
void exchange(individual& i1, individual& i2)
{
int max_digit = static_cast<int>(floor(sqrt(trilength)));//最多改变sqrt位
int digit{ max_digit };
while (digit > 0)
{
int i = rand() % trilength;
int j = i % Length;
i = i / Length;
exchange(i1.individual_chromosomes[i], i2.individual_chromosomes[i], j);
digit -= 1;
}
}
class Population
{
double variation_rate;
double variation_degree;//变异率和最大变异幅度
public:
int selection();//选择函数
void produce();//繁殖函数
int generation;//迭代次数
void mutate();//变异
individual population[double_size + 1];//种群2倍+1为了交叉和后续交换顺序
Population(int _generation = 100) : variation_rate(0.02), variation_degree(0.14), generation(_generation)
{
for (int i = 0; i < population_size; ++i)
{
population[i] = individual();
}
} // 构造函数初始化变异率和变异幅度,设置迭代次数,初始化种群
//种群初始化
void print_population()
{
for (int i{ 0 }; i < population_size; ++i)
{
cout << "" << i + 1 << "个个体:" << endl;
population[i].print_chromosomes();
}
}
double get_max_fitness()
{
double max_fitness = population[0].fitness;
for (int i = 0; i < double_size + 1; ++i)
{
if (population[i].fitness > max_fitness)
{
max_fitness = population[i].fitness;
}
}
return max_fitness;
}
};
void exchange(Population& a, Population& b)
{
int times = rand() % population_size;
while (times > 0)
{
int i = rand() % population_size;
int j = (i + rand()) % population_size;
if (i == j)times -= 1;
else
{
exchange(a.population[j], b.population[j]);
//cout << "交换了第" << j + 1 << "个个体的" << endl;
a.population[j].calculate_fitness();
b.population[j].calculate_fitness();
times -= 1;
}
}
}
void Population::mutate()
{
for (int i = 0; i < population_size; ++i)
{
for (int j = 0; j < numbers; ++j)
{
double random = rand() * 1.0 / RAND_MAX;//产生一个0到1之间的随机数
if (random < variation_rate)
{
int position = rand() % 20;
if (population[i].individual_chromosomes[j].Chromosome[position] == 1)
population[i].individual_chromosomes[j].Chromosome[position] = 0;
else
population[i].individual_chromosomes[j].Chromosome[position] = 1;
}
}
}
}
int Population::selection()
{
double total_fitness = 0;
for (int i = 0; i < population_size; ++i) {
total_fitness += population[i].calculate_fitness();
}
double random = (double)rand() / RAND_MAX * total_fitness;
double current_sum = 0;
for (int i = 0; i < population_size; ++i) {
current_sum += population[i].calculate_fitness();
if (current_sum >= random)
{
return i;
}
}
return -1;
}//选择适应度最高的,给予下标
void Population::produce()
{
for (int i{ population_size }; i < double_size; ++i)
{
population[i].copy_individual(population[i - population_size]);
}
for (int i{ 0 }; i < population_size - 1; ++i)
{
exchange(population[i], population[i + 1]);
}
for (int i{ 0 }; i < population_size - 1; ++i)
{
if (population[i].calculate_fitness() < population[i + population_size].calculate_fitness())
{
population[double_size].copy_individual(population[i]);
population[i].copy_individual(population[i + population_size]);
population[i + population_size].copy_individual(population[double_size]);
}
}
}
int main()
{
srand(static_cast<unsigned int>(time(0)));
/*int a;
cout << "请输入迭代次数";
cin >> a;
generation = a;*/
for (int i = 0; i < numbers; ++i)
{
cout << "请输入第 " << i + 1 << " 个方程的系数 (用空格分隔): ";
for (int j = 0; j < numbers; ++j)
{
cin >> coefficients[i][j];
}
cout << "请输入第 " << i + 1 << " 个方程的常数项: ";
cin >> constants[i];
}
int _generation;
cout << "请输入迭代次数:";
cin >> _generation;
Population a(_generation);
a.print_population();
int one1 = a.selection();
cout << "初始值:" << endl;
a.population[one1].print_values();
int times = 0;
Population b;
while (a.get_max_fitness() < 100)
{
a.mutate();
a.produce();
if (times % 1000 == 0&&times!=0)
{
cout << "这是第" << times << "迭代,最合适的解为:";
int one = a.selection();
a.population[one].print_values();
}
++times;
if (times > a.generation)
{
break;
}
}
int one = a.selection();
cout << "迭代最终解为:" << endl;
a.print_population();
a.population[one].print_values();
}