桐城网

 找回密码
 我要注册

QQ登录

只需一步,快速开始

查看: 3566|回复: 3

[互助] 遗传算法matlab 和 c++版

[复制链接]

23

主题

399

回帖

645

积分

桐网贡生

Rank: 3Rank: 3

积分
645
QQ
鲜花(0) 鸡蛋(0)
发表于 2010-10-9 18:51:43 | 显示全部楼层 |阅读模式
用遗传算法求f=sin(x)sin(y)/x*y的最大值,x、y在-10到10之间

#include<iostream.h>
#include<stdlib.h>
#include<fstream.h>
#include<math.h>
#include<time.h>
//********************************************************//

# define Size 50                        //种群数量
# define Iter 100                        //迭代次数
# define Bitlen 16                        //二进制位数
# define Nc 28                                //交换的个数
# define Nm 10                                //变异的个数
# define Bm 4                                //变异的位数统一为4
# define Max 10
# define Min  -10
//********************************************************//
int Pop[Iter][Size][2*Bitlen];
double X[Size],Y[Size],F[Size],F_sum[Size],Fitness[Size];//x,y及适应值                                                       
double MaxF;                                //记录所有代中的最大值
int iMax;                                        //最大值的下标

struct Geninfo                                //记录每一代的最优基因
{
        int generi;
        double BestX,BestY;
        double MaxF;
        int BestGener[2*Bitlen];
}Info[Iter];


//*******************************************************//函数声明
void InitialGroup();       
void Uncoding(int);               
void Calu(int);
void Select(int);
void Cross(int);
void Mutation(int);       
void BestOfAll(int);
void Output();

//**********************************************************主函数
int  main()
{
        int gener=0;
        InitialGroup();       
        cout<<"Iteration is starting."<<"\n";
        cout<<"数据保存在'data.txt'中!"<<endl;
        while(gener<=Iter)
        {       
                Uncoding(gener);
                Calu(gener);
                Select(gener);
                Cross(gener);
                Mutation(gener);
                BestOfAll(gener);
                gener++;
        }
        Output();
    return 0;
}

//********************************************************//初始生成种群
void InitialGroup()
{       
        srand(time(NULL));
        for(int i=0;i<Size;i++)
          for(int j=0;j<2*Bitlen;j++)
                         Pop[0][i][j]=rand()%2;
}

//********************************************************////对基因序列进行解码                                                                                                                               
void Uncoding(int gener)
{
        int i;
        for(i=0;i<Size;i++)
        {
                X[i]=0;
                for(int j=0;j<Bitlen;j++)
                        X[i]+=pow(2,j)*Pop[gener][i][Bitlen-j-1];
                X[i]=Min+(Max-Min)*X[i]/(pow(2,Bitlen)-1);
        }
       
        for(i=0;i<Size;i++)
        {
                Y[i]=0;
                for(int j=0;j<Bitlen;j++)
                        Y[i]+=pow(2,j)*Pop[gener][i][2*Bitlen-j-1];
                Y[i]=Min+(Max-Min)*Y[i]/(pow(2,Bitlen)-1);
        }
}

//********************************************************//计算适应值
void Calu(int gener)
{

        double temp=0;
        int Imax=0;
        for(int i=0;i<Size;i++)
        {
                F[i]=(sin(X[i])*sin(Y[i]))/(X[i]*Y[i]);
                if(F[i]<0)  F[i]=0;
                if(F[i]>temp)
                { temp=F[i];Imax=i;}
        }
        for(i=0;i<2*Bitlen;i++)
                Info[gener].BestGener[i]=Pop[gener][Imax][i];
        Info[gener].generi=gener;
        Info[gener].MaxF=temp;
        Info[gener].BestX=X[Imax];
        Info[gener].BestY=Y[Imax];
}


//********************************************************适应度选择,赌轮盘法
void Select(int gener)
{
       
        int i,j,k;
        int select;
        for(i=0;i<Size;i++)
        {
                if(i==0)  F_sum[i]=F[i];
                else        F_sum[i]=F_sum[i-1]+F[i];
        }
        for(i=0;i<Size;i++)
                Fitness[i]=F[i]/F_sum[Size-1];

        double randnum;
        for(i=0;i<Size;i++)
        {
                srand(rand());
                select=0;
                randnum=(double)rand()/RAND_MAX;                                  
                double psum=0;
                while(randnum>psum)
                {
                        psum=psum+Fitness[select];
                        select++;
                }
                for(j=0;j<2*Bitlen;j++)
                        Pop[gener+1][i][j]=Pop[gener][select-1][j];   
        }
       
        //****************************************保护最优个体
        int a[5];
        for(i=0;i<5;i++)
                a[i]=rand()%Size;
        for(j=0;j<5;j++)
                for(k=0;k<2*Bitlen;k++)
                        Pop[gener+1][a[j]][k]=Info[gener].BestGener[k];
                               
}


//********************************************************
void swap(int * a,int *b)
{
        int p;
        p=*a;*a=*b;*b=p;
}
//********************************************************


//********************************************************//交叉运算
void Cross(int gener)
{
        int i,C[Size],P[Bitlen];
        int j=0;
        srand(rand());
        for(i=0;i<Size;i++)
                C[i]=i;
        for(i=Size-1;i>=1;--i)
                swap(&C[i], &C[rand()%i]);
//*************************产生Nc个不同的个体


//*************************产生不重复的随机位置
        for(i=0;i<Bitlen;i++)
                P[i]=i;
        for(i=Bitlen-1;i>=1;--i)
                swap(&P[i], &P[rand()%i]);
//************************
        for(i=0;i<=Nc-2;i=i+2)
                for(j=0;j<Bitlen/2;j++)
                        Pop[gener+1][C[i]][P[j]]=Pop[gener+1][C[i+1]][P[j]];

//*************************产生不重复的随机位置
        for(i=Bitlen;i<2*Bitlen;i++)
                P[i]=i;
        for(i=2*Bitlen-1;i>=1+Bitlen;--i)
                swap(&P[i], &P[rand()%i]);
//**************************
        for(i=0;i<=Nc-2;i=i+2)
                for(j=0;j<Bitlen/2;j++)
                        Pop[gener+1][C[i]][P[j]]=Pop[gener+1][C[i+1]][P[j]];

}



//********************************************************//变异
void Mutation(int gener)
{
        int i,k,M[Size],P[2*Bitlen];
        srand(rand());

        for(i=0;i<Size;i++)
                M[i]=i;
        for(i=Size-1;i>=1;--i)
                swap(&M[i], &M[rand()%i]);                                //产生随机变异个体
        //********************************************************
        for(i=0;i<2*Bitlen;i++)
                P[i]=i;
        for(i=2*Bitlen-1;i>=1;--i)
                swap(&P[i], &P[rand()%i]);                                //产生变异位置

        for(i=0;i<Nc;i++)
        {       
                for(k=0;k<Bm;k++)
                {
                if(Pop[gener+1][M[i]][P[k]]==0 ) Pop[gener+1][M[i]][P[k]]=1;
                        else Pop[gener+1][M[i]][P[k]]=0;
                }
        }  
}



//**************************************************寻找所有代中的最优个体  
void BestOfAll(int gener)
{
        MaxF=0;
        iMax=0;
        for(int i=0;i<gener;i++)
                if(Info[i].MaxF>=MaxF) {MaxF=Info[i].MaxF;iMax=i;}
}

//**************************************************将每一代的信息输入到txt中
void Output()
{
    ofstream outfile("data.txt");
        outfile<<Iter<<"代中最优值为:"<<MaxF<<" ";
        outfile<<"\t"<<"x="<<Info[iMax-1].BestX<<" \t"<<"y="<<Info[iMax-1].BestY<<endl;
        outfile<<"***************************************************************"<<endl;
       
        for(int i=0;i<Iter;i++)
        {
                outfile<<"第"<<Info[i].generi<<"代的"<<"最优值为"<<Info[i].MaxF<<" ";
                outfile<<" "<<"\t"<<"x="<<Info[i].BestX<<" \t"<<"y="<<Info[i].BestY;       
                outfile<<endl;
        }
}


clear all;
close all;
Size=50;    %种群个数
Iter=100;     %代数
Bitlen=18;   %二进制串位数
Nc=40;      %交换个体数
Nm=15;       %变异个体数
max=10;
min=-10;   %个体取值范围
%随机生成种群
P=round(rand(Size,2*Bitlen));


%进化开始
for k=1:Iter %迭代步数
    time(k)=k;
    for j=1:Size %生成50组 x和y,即所有的个体组成的种群
        M=P(j,:);   %生成个体,即取P的每一行
        x1=0;y1=0;
        %计算 x
        for i=1:Bitlen
            x1=x1+M(i)*2^(Bitlen-i); %计算前Bitlen列变成十进制数
        end
        x=(max-min)*x1/(2^Bitlen-1)+min;
        %计算y
        for i=1:Bitlen
            y1=y1+M(Bitlen+i)*2^(Bitlen-i);%计算后Bitlen列变成十进制数
        end
        y=(max-min)*y1/(2^Bitlen-1)+min;
     
        %计算适应值,并寻找当代最优个体及最优适应值
        F(j)=0.9*exp(-((x+5)^2+(y+5)^2)/10)+0.99996*exp(-((x-5)^2+(y-5)^2)/20);
        %F(j)=sin(x)*sin(y)/(x*y);
        if j==1
                 BestF(k)=F(j);  
                 BestX(k)=x;
                 BestY(k)=y;
                 BestM=M;  
        else
               if F(j)>BestF(k)
                    BestF(k)=F(j);
                    BestX(k)=x;
                    BestY(k)=y;
                    BestM=M;
               end
        end
    end
   
    %计算所有个体的适应值之和
    sum=0;
    for i=1:Size
        sum=sum+F(i);
    end
   %计算个体的适应度
   for i=1:Size
       Fitness(i)=F(i)/sum;
   end
   
        
   
    %选择,赌轮盘算法,每次产生一个选择因子bet
     for j=1:1:Size
         bet=rand(1); %产生随机因子
         psum=0;select=1;
            while(psum<bet)
                psum=psum+Fitness(select);
                select=select+1;
            end
            tempP(i,:)=P(i,:);   
     end
     
           
   
    %保护最优个体
    tempP2=randint(1,5,[1,Size]); % 随机产生5个位置
    for i=1:5
        tempP(tempP2(i),:)=BestM;
    end

    %交叉
    C=randint(1,Nc,[1,Size]); %随机选择交换个体
    for i=1:2:(Nc-1)   
        p=randint(1,1,[1,2*Bitlen-Bitlen/2]);%从1-Bitlen中产生一个交叉点
            temp=tempP(C(i),p:p+Bitlen/2);
            tempP(C(i),p:p+Bitlen/2)=tempP(C(i+1),p:p+Bitlen/2);
            tempP(C(i+1),p:p+Bitlen/2)=temp;
    end


    %变异
    M=randint(1,Nm,[1,Size]);%随机选择变异个体
    for i=1:Nm
        P=randint(1,4,[1,2*Bitlen]);%产生4个变异位置
        for j=1:4
            if(tempP(M(i),P(j))==0)
                tempP(M(i),P(j))=1;
            else tempP(M(i),P(j))=0;
            end
        end
    end
   
P=tempP;
disp(['迭代第' num2str(k) '步的最优值'])
[BestX(k) BestY(k) BestF(k)]
end
figure(1);
plot(time,BestF);
xlabel('Times');ylabel('BestF');
figure(2);
plot(time,BestX);
xlabel('times');ylabel('BestX');
figure(3);
plot(time,BestY);
xlabel('time');ylabel('BestY')


        

   

               
               
   





叶子是不会飞翔的翅膀

23

主题

399

回帖

645

积分

桐网贡生

Rank: 3Rank: 3

积分
645
QQ
鲜花(0) 鸡蛋(0)
 楼主| 发表于 2010-10-9 19:39:26 | 显示全部楼层
怎么会有表情的。。。。呵呵
叶子是不会飞翔的翅膀

23

主题

399

回帖

645

积分

桐网贡生

Rank: 3Rank: 3

积分
645
QQ
鲜花(0) 鸡蛋(0)
 楼主| 发表于 2010-10-9 19:39:27 | 显示全部楼层
怎么会有表情的。。。。呵呵
叶子是不会飞翔的翅膀

49

主题

990

回帖

3517

积分

桐网举人

Rank: 4

积分
3517
QQ
鲜花(0) 鸡蛋(0)
发表于 2010-10-10 16:27:37 | 显示全部楼层
放这些C的程序在论坛有什么用呢:lol
裕华机电:承接自动化编程,安装,调试.配电柜制作。
您需要登录后才可以回帖 登录 | 我要注册

本版积分规则

快速回复 返回顶部 返回列表