遗传算法

写的遗传算法,参考的是这篇文章<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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值