#include <iostream>
#include <time.h> //产生随机数要用到使每次产生的数不同。
#include <math.h>
using namespace std;
const double pi = 3.1415926;
const int MAX = 4194304;
const int MIN = 0;
class Individuality //个体类
{
private:
int chromosome; //染色体
public:
void set(int chromosome)
{
this->chromosome = chromosome;
}
Individuality operator =(Individuality c)//重载等号
{
this->chromosome = c.chromosome;
return *this;
}
bool operator ==(Individuality c)//判相等
{
return this->chromosome == c.chromosome;
}
float resolve() //通过染色体取得x的值
{
return -1.0 + (float)chromosome * 3.0 / (MAX - 1);
}
float evaluate() //f()
{
return resolve() * (float)sin(10*pi*resolve()) + 1.0;
}
void print()
{
cout << '\t';
for(int j = 21; j >= 0; j--) //以下循环是在以二进制串的形式打印染色体
{
if((1<<j) & chromosome)
cout << '1';
else
cout << '0';
}
cout << "\t\tx = " << resolve() << "\tf(x) = " << evaluate() << endl;
}
//以下是对当前个体进行变异的操作
Individuality variate() {
int i = rand() % 21 + 1;
this->chromosome ^= 1<<i;
return *this;
}
//以下是两个个体进行交叉,并且返回两个新个体的操作
void crisscross(Individuality prnt1, Individuality prnt2, Individuality &child1, Individuality &child2)
{
int i = rand() % 21 + 1;
int temp1 = prnt1.chromosome;
int temp2 = prnt2.chromosome;
int temp = 0;
for(; i < 22; i++)
temp += 1<<i;
temp1 &= temp;
temp2 &= temp;
prnt1.chromosome &= ~temp;
prnt2.chromosome &= ~temp;
prnt1.chromosome |= temp2;
prnt2.chromosome |= temp1;
child1 = prnt1;
child2 = prnt2;
}
};
//建立一个种群的类,并且有固定的大小
const int POP_SIZE = 200;
/*================================
每次遗传,选出f(x)的排名在前50%的个体进行遗传(排名通过希尔排序实现),
都会有约1%的个体变异,10%的个体发生交叉遗传,其余的直接遗传。每次遗传都
记录下本次f(x)为最大的个体Max。遗传150次,如果过程中发现已有30代的Max一
直不变了,说明已达到最优,基本不需要再遗传了,所以提前跳出循环。
===================================*/
class Population //种群类
{
private:
Individuality ind[POP_SIZE];
public:
Population()
{
for(int i = 0; i < POP_SIZE; i++)
ind[i].set( (((double)rand()/(double)RAND_MAX) * MAX + MIN));
}
void shellSort() //希尔排序
{
int gap, i, j;
Individuality temp;
for(gap = POP_SIZE/2; gap > 0; gap /= 2)
for(i = gap; i < POP_SIZE; i++)
for(j=i-gap; j>=0 && ind[j].evaluate() < ind[j+gap].evaluate(); j -= gap)
{
temp = ind[j];
ind[j] = ind[j+gap];
ind[j+gap] = temp;
}
}
void inherit()
{
Population::shellSort();
const int NT = POP_SIZE / 2;
int nc = (rand() % (POP_SIZE/10) + (POP_SIZE/4)) / 2;
int nv = rand() % (POP_SIZE/100+1) + (POP_SIZE/100);
int i, n1, n2;
Individuality temp[NT];
for(i = 0; i < NT; i++)
temp[i] = ind[i];
for(i = 0; i < nv; i++)
{
n1 = rand() % NT;
ind[i] = temp[n1].variate();
}
for(i = nv; i < nc; i += 2)
{
n1 = rand() % NT;
n2 = rand() % NT;
Individuality temp1, temp2;
temp->crisscross(temp[n1], temp[n2], temp1, temp2);
ind[i] = temp1; ind[i+1] = temp2;
}
for(i = nv+nc*2; i < POP_SIZE; i++)
{
n1 = rand() % NT;
ind[i] = temp[n1];
}
}
Individuality getMax()
{
Individuality max = ind[0];
for(int i = 0; i < POP_SIZE-1; i++)
{
if( ind[i+1].evaluate() > ind[i].evaluate() ) max = ind[i+1];
}
return max;
}
void traverse()
{
for(int i = 0; i < POP_SIZE; i++)
ind[i].print();
cout << endl;
}
};
int main()
{
srand( (unsigned)time( NULL ) );
Population a;
a.traverse();
int count = 0;
int gen = 0;
for(int i = 0; i < 150; i++)
{
Individuality temp = a.getMax();
a.inherit();
if(a.getMax() == temp) count++;
if(count > 30) break;
a.traverse();
gen++;
}
cout << "The max is:\n";
a.getMax().print();
cout << "After " << gen << " generations.\n";
return 0;
}
- 1
- 2
- 3
前往页