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

#include<cmath>
#include<ctime>
#include<iostream>
#include<cstdlib>
using namespace std;
const int Length{ 50 };//Ⱦɫ<C8BE><EFBFBD>ȡ<EFBFBD>ʹ<EFBFBD><CAB9><EFBFBD>ȿ<EFBFBD><C8BF>Դﵽ0.01
const int population_size{ 30 };//<2F><>Ⱥ<EFBFBD><C8BA>С
const int double_size{ 2 * population_size };//<2F><><EFBFBD><EFBFBD>ѡ<EFBFBD><D1A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>IJ<EFBFBD><C4B2><EFBFBD>
const int numbers{ 3 };
const int trilength{ 3 * Length };//<2F><><EFBFBD><EFBFBD><E6BAAF>
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);//Ⱦɫ<C8BE><EFBFBD><E5BDBB>
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; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>λ<EFBFBD>ķ<EFBFBD><C4B7><EFBFBD>
return x * 0.000000001; // ת<><D7AA><EFBFBD><EFBFBD>ʵ<EFBFBD><CAB5><EFBFBD><EFBFBD>ֵ<EFBFBD><D6B5>Χ
}//ת<><D7AA><EFBFBD><EFBFBD>ʮ<EFBFBD><CAAE><EFBFBD><EFBFBD>
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 << "<22><>" << j + 1 << "<22><>Ⱦɫ<C8BE><C9AB>" << endl;
}
class individual
{
private:
chromosome individual_chromosomes[numbers];//Ⱦɫ<C8BE><C9AB>
double fitness;//<2F><>Ӧ<EFBFBD><D3A6>
double error;//<2F><><EFBFBD><EFBFBD>̵<EFBFBD><CCB5><EFBFBD><EFBFBD><EFBFBD>
public:
individual();//<2F><>ʼ<EFBFBD><CABC>
~individual()
{
if (!individual_chromosomes)
delete[]individual_chromosomes;
}
void calculate_error()//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
{
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;
}
//<2F><><EFBFBD><EFBFBD>Ӧ<EFBFBD><D3A6>
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 << "<EFBFBD><EFBFBD>" << i + 1 << "<EFBFBD><EFBFBD>Ⱦɫ<EFBFBD><EFBFBD>Ϊ<EFBFBD><EFBFBD>";
individual_chromosomes[i].print_chromosome();
}
}
void print_values()
{
for (int i{ 0 }; i < numbers; ++i)
{
cout << "<EFBFBD><EFBFBD>" << i + 1 << "<EFBFBD><EFBFBD>δ֪<EFBFBD><EFBFBD>Ϊ<EFBFBD><EFBFBD>";
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)));//<2F><><EFBFBD><EFBFBD><EFBFBD>ı<EFBFBD>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;//<2F><><EFBFBD><EFBFBD><EFBFBD>ʺ<EFBFBD><CABA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
public:
int selection();//ѡ<><D1A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
void produce();//<2F><>ֳ<EFBFBD><D6B3><EFBFBD><EFBFBD>
int generation;//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
void mutate();//<2F><><EFBFBD><EFBFBD>
individual population[double_size + 1];//<2F><>Ⱥ<EFBFBD><C8BA>2<EFBFBD><32>+1Ϊ<31>˽<EFBFBD><CBBD><EFBFBD><EFBFBD>ͺ<EFBFBD><CDBA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>˳<EFBFBD><CBB3>
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();
}
} // <20><><EFBFBD><EFBFBD><ECBAAF><EFBFBD><EFBFBD>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʺͱ<CABA><CDB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>,<2C><><EFBFBD>õ<EFBFBD><C3B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>,<2C><>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD>Ⱥ
//<2F><>Ⱥ<EFBFBD><C8BA>ʼ<EFBFBD><CABC>
void print_population()
{
for (int i{ 0 }; i < population_size; ++i)
{
cout << "<EFBFBD><EFBFBD>" << i + 1 << "<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>" << 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 << "<22><><EFBFBD><EFBFBD><EFBFBD>˵<EFBFBD>" << j + 1 << "<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>" << 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;//<2F><><EFBFBD><EFBFBD>һ<EFBFBD><D2BB>0<EFBFBD><30><31><D6AE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
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;
}//ѡ<><D1A1><EFBFBD><EFBFBD>Ӧ<EFBFBD><D3A6><EFBFBD><EFBFBD><EFBFBD>ߵģ<DFB5><C4A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>±<EFBFBD>
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 << "<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>";
cin >> a;
generation = a;*/
for (int i = 0; i < numbers; ++i)
{
cout << "<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> " << i + 1 << " <20><><EFBFBD><EFBFBD><EFBFBD>̵<EFBFBD>ϵ<EFBFBD><CFB5> (<28>ÿո<C3BF><D5B8>ָ<EFBFBD>): ";
for (int j = 0; j < numbers; ++j)
{
cin >> coefficients[i][j];
}
cout << "<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> " << i + 1 << " <20><><EFBFBD><EFBFBD><EFBFBD>̵ij<CCB5><C4B3><EFBFBD><EFBFBD><EFBFBD>: ";
cin >> constants[i];
}
int _generation;
cout << "<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>";
cin >> _generation;
Population a(_generation);
a.print_population();
int one1 = a.selection();
cout << "<EFBFBD><EFBFBD>ʼֵ<EFBFBD><EFBFBD>" << 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 << "<EFBFBD><EFBFBD><EFBFBD>ǵ<EFBFBD>" << times << "<EFBFBD><EFBFBD><EFBFBD><EFBFBD>,<2C><><EFBFBD><EFBFBD><EFBFBD>ʵĽ<CAB5>Ϊ<EFBFBD><CEAA>";
int one = a.selection();
a.population[one].print_values();
}
++times;
if (times > a.generation)
{
break;
}
}
int one = a.selection();
cout << "<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ս<EFBFBD>Ϊ<EFBFBD><EFBFBD>" << endl;
a.print_population();
a.population[one].print_values();
}