遗传算法

遗传算法思路比较清晰,按照步骤按部就班即可。不过它的适应性很强,想让它适应不同的任务要针对任务的特点对算法初始化、编码、评价函数等各个方面进行相应的调节。
算法流程图

//遗传算法
//可以通过改变group_number,group_size的值改变种群的大小和数目
//可以通过修改函数Encode()修改编码方式
//可以通过修改EvalFun()修改评价函数
//该算法可拓展性强,编码、选择、交叉、变异、评价等方式均可以方便地修改
//本算法包含了测验的五个函数,可根据需要测试其他的函数
//1.F(x)=sin(x1)+sin(x2)
//2.F(x)=cos(x1)+sin(x1)
//3.F(x)=x1*x1+x2*x2
//4.F(x)=1/(x1*x1+x2*x2+1)
//5.F(x)=(x1-x2)^2+(x1+x2)^2
#include<iostream>
#include<ctime>
#include<iomanip>
#include <algorithm>
#include <cmath>
using namespace std;
const int group_number=3;                    //种群数目
const int group_size=2;                      //每个种群的规模
const float cross_probality=0.88;          //交叉概率
const float vari_probality=0.1;            //变异概率
float float_code[group_number][group_size]; //每个个体的编码,浮点数
float fitness[group_number];                //每个种群的适应值
float best_result=0;                        //当前最佳
double Encode()      //自变量范围
{
    return ((-5000+rand()%100000)*0.0001);
}
void EvalFun()//函数1
{


    for(int i=0;i<group_number;i++)
    {
        float sum=0;
        for(int j=0;j<group_size;j++) //目标函数,也即评价函数
                sum+=sin(float_code[i][j]);
    fitness[i]=sum;
    cout<<"finess"<<i<<":"<<fitness[i]<<" ";
    }
    cout<<endl;
}
/*void EvalFun() //函数2
{


    for(int i=0;i<group_number;i++)
    {
        float sum=0;
        for(int j=0;j<group_size-1;j++) //目标函数,也即评价函数
                sum+=sin(float_code[i][j])+cos(float_code[i][j]);
    fitness[i]=sum;
    cout<<"finess"<<i<<":"<<fitness[i]<<" ";
    }
    cout<<endl;
}
void EvalFun()  //函数3
{


    for(int i=0;i<group_number;i++)
    {
        float sum=0;
        for(int j=0;j<group_size;j++) //目标函数,也即评价函数
                sum+=float_code[i][j]*float_code[i][j];

    fitness[i]=sum;
    cout<<"finess"<<i<<":"<<fitness[i]<<" ";
    }
    cout<<endl;
}
void EvalFun()//函数4
{


    for(int i=0;i<group_number;i++)
    {
        float sum=0;
        for(int j=0;j<group_size;j++) //目标函数,也即评价函数
                sum+=float_code[i][j]*float_code[i][j];

    fitness[i]=1/(1+sum);
    cout<<"finess"<<i<<":"<<fitness[i]<<" ";
    }
    cout<<endl;
}
void EvalFun()//函数5
{


    for(int i=0;i<group_number;i++)
    {
        float sum=0;
        for(int j=0;j<group_size-1;j++) //目标函数,也即评价函数
                sum+=(float_code[i][j]-float_code[i][j+1])*(float_code[i][j]-float_code[i][j+1])
                        +(float_code[i][j]+float_code[i][j+1])*(float_code[i][j]+float_code[i][j+1]);
    fitness[i]=sum;
    cout<<"finess"<<i<<":"<<fitness[i]<<" ";
    }
    cout<<endl;
}
*/
void Init()                                  //初始化
{
    cout<<"初始化:"<<endl;
    for(int i=0;i<group_number;i++)
    {
        cout<<"C"<<i<<" ";
        for(int j=0;j<group_size;j++)
        {
            float_code[i][j]=Encode();//个体的编码范围
            cout<<setiosflags(ios::left)<<setw(8)<<float_code[i][j]<<" ";
        }
        cout<<endl;
    }
}
void Evaluate()                     //评价函数,更新最佳
{
    float test_result;
    float result1[group_number];
    EvalFun();   //目标函数的值为评价标准
    for(int i=0;i<group_number;i++)
            result1[i]=fitness[i];
    sort(result1,result1+group_number);//排序
    test_result=result1[group_number-1];
    if(test_result>best_result)
    best_result=test_result;
    cout<<"适应值计算,当前best_result:"<<best_result<<endl;
}
void Select()                       //轮盘赌选择
{

        float sum_result=0;
        float pecentage[group_number];
        for(int i=0;i<group_number;i++)
            sum_result+=fitness[i];
        for(int i=0;i<group_number;i++)
        {
            pecentage[i]=fitness[i]/sum_result;
        }
        float a;
        float float_code1[group_number][4];
        for(int i=0;i<group_number;i++)
            for(int j=0;j<group_number;j++)
                float_code1[i][j]=float_code[i][j];
        for(int i=0;i<group_number;i++)
        {
            a=(rand()%100)*0.01;
            if(a<=pecentage[0])
                for(int j=0;j<group_size;j++)
                    float_code[i][j]=float_code1[0][j];
            if(a>pecentage[0]&&a<=(pecentage[0]+pecentage[1]))
                for(int j=0;j<group_size;j++)
                    float_code[i][j]=float_code1[1][j];
            if(a>(pecentage[0]+pecentage[1])&&a<=(pecentage[0]+pecentage[1]+pecentage[2]))
                for(int j=0;j<group_size;j++)
                    float_code[i][j]=float_code1[2][j];
            if(a>(pecentage[0]+pecentage[1]+pecentage[2])&&a<=(pecentage[0]+pecentage[1]+pecentage[2]+pecentage[3]))
                for(int j=0;j<group_size;j++)
                    float_code[i][j]=float_code1[3][j];
            if(a>(pecentage[0]+pecentage[1]+pecentage[2]+pecentage[3])&&a<=(pecentage[0]+pecentage[1]+pecentage[2]+pecentage[3]+pecentage[4]))
                for(int j=0;j<group_size;j++)
                    float_code[i][j]=float_code1[4][j];
        }
}
void Cross()                //交配
{
    float mating[group_number];
        int num;
        float tend[group_size]={0};
        for(int i=0;i<group_number;i++)
        {
            mating[i]=(rand()%100)*0.01;
        }

        for(int i=0;i<group_number;i++)
        {
            if(mating[i]<=0.88)
            {
                for(int k=i+1;k<group_number;k++)
                {
                    if(mating[k]<=cross_probality&&float_code[i][0]!=float_code[k][0])
                    {
                        num=rand()%3;
                        for(int l=num+1;l<group_size;l++)
                            tend[l]=float_code[i][l];
                        for(int m=num+1;m<group_size;m++)
                        {
                            float_code[i][m]=float_code[k][m];
                            float_code[k][m]=tend[m];
                        }
                    }
                    mating[k]=1;
                    break;
                }
            }
        }
}
void Variation()                //变异
{
    float variation[group_number][group_size];
        for(int i=0;i<group_number;i++)
        {
            for(int j=0;j<group_size;j++)
                variation[i][j]=(rand()%100)*0.01;
        }
        for(int i=0;i<group_number;i++)
            for(int j=0;j<group_size;j++)
                if(variation[i][j]<vari_probality)
                    float_code[i][j]=Encode();
        cout<<"新群体:"<<endl;
        for(int i=0;i<group_number;i++)
        {
            cout<<"C"<<i<<" ";
            for(int j=0;j<group_size;j++)
                cout<<setiosflags(ios::left)<<setw(8)<<float_code[i][j]<<" ";
            cout<<endl;
        }
}
int main()
{
    srand(time(0));
    int n;
    cout<<"请输入需要迭代的次数:";
    cin>>n;
    int test_num=1;
    Init();
    Evaluate();
    while(test_num<=n)
    {
        int inc=0;
        cout<<"第"<<test_num<<"次迭代:"<<endl;
        Select();
        Cross();
        Variation();
        Evaluate();
        test_num++;
        if(test_num>n)
        {
            cout<<"继续迭代?n>0 for 增加的迭代次数,0 for NO. ";
            cin>>inc;
            if(inc==0);
            else n+=inc;
        }
    }
    system("pause");
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值