ilikenba 发表于 2005-1-31 12:29

[分享]遗传算法(C++)

<DIV class=HtmlCode>
<P>// Genetic.cpp: implementation of the CGenetic class.
//
//////////////////////////////////////////////////////////////////////</P>
<P>#include "stdafx.h"</P>
<P>#include "Genetic.h"
#include"math.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
/////张纯禹  2001年   <a href="mailtchunyu79@hotmail.com" target="_blank" >chunyu79@hotmail.com</A>
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////</P>
<P>CGenetic::CGenetic()
{pmutation=0.01;//变异概率
pcross=0.9;//交叉概率
maxgen=5000;//最大进化代数
iVarNo=0;//染色体数目
sumfitness=0.0;
gen=0;
IsSetScope=false;//还未设定个变量范围
IsStoped=false;
for(int i=0;i&lt;MAXBESTNUM;i++)
   bestchrom.fitness=0;
iBestNum=0;
dblCre=0.0;
dblDifference=0.15;
best.fitness=0.0;

initM(MATCOM_VERSION);
}</P>
<P>CGenetic::~CGenetic()
{exitM();
}</P>
<P>int CGenetic::rselect()
{double rand1,partsum;
int j=0;
partsum=0;
rand1=rand()*sumfitness;
do{
  partsum=partsum+newpop.fitness;
  j++;
}while((partsum&lt;rand1)&amp;&amp;(j&lt;POPSIZE));
return (j-1);
}</P>
<P>void CGenetic::generation()
{int i,r1,r2;
CHROM tempChrom;
//进行统计,计算newpop单个染色体的适应度,选出最优染色体
statistic(newpop);
//从1到POPSIZE循环,根据适应度选择,进行交叉,组成oldpop
    for(i=0;i&lt;POPSIZE;i+=2){
  r1=rselect();
  r2=rselect();
  cross(newpop,newpop,i);
}</P>
<P> // oldpop,newpop进行调换
for(i=0;i&lt;POPSIZE;i++){
  tempChrom=newpop;
  newpop=oldpop;
  oldpop=tempChrom;
}
//从1到POPSIZE循环,对newpop进行变异
    for(i=0;i&lt;POPSIZE;i++)
     mutation(&amp;newpop);
}</P>
<P>bool CGenetic::begin()
{MSG msg;
mData=zeros(1,bpnet-&gt;iInput);
mResult=zeros(1,bpnet-&gt;iOutput);
for(int i=gen;i&lt;maxgen;i++)
{if(IsStoped)
  break;
if(bpnet-&gt;iOutput&gt;1){
::MessageBox(NULL,"目前只支持一个输出量!","错误",MB_OK);
return(false);
}
if(gen==0)
  init();//如果刚开始运算,初始化
generation();
gen++;
//防止假死机
::PeekMessage(&amp;msg,NULL,0,0,PM_REMOVE);
::DispatchMessage(&amp;msg);
msg.message=-1;
::DispatchMessage(&amp;msg);//这样可以消除屏闪
}</P>
<P>return(true);
}</P>
<P>
void CGenetic::cross(CHROM chrom1, CHROM chrom2, int iPlace)
{double c;
int i=0;
//以交叉概率进行交叉,并对交叉后的新染色体进行判别
//循环,直到产生合法的新染色体
do{if(flip(pcross)){//交叉概率
c=rand();
    for(i=0;i&lt;iVarNo;i++){
oldpop.chrom=c*chrom1.chrom+(1-c)*chrom2.chrom;
oldpop.chrom=(1-c)*chrom1.chrom+c*chrom2.chrom;
}
}
else//直接赋值,不再交叉
{oldpop=chrom1;
  oldpop=chrom2;
}
}while(!identify(oldpop)||!identify(oldpop));</P>
<P>}</P>
<P>bool CGenetic::flip(double possibility)
{double ppp;
ppp=rand();
if(ppp&lt;=possibility)
return (true);
else
return (false);
}</P>
<P>void CGenetic::mutation(CHROM *chrome)
{double m=10;
int i=0;
CHROM temp1,temp2;
if(flip(pmutation)){ //以变异概率进行变异
  do{ for(i=0;i&lt;iVarNo;i++)
     temp2.chrom=chrome-&gt;chrom;
         for(i=0;i&lt;iVarNo;i++)
    temp1.chrom=randxy(varminmax-varminmax,varminmax-varminmax)/10;
          for(i=0;i&lt;iVarNo;i++)
     temp2.chrom+=m*temp1.chrom;
    if(!identify(temp2))
     m=(double)m/(double)(2.0);
  }while(!identify(temp2));
}
else{
  for(i=0;i&lt;iVarNo;i++)
     temp2.chrom=chrome-&gt;chrom;
}
for(i=0;i&lt;iVarNo;i++)
  chrome-&gt;chrom=temp2.chrom;
}</P>
<P>void CGenetic::statistic(CHROM pop[])
{int i;
sumfitness=0;
//循环,计算单个染色体的适应度,以及sumfitness
for(i=0;i&lt;POPSIZE;i++){
   pop.fitness=CalFitness(pop);
   sumfitness+=pop.fitness;}
//选出符合条件的染色体
for(i=0;i&lt;POPSIZE;i++){
if(pop.fitness&gt;=dblCre&amp;&amp;IsNew(pop))
  bestchrom=pop;
if(pop.fitness&gt;best.fitness)
  best=pop;//纪录最佳染色体
}</P>
<P>}</P>
<P>void CGenetic::init()
{//对种群进行随机初始化
int i,j;
srand( (unsigned)time( NULL ) );</P>
<P>if(iVarNo!=0&amp;&amp;IsSetScope)
{for(i=0;i&lt;POPSIZE;i++){
for(j=0;j&lt;iVarNo;j++){//在最值间随机赋值
  newpop.chrom=randxy(varminmax,varminmax);
        oldpop.chrom=newpop.chrom;
}
}
}
else
{if(iVarNo==0)::MessageBox(NULL,"变量数不能为0!","错误...",MB_OK);
  else if(!IsSetScope) ::MessageBox(NULL,"还未设置变量范围","错误...",MB_OK);
}
}</P>

<P>double CGenetic::randxy(double x, double y)
{ return (x+(y-x)*rand());</P>
<P>}</P>
<P>void CGenetic::setscope(double scope, int iNo)
{int i;
for(i=0;i&lt;iNo;i++)
{varminmax=scope;//最小值
varminmax=scope;//最大值
}
IsSetScope=true; </P>
<P>}</P>
<P>double CGenetic::CalFitness(CHROM chrome)
{ double dblResult;
int i;
for(i=0;i&lt;iVarNo;i++)
  mData.r(i+1)=chrome.chrom;
mResult=bpnet-&gt;simulate(mData);
dblResult=mResult.r(1);
return(dblResult);
}</P>

<P>bool CGenetic::identify(CHROM chrome)
{int i=0;
bool IsOk=true;;
for(i=0;i&lt;iVarNo;i++){
  if(chrome.chrom&gt;varminmax||chrome.chrom&lt;varminmax)
  {IsOk=false;
  break;}
}
return (IsOk);
}</P>

<P>double CGenetic::difference(CHROM ch1, CHROM ch2)
{double differ,temp1=0.0,temp2=0.0,temp3=0.0,dblTemp1,dblTemp2;
int i;
for(i=0;i&lt;iVarNo;i++){
  dblTemp1=ch1.chrom/(varminmax-varminmax);
  dblTemp2=ch2.chrom/(varminmax-varminmax);
  temp1=temp1+fabs(dblTemp1-dblTemp2)*fabs(dblTemp1-dblTemp2);
     temp2+=dblTemp1*dblTemp1;
  temp3+=dblTemp2*dblTemp2;
}
temp2=(temp2&gt;temp3)?temp2:temp3;//取较大者
differ=sqrt(temp1)/sqrt(temp2);
return (differ);
}</P>
<P>bool CGenetic::IsNew(CHROM ch)
{int i;
bool IsDifferent;
IsDifferent=true;
for(i=0;i&lt;iBestNum;i++)
  if((difference(ch,bestchrom)&lt;dblDifference)&amp;&amp;(angle(ch,bestchrom)&lt;dblAngle))
  {IsDifferent=false;
      break;
  }
return (IsDifferent);</P>
<P>}</P>
<P>double CGenetic::angle(CHROM ch1, CHROM ch2)
{double pi,temp1=0.0,temp2=0.0,temp3=0.0,dblCos=0.0,angle;
int i=0;
double dblTemp1,dblTemp2;
for(i=0;i&lt;iVarNo;i++)
{dblTemp1=ch1.chrom/(varminmax-varminmax);
  dblTemp2=ch2.chrom/(varminmax-varminmax);
  temp1+=dblTemp1*dblTemp2;
  temp2+=dblTemp1*dblTemp1;
  temp3+=dblTemp2*dblTemp2;
}
temp2=sqrt(temp2);
temp3=sqrt(temp3);
dblCos=temp1/(temp2*temp3);
pi=acos(-1.0);
angle=acos(dblCos);
angle=(angle/pi)*180.0;//转化为角度
return (angle);</P>
<P>}</P></DIV>
<DIV class=HtmlCode>
<P>// Genetic.h: interface for the CGenetic class.
//
//////////////////////////////////////////////////////////////////////</P>
<P>#if !defined(AFX_GENETIC_H__72C36058_C073_487F_BD99_D8BD4A59EFF0__INCLUDED_)
#define AFX_GENETIC_H__72C36058_C073_487F_BD99_D8BD4A59EFF0__INCLUDED_</P>
<P>#if _MSC_VER &gt; 1000
#pragma once
#endif // _MSC_VER &gt; 1000
#include"definition.h"
typedef struct mychrom{
double chrom;
double fitness;//适应度
}CHROM;
#include "BpNet.h"
////////张纯禹 2001年   <a href="mailtchunyu79@hotmail.com" target="_blank" >chunyu79@hotmail.com</A>
class CGenetic  
{
public:
bool IsStoped;
double dblAngle;
CHROM best;
Mm mData,mResult;
double dblDifference;//差异〉改值的染色体视为不同
double dblCre;//适应度&gt;改值的染色体符合条件
int iBestNum;//符合条件的染色体数目
CBpNet * bpnet;
//double (* obj_fun)();
double CalFitness(CHROM chrome);//计算适应度函数
long gen;//当前进化代数
void setscope(double scope,int iNo);//设置染色体取值范围
double randxy(double x,double y);//产生x,y之间的随机数
void statistic(CHROM pop[]);
CHROM bestchrom;//最优染色体
bool begin();//主函数
void generation();//一次进化
int rselect();//轮盘赌选择
CHROM newpop;//种群
CHROM oldpop;//种群
double pmutation;//变异概率
double pcross;//交叉概率
long maxgen;//最大进化代数
int iVarNo;//染色体数目
double sumfitness;
CGenetic();
virtual ~CGenetic();</P>
<P>private:
double angle(CHROM ch1,CHROM ch2);
bool IsNew(CHROM ch);//判断是否为符合条件的新染色体
double difference(CHROM ch1,CHROM ch2);//量个染色体之间的差异,用以区别</P>
<P> bool identify(CHROM chrome);//验证是否为合法的染色体
double varminmax;
void init();//初始化,设置初始染色体
void mutation(CHROM *chrome);//对新染色体进行变异
bool flip(double possibility);//测试
//交叉操作,iPlace指明新染色体位置
void cross(CHROM chrom1,CHROM chrom2,int iPlace);
bool IsSetScope;

};</P>
<P>#endif // !defined(AFX_GENETIC_H__72C36058_C073_487F_BD99_D8BD4A59EFF0__INCLUDED_)

</P></DIV>

bogolyx 发表于 2005-3-21 11:26

细细,谢谢了,请问有神经网络的vc++程序码?

edewo 发表于 2005-3-29 22:30

你好,你发的程序我也看了,不过请问一下在Genetic.h头文件中,头文件definition.h和变量MAXVARNO在哪里可以找到,多谢了,你用这个类了吗,效果怎么样

hawkltl 发表于 2005-4-28 11:05

<P>能不能发份你的这部分程序给我啊?(包含Genetic.h头文件)</P><P>谢谢!</P><P><a href="mailthawkltl@eyou.com" target="_blank" >hawkltl@eyou.com</A></P><P>QQ:297478832</P>

canglang 发表于 2005-5-2 09:10

不错,支持

yiping_fly 发表于 2005-5-28 15:39

<P>有量子遗传算法解背包问题的程序么,谢谢斑竹</P>
<P>QQ 20409589 EMAIL yiping8241@sohu.com</P>

txj66 发表于 2005-9-13 13:13

好啊啊

<P>好啊啊</P>

luotianj 发表于 2005-9-23 23:06

<P>谢谢</P>

john.liu 发表于 2005-11-6 11:11

<P>good</P>

bluewisher 发表于 2005-11-11 00:35

<P>还不会用</P>
页: [1] 2 3 4 5
查看完整版本: [分享]遗传算法(C++)