这是我在解决电梯动力学参数写的简单遗传算法(程序带目标函数值、适应度值计算,但是我的适应度函数因为目标函数的计算很特殊,一起放在了程序外面计算,在此不提供)。 头文件:
// CMVSOGA.h : main header file for the CMVSOGA.cpp
// 本来想使用链表里面套链表的,程序调试比较麻烦,改为种群用链表表示
//染色体固定为16的方法。
#if !defined(AFX_CMVSOGA_H__45BECA_61EB_4A0E_9746_9A94D1CCF767__INCLUDED_)
#define
AFX_CMVSOGA_H__45BECA_61EB_4A0E_9746_9A94D1CCF767__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include "Afxtempl.h"
#define variablenum 16
class CMVSOGA
{
public:
CMVSOGA();
void selectionoperator();
void crossoveroperator();
void mutationoperator();
void initialpopulation(int, int ,double ,double,double *,double *); //种群初始化
void generatenextpopulation(); //生成下一代种群
void evaluatepopulation(); //评价个体,求最佳个体
void calculateobjectvalue(); //计算目标函数值
void calculatefitnessvalue(); //计算适应度函数值
void findbestandworstindividual(); //寻找最佳个体和最差个体
void performevolution();
void GetResult(double *);
void GetPopData(double **);
void SetValueData(double *);
void maxandexpectation();
private:
struct individual
{
double chromosome[variablenum]; //染色体编码长度应该为变量的个数 double value;
double fitness; //适应度
};
double variabletop[variablenum]; //变量值
double variablebottom[variablenum]; //变量值
int popsize; //种群大小
// int generation; //世代数
int best_index;
int worst_index;
double crossoverrate; //交叉率
double mutationrate; //变异率
int maxgeneration; //最大世代数
struct individual bestindividual; //最佳个体
struct individual worstindividual; //最差个体
struct individual current; //当前个体
struct individual current1; //当前个体
struct individual currentbest; //当前最佳个体
CList population; //种群
CList newpopulation; //新种群 CList cfitness; //存储适应度值
// double maxfitness;
// double minfitness;
// double avefitness;
//怎样使链表的数据是一个结构体????主要是想把种群作成链表。节省空间。 };
#endif
执行文件
// CMVSOGA.cpp : implementation file
//
#include "stdafx.h"
#include "CMVSOGA.h"
#include "math.h"
#include "stdlib.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
///////////////////////////////////////////////////////////////////////////// // CMVSOGA.cpp
void CMVSOGA::initialpopulation(int ps, int gen ,double cr ,double mr,double *xtop,double *xbottom) //第一步,初始化。
{
int i ,j;
popsize=ps ;
maxgeneration=gen;
crossoverrate=cr;
mutationrate =mr;
for (i=0;i
{
variabletop[i] =xtop[i];
variablebottom[i] =xbottom[i];
}
srand( (unsigned)time( NULL ) );
for(i=0;i
{
for (j=0;j
{
current.chromosome[j]=double(rand()%1000)/1000*(variabletop[j]-variablebottom[j])+variablebottom[j];
}
current.fitness=0;
current.value=0;
population.InsertAfter(population.FindIndex(i),current);//除了初始化使用insertafter外,其他的用setat命令。
}
}
void CMVSOGA::generatenextpopulation()//第三步,生成下一代。
{
selectionoperator();
crossoveroperator();
mutationoperator();
}
void CMVSOGA::evaluatepopulation() //第二步,评价个体,求最佳个体 {
// calculateobjectvalue();
calculatefitnessvalue(); //在此步中因该按适应度值进行排序.链表的排序. findbestandworstindividual();
}
void CMVSOGA:: calculateobjectvalue() //计算函数值,应该由外部函数实现。主要因为目标函数很复杂。
{
int i,j;
double x[variablenum];
for (i=0; i
{
current=population.GetAt(population.FindIndex(i));
current.value=0;
//使用外部函数进行,在此只做结果的传递。
for (j=0;j
{
x[j]=current.chromosome[j];
current.value=current.value+(j+1)*pow(x[j],4);
}
////使用外部函数进行,在此只做结果的传递。
population.SetAt(population.FindIndex(i),current);
}
}
void CMVSOGA::mutationoperator() //对于浮点数编码,变异算子的选择具有决定意义。
//需要guass正态分布函数,生成方差为sigma,均值为浮点数编码值c。 {
int i,j;
double r1,r2,p,sigma;//sigma高斯变异参数
sigma=0.5;
for (i=0;i
{
current=population.GetAt(population.FindIndex(i));
//生成均值为current.chromosome,方差为sigma的高斯分布数
srand((unsigned int) time (NULL));
for(j=0; j
{
r1 =double( rand()%1001)/1000;
r2 = double(rand()%1001)/1000;
p=double(rand()%1000)/1000;
if(p
{
//高斯变异
current.chromosome[j] = (current.chromosome[j]
+ sigma*sqrt(-2*log(r1)/0.4323)*sin(2*3.1415926*r2));
if (current.chromosome[j]>variabletop[j])
{
current.chromosome[j]=variabletop[j];
}
if (current.chromosome[j]
{
current.chromosome[j]=variablebottom [j];
}
}
}
population.SetAt(population.FindIndex(i),current);
}
void CMVSOGA::selectionoperator() //从当前个体中按概率选择新种群,应该加一个复制选择,提高种群的平均适应度
//第二次循环出错
{
int i,j,pindex=0;
double p,pc,sum=0;
i=0;
j=0;
pindex=0;
p=0;
pc=0;
sum=0.001;
newpopulation.RemoveAll();
cfitness.RemoveAll();
//链表排序
// population.SetAt (population.FindIndex(0),current); //多余代码
for (i=1;i
{
current=population.GetAt(population.FindIndex(i));
for(j=0;j
{
current1=population.GetAt(population.FindIndex(j));//临时借用变量 if(current.fitness
{
population.InsertBefore(population.FindIndex(j),current);
population.RemoveAt(population.FindIndex(i+1));
break;
}
}
// m=population.GetCount();
}
//链表排序
for(i=0;i
current=population.GetAt(population.FindIndex(i));
sum+=current.fitness;
}
for(i=0;i
{
current=population.GetAt(population.FindIndex(i));
current.fitness=current.fitness/sum;
cfitness.InsertAfter (cfitness .FindIndex(i),current.fitness);
for(i=1;i
{
current.fitness=cfitness.GetAt (cfitness.FindIndex(i-1))
+cfitness.GetAt(cfitness.FindIndex(i)); //归一化
cfitness.SetAt (cfitness .FindIndex(i),current.fitness);
population.SetAt(population.FindIndex(i),current);
}
for (i=0;i
{
p=double(rand()%1000)/1000+0.0001; //随机生成概率
pindex=0; //遍历索引
pc=cfitness.GetAt(cfitness .FindIndex(0));
while(p>=pc&&pindex
{
pc=cfitness.GetAt(cfitness .FindIndex(pindex));
pindex++;
}
//必须是从index~popsize,选择高概率的数。即大于概率p的数应该被选择,选择不满则进行下次选择。
for (j=popsize-1;j
{
newpopulation.InsertAfter (newpopulation.FindIndex(0),
population.GetAt (population.FindIndex(j)));
i++;
}
}
for(i=0;i
{
population.SetAt (population.FindIndex(i),
newpopulation.GetAt (newpopulation.FindIndex(i)));
}
// j=newpopulation.GetCount();
// j=population.GetCount();
newpopulation.RemoveAll();
}
//current 变化后,以上没有问题了。
void CMVSOGA:: crossoveroperator() //非均匀算术线性交叉,浮点数适用,alpha ,beta是(0,1)之间的随机数
//对种群中两两交叉的个体选择也是随机选择的。也可取beta=1-alpha; //current的变化会有一些改变。
int i,j;
double alpha,beta;
CList index;
int point,temp;
double p;
srand( (unsigned)time( NULL ) );
for (i=0;i
{
index.InsertAfter (index.FindIndex(i),i);
}
for (i=0;i
{
point=rand()%(popsize-1);
temp=index.GetAt(index.FindIndex(i));
index.SetAt(index.FindIndex(i),
index.GetAt(index.FindIndex(point)));
index.SetAt(index.FindIndex(point),temp);
}
for (i=0;i
{//按顺序序号,按序号选择两个母体进行交叉操作。
p=double(rand()%1000)/1000.0;
if (p
{
alpha=double(rand()%1000)/1000.0;
beta=double(rand()%1000)/1000.0;
current=population.GetAt(population.FindIndex(index.GetAt(index.FindIndex(i))));
current1=population.GetAt(population.FindIndex(index.GetAt(index.FindIndex(i+1))));//临时使用current1代替
for(j=0;j
{
//交叉
current.chromosome[j]=(1-alpha)*current.chromosome[j]+
beta*current1.chromosome[j];
if (current.chromosome[j]>variabletop[j]) //判断是否超界.
{
current.chromosome[j]=variabletop[j];
}
if (current.chromosome[j]
{
current.chromosome[j]=variablebottom [j];
}
current1.chromosome[j]=alpha*current.chromosome[j]
+(1- beta)*current1.chromosome[j];
if (current1.chromosome[j]>variabletop[j])
{
current1.chromosome[j]=variabletop[j];
}
if (current1.chromosome[j]
{
current1.chromosome[j]=variablebottom [j];
}
}
//回代
}
newpopulation.InsertAfter (newpopulation.FindIndex(i),current);
newpopulation.InsertAfter (newpopulation.FindIndex(i),current1); }
j=newpopulation.GetCount();
for (i=0;i
{
population.SetAt (population.FindIndex(i),
newpopulation.GetAt (newpopulation.FindIndex(i)));
}
newpopulation.RemoveAll();
}
void CMVSOGA:: findbestandworstindividual( )
{
int i;
bestindividual=population.GetAt(population.FindIndex(best_index)); worstindividual=population.GetAt(population.FindIndex(worst_index)); for (i=1;i
{
current=population.GetAt(population.FindIndex(i));
if (current.fitness>bestindividual.fitness)
{
bestindividual=current;
best_index=i;
}
else if (current.fitness
{
worstindividual=current;
worst_index=i;
}
}
population.SetAt(population.FindIndex(worst_index),
population.GetAt(population.FindIndex(best_index)));
//用最好的替代最差的。使用这个之后结果相差很大。不收敛。
if (maxgeneration==0)
{
currentbest=bestindividual;
}
else
{
if(bestindividual.fitness>=currentbest.fitness)
{
currentbest=bestindividual;
}
}
}
void CMVSOGA:: calculatefitnessvalue() //适应度函数值计算,关键是适应度函数的设计
//current变化,这段程序变化较大,特别是排序。
{
int i;
double temp;//alpha,beta;//适应度函数的尺度变化系数
double cmax=100;
for(i=0;i
{
current=population.GetAt(population.FindIndex(i));
if(current.value
{
temp=cmax-current.value;
}
else
{
temp=0.0;
}
/*
if((population[i].value+cmin)>0.0)
{temp=cmin+population[i].value;}
else
{temp=0.0;
}
*/
current.fitness=temp;
population.SetAt(population.FindIndex(i),current);
}
}
void CMVSOGA:: performevolution() //演示评价结果,有冗余代码,current变化,程序应该改变较大
{
if (bestindividual.fitness>currentbest.fitness)
{
currentbest=population.GetAt(population.FindIndex(best_index));
}
else
{
population.SetAt(population.FindIndex(worst_index),currentbest); }
}
void CMVSOGA::GetResult(double *Result)
{
int i;
for (i=0;i
{
Result[i]=currentbest.chromosome[i];
}
Result[i]=currentbest.value;
}
CMVSOGA::CMVSOGA()
{
best_index=0;
worst_index=0;
crossoverrate=0; //交叉率
mutationrate=0; //变异率
maxgeneration=0;
}
void CMVSOGA::GetPopData(double **PopData) //不能保证每次计算结果都对,为什么?
{
int i,j;
for (i=0;i
{
current=population.GetAt(population.FindIndex(i));
for (j=0;j
{
PopData[i][j]=current.chromosome[j];
}
}
}
void CMVSOGA::SetValueData(double *ValueData)
{
int j;
for (j=0;j
{
current=population.GetAt(population.FindIndex(j));
current.value=ValueData[j];
population.SetAt(population.FindIndex(j),current);
}
}
DLG中调用代码:
void CMVSOFGADlg::OncalNoGuass()
{
// TODO: Add your control notification handler code here
UpdateData(true);
UINT i;
UINT generation;
double topx[16], bottomx[16];
double resultx[17];
////////////////////////////////////
double ** PopData;
double *PopValue;
PopData = new double*[m_popsize];
for(i=0; i
{
PopData[i] = new double[16];
}
PopValue=new double [m_popsize];
////////////////////////////////////
//////////////初始化/////////////
CMVSOGA cdata;
m_result=0;
topx[0]=1.28;
topx[1]=1.28;
topx[2]=1.28;
topx[3]=1.28;
topx[4]=1.28;
topx[5]=1.28;
topx[6]=1.28;
topx[7]=1.28;
topx[8]=1.28;
topx[9]=1.28;
topx[10]=1.28;
topx[11]=1.28;
topx[12]=1.28;
topx[13]=1.28;
topx[14]=1.28;
topx[15]=1.28;
bottomx[0]=-1.28;
bottomx[1]=-1.28;
bottomx[2]=-1.28;
bottomx[3]=-1.28;
bottomx[4]=-1.28;
bottomx[5]=-1.28;
bottomx[6]=-1.28;
bottomx[7]=-1.28;
bottomx[8]=-1.28;
bottomx[9]=-1.28;
bottomx[10]=-1.28;
bottomx[11]=-1.28;
bottomx[12]=-1.28;
bottomx[13]=-1.28;
bottomx[14]=-1.28;
bottomx[15]=-1.28;
cdata.initialpopulation(m_popsize ,m_generation ,m_csrate ,m_mrate ,topx,bottomx);
cdata.GetPopData(PopData); TargetFunctionCal(PopData,PopValue); cdata.SetValueData(PopValue);
cdata.evaluatepopulation();
for (generation=0;generation
{
cdata.generatenextpopulation();
cdata.GetPopData(PopData);
TargetFunctionCal(PopData,PopValue);
cdata.SetValueData(PopValue);
cdata.evaluatepopulation();
cdata.performevolution();
}
cdata.GetResult (resultx);
m_x1=resultx[0];
m_x2=resultx[1];
m_x3=resultx[2];
m_x4=resultx[3];
m_x5=resultx[4];
m_x6=resultx[5];
m_x7=resultx[6];
m_x8=resultx[7];
m_x9=resultx[8];
m_x10=resultx[9];
m_x11=resultx[10];
m_x12=resultx[11];
m_x13=resultx[12];
m_x14=resultx[13];
m_x15=resultx[14];
m_x16=resultx[15];
m_result=resultx[16];
UpdateData(false);
//不过删除的时候记得要删除PopData[i]里的每个数组: for(i=0; i
{
delete [](PopData[i]);
}
delete []PopData;
delete []PopValue;
//释放数组A;
}
计算结果:
这是我在解决电梯动力学参数写的简单遗传算法(程序带目标函数值、适应度值计算,但是我的适应度函数因为目标函数的计算很特殊,一起放在了程序外面计算,在此不提供)。 头文件:
// CMVSOGA.h : main header file for the CMVSOGA.cpp
// 本来想使用链表里面套链表的,程序调试比较麻烦,改为种群用链表表示
//染色体固定为16的方法。
#if !defined(AFX_CMVSOGA_H__45BECA_61EB_4A0E_9746_9A94D1CCF767__INCLUDED_)
#define
AFX_CMVSOGA_H__45BECA_61EB_4A0E_9746_9A94D1CCF767__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include "Afxtempl.h"
#define variablenum 16
class CMVSOGA
{
public:
CMVSOGA();
void selectionoperator();
void crossoveroperator();
void mutationoperator();
void initialpopulation(int, int ,double ,double,double *,double *); //种群初始化
void generatenextpopulation(); //生成下一代种群
void evaluatepopulation(); //评价个体,求最佳个体
void calculateobjectvalue(); //计算目标函数值
void calculatefitnessvalue(); //计算适应度函数值
void findbestandworstindividual(); //寻找最佳个体和最差个体
void performevolution();
void GetResult(double *);
void GetPopData(double **);
void SetValueData(double *);
void maxandexpectation();
private:
struct individual
{
double chromosome[variablenum]; //染色体编码长度应该为变量的个数 double value;
double fitness; //适应度
};
double variabletop[variablenum]; //变量值
double variablebottom[variablenum]; //变量值
int popsize; //种群大小
// int generation; //世代数
int best_index;
int worst_index;
double crossoverrate; //交叉率
double mutationrate; //变异率
int maxgeneration; //最大世代数
struct individual bestindividual; //最佳个体
struct individual worstindividual; //最差个体
struct individual current; //当前个体
struct individual current1; //当前个体
struct individual currentbest; //当前最佳个体
CList population; //种群
CList newpopulation; //新种群 CList cfitness; //存储适应度值
// double maxfitness;
// double minfitness;
// double avefitness;
//怎样使链表的数据是一个结构体????主要是想把种群作成链表。节省空间。 };
#endif
执行文件
// CMVSOGA.cpp : implementation file
//
#include "stdafx.h"
#include "CMVSOGA.h"
#include "math.h"
#include "stdlib.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
///////////////////////////////////////////////////////////////////////////// // CMVSOGA.cpp
void CMVSOGA::initialpopulation(int ps, int gen ,double cr ,double mr,double *xtop,double *xbottom) //第一步,初始化。
{
int i ,j;
popsize=ps ;
maxgeneration=gen;
crossoverrate=cr;
mutationrate =mr;
for (i=0;i
{
variabletop[i] =xtop[i];
variablebottom[i] =xbottom[i];
}
srand( (unsigned)time( NULL ) );
for(i=0;i
{
for (j=0;j
{
current.chromosome[j]=double(rand()%1000)/1000*(variabletop[j]-variablebottom[j])+variablebottom[j];
}
current.fitness=0;
current.value=0;
population.InsertAfter(population.FindIndex(i),current);//除了初始化使用insertafter外,其他的用setat命令。
}
}
void CMVSOGA::generatenextpopulation()//第三步,生成下一代。
{
selectionoperator();
crossoveroperator();
mutationoperator();
}
void CMVSOGA::evaluatepopulation() //第二步,评价个体,求最佳个体 {
// calculateobjectvalue();
calculatefitnessvalue(); //在此步中因该按适应度值进行排序.链表的排序. findbestandworstindividual();
}
void CMVSOGA:: calculateobjectvalue() //计算函数值,应该由外部函数实现。主要因为目标函数很复杂。
{
int i,j;
double x[variablenum];
for (i=0; i
{
current=population.GetAt(population.FindIndex(i));
current.value=0;
//使用外部函数进行,在此只做结果的传递。
for (j=0;j
{
x[j]=current.chromosome[j];
current.value=current.value+(j+1)*pow(x[j],4);
}
////使用外部函数进行,在此只做结果的传递。
population.SetAt(population.FindIndex(i),current);
}
}
void CMVSOGA::mutationoperator() //对于浮点数编码,变异算子的选择具有决定意义。
//需要guass正态分布函数,生成方差为sigma,均值为浮点数编码值c。 {
int i,j;
double r1,r2,p,sigma;//sigma高斯变异参数
sigma=0.5;
for (i=0;i
{
current=population.GetAt(population.FindIndex(i));
//生成均值为current.chromosome,方差为sigma的高斯分布数
srand((unsigned int) time (NULL));
for(j=0; j
{
r1 =double( rand()%1001)/1000;
r2 = double(rand()%1001)/1000;
p=double(rand()%1000)/1000;
if(p
{
//高斯变异
current.chromosome[j] = (current.chromosome[j]
+ sigma*sqrt(-2*log(r1)/0.4323)*sin(2*3.1415926*r2));
if (current.chromosome[j]>variabletop[j])
{
current.chromosome[j]=variabletop[j];
}
if (current.chromosome[j]
{
current.chromosome[j]=variablebottom [j];
}
}
}
population.SetAt(population.FindIndex(i),current);
}
void CMVSOGA::selectionoperator() //从当前个体中按概率选择新种群,应该加一个复制选择,提高种群的平均适应度
//第二次循环出错
{
int i,j,pindex=0;
double p,pc,sum=0;
i=0;
j=0;
pindex=0;
p=0;
pc=0;
sum=0.001;
newpopulation.RemoveAll();
cfitness.RemoveAll();
//链表排序
// population.SetAt (population.FindIndex(0),current); //多余代码
for (i=1;i
{
current=population.GetAt(population.FindIndex(i));
for(j=0;j
{
current1=population.GetAt(population.FindIndex(j));//临时借用变量 if(current.fitness
{
population.InsertBefore(population.FindIndex(j),current);
population.RemoveAt(population.FindIndex(i+1));
break;
}
}
// m=population.GetCount();
}
//链表排序
for(i=0;i
current=population.GetAt(population.FindIndex(i));
sum+=current.fitness;
}
for(i=0;i
{
current=population.GetAt(population.FindIndex(i));
current.fitness=current.fitness/sum;
cfitness.InsertAfter (cfitness .FindIndex(i),current.fitness);
for(i=1;i
{
current.fitness=cfitness.GetAt (cfitness.FindIndex(i-1))
+cfitness.GetAt(cfitness.FindIndex(i)); //归一化
cfitness.SetAt (cfitness .FindIndex(i),current.fitness);
population.SetAt(population.FindIndex(i),current);
}
for (i=0;i
{
p=double(rand()%1000)/1000+0.0001; //随机生成概率
pindex=0; //遍历索引
pc=cfitness.GetAt(cfitness .FindIndex(0));
while(p>=pc&&pindex
{
pc=cfitness.GetAt(cfitness .FindIndex(pindex));
pindex++;
}
//必须是从index~popsize,选择高概率的数。即大于概率p的数应该被选择,选择不满则进行下次选择。
for (j=popsize-1;j
{
newpopulation.InsertAfter (newpopulation.FindIndex(0),
population.GetAt (population.FindIndex(j)));
i++;
}
}
for(i=0;i
{
population.SetAt (population.FindIndex(i),
newpopulation.GetAt (newpopulation.FindIndex(i)));
}
// j=newpopulation.GetCount();
// j=population.GetCount();
newpopulation.RemoveAll();
}
//current 变化后,以上没有问题了。
void CMVSOGA:: crossoveroperator() //非均匀算术线性交叉,浮点数适用,alpha ,beta是(0,1)之间的随机数
//对种群中两两交叉的个体选择也是随机选择的。也可取beta=1-alpha; //current的变化会有一些改变。
int i,j;
double alpha,beta;
CList index;
int point,temp;
double p;
srand( (unsigned)time( NULL ) );
for (i=0;i
{
index.InsertAfter (index.FindIndex(i),i);
}
for (i=0;i
{
point=rand()%(popsize-1);
temp=index.GetAt(index.FindIndex(i));
index.SetAt(index.FindIndex(i),
index.GetAt(index.FindIndex(point)));
index.SetAt(index.FindIndex(point),temp);
}
for (i=0;i
{//按顺序序号,按序号选择两个母体进行交叉操作。
p=double(rand()%1000)/1000.0;
if (p
{
alpha=double(rand()%1000)/1000.0;
beta=double(rand()%1000)/1000.0;
current=population.GetAt(population.FindIndex(index.GetAt(index.FindIndex(i))));
current1=population.GetAt(population.FindIndex(index.GetAt(index.FindIndex(i+1))));//临时使用current1代替
for(j=0;j
{
//交叉
current.chromosome[j]=(1-alpha)*current.chromosome[j]+
beta*current1.chromosome[j];
if (current.chromosome[j]>variabletop[j]) //判断是否超界.
{
current.chromosome[j]=variabletop[j];
}
if (current.chromosome[j]
{
current.chromosome[j]=variablebottom [j];
}
current1.chromosome[j]=alpha*current.chromosome[j]
+(1- beta)*current1.chromosome[j];
if (current1.chromosome[j]>variabletop[j])
{
current1.chromosome[j]=variabletop[j];
}
if (current1.chromosome[j]
{
current1.chromosome[j]=variablebottom [j];
}
}
//回代
}
newpopulation.InsertAfter (newpopulation.FindIndex(i),current);
newpopulation.InsertAfter (newpopulation.FindIndex(i),current1); }
j=newpopulation.GetCount();
for (i=0;i
{
population.SetAt (population.FindIndex(i),
newpopulation.GetAt (newpopulation.FindIndex(i)));
}
newpopulation.RemoveAll();
}
void CMVSOGA:: findbestandworstindividual( )
{
int i;
bestindividual=population.GetAt(population.FindIndex(best_index)); worstindividual=population.GetAt(population.FindIndex(worst_index)); for (i=1;i
{
current=population.GetAt(population.FindIndex(i));
if (current.fitness>bestindividual.fitness)
{
bestindividual=current;
best_index=i;
}
else if (current.fitness
{
worstindividual=current;
worst_index=i;
}
}
population.SetAt(population.FindIndex(worst_index),
population.GetAt(population.FindIndex(best_index)));
//用最好的替代最差的。使用这个之后结果相差很大。不收敛。
if (maxgeneration==0)
{
currentbest=bestindividual;
}
else
{
if(bestindividual.fitness>=currentbest.fitness)
{
currentbest=bestindividual;
}
}
}
void CMVSOGA:: calculatefitnessvalue() //适应度函数值计算,关键是适应度函数的设计
//current变化,这段程序变化较大,特别是排序。
{
int i;
double temp;//alpha,beta;//适应度函数的尺度变化系数
double cmax=100;
for(i=0;i
{
current=population.GetAt(population.FindIndex(i));
if(current.value
{
temp=cmax-current.value;
}
else
{
temp=0.0;
}
/*
if((population[i].value+cmin)>0.0)
{temp=cmin+population[i].value;}
else
{temp=0.0;
}
*/
current.fitness=temp;
population.SetAt(population.FindIndex(i),current);
}
}
void CMVSOGA:: performevolution() //演示评价结果,有冗余代码,current变化,程序应该改变较大
{
if (bestindividual.fitness>currentbest.fitness)
{
currentbest=population.GetAt(population.FindIndex(best_index));
}
else
{
population.SetAt(population.FindIndex(worst_index),currentbest); }
}
void CMVSOGA::GetResult(double *Result)
{
int i;
for (i=0;i
{
Result[i]=currentbest.chromosome[i];
}
Result[i]=currentbest.value;
}
CMVSOGA::CMVSOGA()
{
best_index=0;
worst_index=0;
crossoverrate=0; //交叉率
mutationrate=0; //变异率
maxgeneration=0;
}
void CMVSOGA::GetPopData(double **PopData) //不能保证每次计算结果都对,为什么?
{
int i,j;
for (i=0;i
{
current=population.GetAt(population.FindIndex(i));
for (j=0;j
{
PopData[i][j]=current.chromosome[j];
}
}
}
void CMVSOGA::SetValueData(double *ValueData)
{
int j;
for (j=0;j
{
current=population.GetAt(population.FindIndex(j));
current.value=ValueData[j];
population.SetAt(population.FindIndex(j),current);
}
}
DLG中调用代码:
void CMVSOFGADlg::OncalNoGuass()
{
// TODO: Add your control notification handler code here
UpdateData(true);
UINT i;
UINT generation;
double topx[16], bottomx[16];
double resultx[17];
////////////////////////////////////
double ** PopData;
double *PopValue;
PopData = new double*[m_popsize];
for(i=0; i
{
PopData[i] = new double[16];
}
PopValue=new double [m_popsize];
////////////////////////////////////
//////////////初始化/////////////
CMVSOGA cdata;
m_result=0;
topx[0]=1.28;
topx[1]=1.28;
topx[2]=1.28;
topx[3]=1.28;
topx[4]=1.28;
topx[5]=1.28;
topx[6]=1.28;
topx[7]=1.28;
topx[8]=1.28;
topx[9]=1.28;
topx[10]=1.28;
topx[11]=1.28;
topx[12]=1.28;
topx[13]=1.28;
topx[14]=1.28;
topx[15]=1.28;
bottomx[0]=-1.28;
bottomx[1]=-1.28;
bottomx[2]=-1.28;
bottomx[3]=-1.28;
bottomx[4]=-1.28;
bottomx[5]=-1.28;
bottomx[6]=-1.28;
bottomx[7]=-1.28;
bottomx[8]=-1.28;
bottomx[9]=-1.28;
bottomx[10]=-1.28;
bottomx[11]=-1.28;
bottomx[12]=-1.28;
bottomx[13]=-1.28;
bottomx[14]=-1.28;
bottomx[15]=-1.28;
cdata.initialpopulation(m_popsize ,m_generation ,m_csrate ,m_mrate ,topx,bottomx);
cdata.GetPopData(PopData); TargetFunctionCal(PopData,PopValue); cdata.SetValueData(PopValue);
cdata.evaluatepopulation();
for (generation=0;generation
{
cdata.generatenextpopulation();
cdata.GetPopData(PopData);
TargetFunctionCal(PopData,PopValue);
cdata.SetValueData(PopValue);
cdata.evaluatepopulation();
cdata.performevolution();
}
cdata.GetResult (resultx);
m_x1=resultx[0];
m_x2=resultx[1];
m_x3=resultx[2];
m_x4=resultx[3];
m_x5=resultx[4];
m_x6=resultx[5];
m_x7=resultx[6];
m_x8=resultx[7];
m_x9=resultx[8];
m_x10=resultx[9];
m_x11=resultx[10];
m_x12=resultx[11];
m_x13=resultx[12];
m_x14=resultx[13];
m_x15=resultx[14];
m_x16=resultx[15];
m_result=resultx[16];
UpdateData(false);
//不过删除的时候记得要删除PopData[i]里的每个数组: for(i=0; i
{
delete [](PopData[i]);
}
delete []PopData;
delete []PopValue;
//释放数组A;
}
计算结果: