【人工智能】遗传算法求解振荡不收敛函数在区间内的最值

/*
this code was first initiated by tuzhuo,cs1503,COI,HZAU
contact email:[email protected]
personal website:wnm1503303791.github.io
personal blogs:www.cnblogs.com/acm-icpcer/
Copyright 2018/4/22 TZ.
All Rights Reserved.
*/

//mission:求函数f(x)=x*sin(10*pi*x)+2在[1,2]上能取到的最大值 
#include<cstdio>  
#include<cstring>  
#include<algorithm>  
#include<iostream>  
#include<string>  
#include<vector>  
#include<stack>  
#include<bitset>  
#include<cstdlib>  
#include<cmath>  
#include<set>  
#include<list>  
#include<deque>  
#include<map>  
#include<queue>  
#include<ctime>
using namespace std;

const double PI=3.14/*15926535897932384626*/;

class point
{
private:
    double x,y;
public:
    char d_a[21];//digital x
    point()
    {
        d_a[20]='\0';
    }
    double getx()
    {
        return x;
    }
    double setx(double mx)
    {
        x=mx;
    }
    double gety()
    {
        return y;
    }
    double sety(double my)//not being used
    {
        y=my;
    }
    bool renew_x()//renew x accroding to d_a
    {
        double x1=1;
        for(int i=2;i<20;i++)
        {
            if(d_a[i]=='1')
            {
                x1+=pow(2,-(i-1));
            }
            else continue;
        }
        x=x1;
        return true;
    }
    bool renew_y()//renew y accroding to x
    {
        y=x*sin(10*PI*x)+2;
        return true;
    }
    bool renew_d_a()//renew d_a accroding to x
    {
        double a=x-1;
        d_a[0]='1';
        d_a[1]='.';
        for(int i=2;i<20;i++)
        {
            a=a*2;
            if(a>=1)
            {
                d_a[i]='1';
                a-=1;
            }
            else    d_a[i]='0';
        }
        return true;
    }
};

bool y_sort(point p[])
{
    for(int i=0;i<100;i++)
    {
        double max=p[i].gety();
        int key=i;
        for(int j=i+1;j<100;j++)
        {
            if(p[j].gety()>max)
            {
                max=p[j].gety();
                key=j;
            }
        }
        point temp=p[i];
        p[i]=p[key];
        p[key]=temp;
    }
    
    return true;
}
//令fitness函数排名前40的个体的基因型两两交叉 ,并取代后20名,以此实现进化 
bool crossgene(point p[])
{
    point new_general[20];
    int t=0;
    
    //j=0,2,4,...,,38
    for(int i=0;i<20;i++)
    {
        new_general[i]=p[t];
        t+=2;
    }
    
    t=1;//reuse the 't' variable
    for(int i=0;i<20;i++)
    {
        //多点随机交叉5次 
        for(int j=0;j<5;j++)
        {
            srand((unsigned)time(NULL));
            int position=rand()%20;
            if(position>=2)//从字符串第三列开始交叉 
            {
                new_general[i].d_a[position]=p[t].d_a[position];
            }
        }
        t+=2;//j=1,3,5,...,39
    } 
    
    for(int i=0;i<20;i++)
    {
        new_general[i].renew_x();
        new_general[i].renew_y();
        p[i+80]=new_general[i];
    }
    
    /*
    cout<<"inner testing"<<endl;
    y_sort(p);
    for(int i=0;i<100;i++)
    {
        cout<<p[i].gety()<<endl;
    }
    */
    return true;
}

//模拟变异过程,以防止局部最优 
bool variation(point p[])
{
    
}

int main()
{
    point pset[100];
    for(int i=0;i<100;i++)
    {
        pset[i].setx(1+0.01*i);
        pset[i].renew_y();
        pset[i].renew_d_a();
        //cout<<pset[i].d_a<<endl;
    }
    
    //present the situation before sorting
    /*
    for(int i=0;i<100;i++)
    {
        cout<<p[i].gety()<<endl;
    }
    */
    
    y_sort(pset);
    //following code used to present the result after sorting
    cout<<"break testing:"<<endl;
    for(int i=0;i<100;i++)
    {
        cout<<pset[i].gety()<<endl;
    }
    cout<<pset[0].getx()<<endl;
    
    //由于不便找合适的终止条件,故直接令其循环1000代以求结果 
    for(int i=0;i<1000;i++)
    {
        crossgene(pset);
        y_sort(pset);
    } 
    
    cout<<"finall result"<<endl;
    for(int i=0;i<100;i++)
    {
        cout<<pset[i].gety()<<endl;
    }
    
    cout<<"the maxium is:"<<pset[0].gety()<<endl;
    
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/acm-icpcer/p/8932874.html
今日推荐