写的遗传算法,参考的是这篇文章<a target=_blank href="http://blog.csdn.net/b2b160/article/details/4680853/">http://blog.csdn.net/b2b160/article/details/4680853/</a>
这个程序求的是函数y=Xin(10πX)2在区间0-0.25上的最大值
函数图像可以去<a target=_blank href="http://graph.tk/">http://graph.tk/</a>
要是想看完整运行过程的就自己加个PLAUS然后把COUT的注释去了
#include<iostream>
#include<string>
#include<math.h>
#include<stack>
#include<stdlib.h>
#include<time.h>
#include<windows.h>
using namespace std;
double Max_Y=0;///最大的评估值
int Cut_P,k;//全局变量,拿来存切割点
string s_temp1,s_temp2;//零时字符串
string::iterator s_i;//迭代器
double f(double x)
{
return x*sin(31.415*x)+2;
///区间为 0-0.25,精确度为0.001
///分为25000份
///111111111111111=32767
///110000110101000=25000
}
double bin(const string &p){///二进制到十进制
double num=0;
for(int i=p.length()-1;i>=0;i--){
num+=(p[i]-48)*pow(2,p.length()-1-i);
}
return num;
}
void _swap(string &a,string &b){///姐妹染色单体联会=。=
//cout<<"联会开始"<<endl;
while(true){
Cut_P=rand()%a.length();//随机切割位点
Cut_P=Cut_P!=0?Cut_P-1:Cut_P;//错误检测,位点为0时会有-1
s_temp1=a.substr(Cut_P,a.length()-1-Cut_P);//最少要切割1个基因
s_temp2=b.substr(Cut_P,b.length()-1-Cut_P);//最少要切割1个基因
///从切点把后面全部交换
///system("pause");
for(s_i=a.begin(),k=0;k<(Cut_P);k++)s_i++;
///system("pause");
//cout<<"联会之前:"<<endl<<a<<endl<<b<<endl<<"联会位置:"<<Cut_P<<" 联会片段:"<<s_temp1<<"-"<<s_temp2<<endl;
a.replace(Cut_P,a.length()-1-Cut_P,s_temp2);//替换
b.replace(Cut_P,b.length()-1-Cut_P,s_temp1);//替换
///system("pause");
if(bin(a)<25000||bin(b)<25000)break;
}
//cout<<"联会终了!"<<endl;
}
void variation(string &p){//变异
//cout<<"变异开始"<<endl;
while(true){
Cut_P=rand()%p.length()-1;//随机变异位点
Cut_P=Cut_P!=0?Cut_P-1:Cut_P;//错误检测,位点为0时会有-1
p[Cut_P]=!(p[Cut_P]-48)+48;
if(bin(p)<25000)break;
}
//cout<<"变异结束"<<endl;
}
int main()
{
int i,j,ij=0;//洗脑循环用
string S_1,S_2,S_3,S_4;//每一轮进化的4个生物
double y_1,y_2,y_3,y_4;//4个生物的评估值
double G_1,G_2,G_3,G_4;//4个生物的进化概率
double total_G;//分母。。
double T_1;//随机数
int q=0,w=0,e=0,r=0;//。。。淘汰记录,选择次数,用来选择
srand(GetTickCount());
stack<string> a,b;
string p,_p;
cout<<"母本:"<<endl;
for(i=0;i<4;i++){
for(j=0;j<15;j++){
p.insert(p.length(),1,rand()%2+48);
}
if(bin(p)>25000){
i--;
p=_p;
continue;
}
cout<<p<<endl;
a.push(p);///入栈
//生成4个初始生物
}
// system("pause");
while(ij<1000){///sa,开始进化吧!
//cout<<"第"<<ij+1<<"代"<<endl;
S_1=(a.top());a.pop();
S_2=(a.top());a.pop();
S_3=(a.top());a.pop();
S_4=(a.top());a.pop();
///全部取出
//
y_1=f(bin(S_1)*0.00001)<0?0:f(bin(S_1)*0.00001);
y_2=f(bin(S_2)*0.00001)<0?0:f(bin(S_2)*0.00001);
y_3=f(bin(S_3)*0.00001)<0?0:f(bin(S_3)*0.00001);
y_4=f(bin(S_4)*0.00001)<0?0:f(bin(S_4)*0.00001);
///计算评估值
if(y_1>y_2&&y_1>y_3&&y_1>y_4&&y_1>Max_Y)
Max_Y=y_1;
else if(y_2>y_2&&y_2>y_3&&y_2>y_4&&y_2>Max_Y)
Max_Y=y_2;
else if(y_3>y_2&&y_3>y_1&&y_3>y_4&&y_3>Max_Y)
Max_Y=y_3;
else if(y_4>y_2&&y_4>y_1&&y_4>y_3&&y_4>Max_Y)
Max_Y=y_4;
/*
///注意这里!!!是取极大值还是极小值需要考虑清楚,因为这个函数是周期函数,评估值会有正负!
这个程序主要是想做极大值,所以就把小于0的评估值设置为0;
*/
total_G=y_1+y_2+y_3+y_4;
if(total_G==0)break;
G_1=y_1/total_G;
G_2=y_2/total_G;
G_3=y_3/total_G;
G_4=y_4/total_G;
//cout<<"分布:"<<G_1<<" "<<G_2<<" "<<G_3<<" "<<G_4<<" "<<endl;
///计算适应度
for(i=0;i<4;i++){
T_1=rand()%1000*0.001;
// cout<<"随机值 :"<<T_1<<endl;
if(T_1>=0&&T_1<G_1)q++;
else if(T_1>G_1&&T_1<(G_2+G_1))w++;
else if(T_1>G_2&&T_1<(G_2+G_1+G_3))e++;
else if(T_1>G_3&&T_1<(G_2+G_1+G_3+G_4))r++;
}
///选择适应度高的生物
//cout<<" 评估值 : "<<y_1<<" "<<y_2<<" "<<y_3<<" "<<y_4<<" 最大值:"<<Max_Y<<endl;
//cout<<" 选择次数: "<<q<<" "<<w<<" "<<e<<" "<<r<<endl;
//cout<<"清空开始"<<endl;
while(a.size()!=0)a.pop();//清空栈
// cout<<"清空OVER"<<endl;
//**选择进化**//
// cout<<"选择进化开始"<<endl;
for(i=0;i<q;i++){
b.push(S_1);
}
for(i=0;i<w;i++){
b.push(S_2);
}
for(i=0;i<e;i++){
b.push(S_3);
}
for(i=0;i<r;i++){
b.push(S_4);
}
// cout<<"选择进化over"<<endl;
//cout<<"清空开始,size为:"<<b.size()<<endl;
S_1=b.top();b.pop();
S_2=b.top();b.pop();
S_3=b.top();b.pop();
S_4=b.top();b.pop();
//cout<<"清空OVER"<<endl;
_swap(S_1,S_2);
_swap(S_2,S_3);
//cout<<bin(S_1)<<" "<<bin(S_2)<<" "<<bin(S_3)<<" "<<bin(S_4)<<endl;
// cout<<"联会之后:"<<endl<<S_1<<endl<<S_2<<endl<<S_3<<endl<<S_4<<endl;
///变异
variation(S_1);
variation(S_2);
variation(S_3);
variation(S_4);
// cout<<"变异之后:"<<endl<<S_1<<endl<<S_2<<endl<<S_3<<endl<<S_4<<endl;
a.push(S_1);
a.push(S_2);
a.push(S_3);
a.push(S_4);
ij++;//初始化计数器
q=0;
w=0;
e=0;
r=0;
}
cout<<"最大值:"<<Max_Y<<endl;
return 0;
}