遗传算法求f(x)=x1^2+x2^2最大值,其中0<=x1,x2<=7。
//this program uses SGA to calculate the maximum value of f(x) = x1^2 + x2^2
#include <iostream>
#include <ctime>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#define LENGTH 3
using namespace std;
class chromosome
{
public:
int x1,x2;
int value;
double fitness;
void assign(int a,int b)
{
x1 = a;
x2 = b;
cal_value();
}
void cal_value()
{
value = x1 << LENGTH;
value |= x2;
}
void cal_fitness()
{
fitness = x1*x1 + x2*x2;
}
};
double total_fitness = 0;
vector<chromosome> population[2];
vector<chromosome> temp;
int cop_counter = 0;
int selector = 0;
int and1 = ((1 << LENGTH) - 1) << LENGTH;
int and2 = (1 << LENGTH) - 1;
int variation_percent = 2;
int random(int end)
{
return rand() % (end + 1);
}
//选择
void select_population()
{
int counter = 0;
int new_sel = (selector + 1) % 2;
population[new_sel].clear();
while (counter <= 3)
{
int pos = population[selector].size() - 1;
int r = random(total_fitness);
int end = population[selector][0].fitness;
for (int i = 1;i < (int)population[selector].size();i++)
if (r <= end)
{
pos = i - 1;
break;
}
else
end += population[selector][i].fitness;
population[new_sel].push_back(population[selector][pos]);
counter++;
}
}
//两个染色体进行交配
void cop(chromosome &temp1, chromosome &temp2)
{
chromosome new1, new2;
int pos = random(LENGTH * 2 - 2);//0..LENGTH * 2 - 2 (end position)
int v1 = temp1.value;
int v2 = temp2.value;
int length = LENGTH * 2;
int num1 = ((1 << pos) - 1) << (length - pos);
int num2 = ((1 << (length - pos)) - 1);
int part11 = v1 & num1;
int part12 = v1 & num2;
int part21 = v2 & num1;
int part22 = v2 & num2;
int new_v1 = part11 | part22;
int new_v2 = part21 | part12;
new1.assign((new_v1 & and1) >> LENGTH, new_v1 & and2);
new2.assign((new_v2 & and1) >> LENGTH, new_v2 & and2);
temp.push_back(new1);
temp.push_back(new2);
}
//种群内随机进行两两交配
void copulation()
{
chromosome temp1,temp2;
int remainder = 4;
int r1,r2;
int new_sel = (selector + 1) % 2;
cop_counter = 0;
while (remainder)
{
r1 = random(remainder-1);
temp1 = population[new_sel][r1];
population[new_sel].erase(population[new_sel].begin() + r1);
remainder--;
r2 = random(remainder-1);
temp2 = population[new_sel][r2];
population[new_sel].erase(population[new_sel].begin() + r2);
remainder--;
cop(temp1,temp2);
}
population[new_sel] = temp;
temp.clear();
}
//变异
void variation()
{
int new_sel = (selector + 1) % 2;
for (int i = 0;i < (int)population[new_sel].size();i++)
{
int rand = random(99) + 1;
if (rand <= 2)
{
int pos = random(LENGTH * 2 - 1) + 1;
int num = 1 << (LENGTH * 2 - pos);
population[new_sel][i].value ^= num;
population[new_sel][i].x1 = (population[new_sel][i].value & and1) >> LENGTH;
population[new_sel][i].x2 = population[new_sel][i].value & and2;
}
}
}
//更新适应度
void update_fitness()
{
total_fitness = 0;
for (int i = 0;i < (int)population[selector].size();i++)
{
population[selector][i].cal_fitness();
total_fitness += population[selector][i].fitness;
}
}
bool cmp(chromosome a,chromosome b)
{
return a.fitness < b.fitness;
}
//initial population: 1 6, 2 4, 3 5, 4 1
void init()
{
srand((unsigned)time(NULL));
chromosome chr;
chr.assign(1,6);
population[0].push_back(chr);
chr.assign(2,4);
population[0].push_back(chr);
chr.assign(3,5);
population[0].push_back(chr);
chr.assign(4,1);
population[0].push_back(chr);
}
//debug
/*int b[100];
char str[100];
int bcounter=0;
void tobinary(int x)
{
memset(b,0,sizeof(b));
bcounter=0;
while (x>0)
{
b[bcounter++]=x%2;
x/=2;
}
int i;
for (i = 0;i < 6;i++)
str[i]=b[5-i]+'0';
str[i]='\0';
}*/
int main()
{
int counter = 0;
init();
int maxn = 0;
int maxvalue;
while (counter <= 1000)
{
update_fitness();
sort(population[selector].begin(),population[selector].end(),cmp);
if (population[selector][population[selector].size() - 1].fitness > maxn)
{
maxn = population[selector][population[selector].size() - 1].fitness;
maxvalue = population[selector][population[selector].size() - 1].value;
}
select_population();
copulation();
variation();
selector = (selector + 1) % 2;
counter++;
}
printf("x1:%d x2:%d\n",(maxvalue&and1)>>LENGTH,maxvalue&and2);
}