说明
原始作者已不可考,程序属于半成品(见图),有志者可以继续完善。这里分享一下,供大家交流学习。
我在VS2019,V142版本的MFC环境下编译成功。
注:C++版本的新安江推荐里新安江模型C++实现
这里还有另一个CPP实现(坡面地表径流采用单位线):xinanjiangcpp
核心代码
新安江模型的实现
XAJ.h
#pragma once
#include <vector>
#include <fstream>
static double UH[]={
0.3,0.6,0.1};
static int M=3;
class XAJ
{
public:
XAJ();
~XAJ();
void InitialPA(std::vector<double> m_Pra);//输入降雨资料
void InitialPE(std::ifstream& ifile);
void MainCompute();
double ComputeValue();
//friend class GeneEvolution;
private:
//std::ifstream ifile;
std::vector<double> P;
std::vector<double> E;
std::vector<double> QR;//计算
std::vector<double> QRS;//实测
int Date_Num;//降雨资料时段数
double K;//流域蒸散发能力Em与实测水面蒸发值Ei之比:蒸发折算系数
double IMP;//不透水面积占全流域面积之比
double B;//蓄水容量曲线的次方
//double WM;//流域平均蓄水容量
double WUM;//流域上层平均蓄水容量
double WLM;//流域下层平均蓄水容量
double WDM;//流域深层平均蓄水容量
double C;//深层蒸散发系数
double SM;//自由水蓄水容量
double EX;//自由水蓄水容量曲线指数
double KG;//地下水出流系数
double KSS;//壤中流出流系数
double KKG;//地下径流消退系数
double KKSS;//壤中流消退系数
double S;//初始流域自由水水深
double WU;//上层张力水含量
double WL;//下层张力水含量
double WD;//深层张力水含量
//double WO;//张力含水量
double FR;
double QRSSO;//初始壤中流流量
double QRGO;//初始地下径流量
//double KE;//单元河段的马斯京根模型参数K值
//double XE;//单元河段的马斯京根模型参数X值
double DT;//单位线时段长
double AREA;//全流域面积
};
// double K=0.65;//流域蒸散发能力Em与实测水面蒸发值Ei之比:蒸发折算系数
// double IMP=0;//不透水面积占全流域面积之比
// double B=0.3;//蓄水容量曲线的次方
// double WM;//流域平均蓄水容量
// double WUM=20;//流域上层平均蓄水容量
// double WLM=75;//流域下层平均蓄水容量
// double WDM=80;//流域深层平均蓄水容量
// double C=0.11;//深层蒸散发系数
// double SM=20;//自由水蓄水容量
// double EX=1;//自由水蓄水容量曲线指数
// double KG=0.3;//地下水出流系数
// double KSS=0.41;//壤中流出流系数
// double KKG=0.99;//地下径流消退系数
// double KKSS=0.6;//壤中流消退系数
// double S=20;//初始流域自由水水深
// double WU=0;//上层张力水含量
// double WL=70;//下层张力水含量
// double WD=80;//深层张力水含量
// double WO;//张力含水量
// double FR=0.1;
// double QRSSO=40;
// double QRGO=20;
// double KE;//单元河段的马斯京根模型参数K值
// double XE;//单元河段的马斯京根模型参数X值
// double DT=2;//单位线时段长
// double AREA=537;//全流域面积
//
//需要率定的参数 16个 存放在一个vector容器里
// 上层张力水容量(WUM) 20 a
// 下层张力水容量(WLM) 75 a
// 深层张力水容量(WDM) 80 a
// 蒸发皿折算系数(K) 0.65 a
// 深层蒸散发系数(C) 0.11 a
// 蓄水容量曲线的方次(b) 0.3 a
// 不透水面积比(IMP) 0.2 a
// 自由水库容量(SM) 20 a
// 自由水库容量曲线(EX) 1 a
// 地下水库出流系数(KG) 0.3 a
// 壤中流出流系数(KSS) 0.41 a
// 地下径流日消退系数(KKG) 0.99 a
// 壤中流日消退系数(KKSS) 0.6 a
// 上层张力水含量(WU) 40 a
// 下层张力水含量(WL) 60 a
// 深层张力水含量(WD) 70 a
xinanjiang.cpp
// xinanjiang.cpp : 定义控制台应用程序的入口点。
//新安江模型
#include "stdafx.h"
#include "XAJ.h"
#include <iostream>
#include <fstream>
#include <vector>
#include <math.h>
using namespace std;
XAJ::XAJ()
{
}
void XAJ::InitialPE(std::ifstream& ifile)
{
ifile>>Date_Num;
P.resize(Date_Num);
E.resize(Date_Num);
QR.resize(Date_Num);
QRS.resize(Date_Num);
for (int i=0;i<Date_Num;i++)
{
ifile>>E[i]>>P[i]>>QRS[i];
QR[i]=0;
if (E[i]<0)
{
E[i]=0;
}
if (P[i]<0)
{
P[i]=0;
}
}
ifile.close();
}
void XAJ::InitialPA(std::vector<double> m_Pra)
{
int Viable_NUM=m_Pra.size();
WUM=m_Pra[0];//
WLM=m_Pra[1];//
WDM=m_Pra[2];//
K=m_Pra[3];//
C=m_Pra[4];//
B=m_Pra[5];//
//IMP=m_Pra[6];
SM=m_Pra[6];//
EX=m_Pra[7];//
KG=m_Pra[8];//
KSS=m_Pra[9];//
KKG=m_Pra[10];//
KKSS=m_Pra[11];//
WU=0;
WL=70;
WD=80;
DT=2;
AREA=537;
QRSSO=40;
QRGO=20;
S=20;
FR=0.1;
IMP=0;
// WU=60;//上层张力水含量
// WL=70;//下层张力水含量
// WD=80;//深层张力水含量
}
void XAJ::MainCompute()
{
// 上层张力水容量(WUM) 20 a
// 下层张力水容量(WLM) 75 a
// 深层张力水容量(WDM) 80 a
// 蒸发皿折算系数(K) 0.65 a
// 深层蒸散发系数(C) 0.11 a
// 蓄水容量曲线的方次(b) 0.3 a
// 不透水面积比(IMP) 0.2 a
// 自由水库容量(SM) 20 a
// 自由水库容量曲线(EX) 1 a
// 地下水库出流系数(KG) 0.3 a
// 壤中流出流系数(KSS) 0.41 a
// 地下径流日消退系数(KKG) 0.99 a
// 壤中流日消退系数(KKSS) 0.6 a
// 上层张力水含量(WU) 40 a
// 下层张力水含量(WL) 60 a
// 深层张力水含量(WD) 70 a
double R,RS,RSS,RG,RIM;
double EU,EL,ED,PE;
double X,Q,U,D,CI,CG,KSSD,KGD;
double SS=0,NN=0,KSSDD=0,KGDD=0,SMM=0,SMMF=0,SMF=0,AU=0,RGD=0,RSD=0,RSSD=0,QRS=0,QRSS=0,QRG=0,QTR=0;
//初始化参数
U= AREA / (DT * 3.6);
if (DT <= 24)
{
D = 24 / DT;
CI = pow((double)KKSS,(double)(1.0 / D));
CG = pow((double)KKG,(double)(1.0 / D));
KSSD = (1.0 -pow((double)(1.0-(KG+KSS)),(double)(1.0/D)))/(1.0+KG/KSS);
KGD = KSSD * KG / KSS;
}
//计算不透水面积的产流量,且直接转化为地面径流
//计算透水面积的产流量
double WMM,WM,WO;
double A;
for(int i=0;i<Date_Num;i++)
{
WM=WLM+WUM+WDM;
WO=WL+WU+WD;
PE=P[i]-K*E[i];
R=0;
RIM=0;
if (PE>0)//净雨大于0,产流,计算土壤含水量变化
{
//土壤的含水量WL,WU,WD会发生变化
//流域土壤的WLM,WUM,WDM平均蓄水容量不会发生变化
WMM=((1+B)/(1-IMP))*WM;
if ((WMM-WM)<=0.000001)
{
A=WMM;
}
else
{
A=WMM*(1-pow((float)(1-WO/WM),(float)(1/(B+1))));
}
if (PE+A<WMM)
{
R=PE-WM+WO+WM*pow((float)(1-(PE+A)/WMM),(float)(B+1));
}
else
{
R=PE-(WM-WO);
}
RIM=PE*IMP;
}
//大于蒸发能力
if(P[i]+WU>E[i])
{
EU=K*E[i];
ED=0;
EL=0;
}
else//要求下层蒸发量与剩余蒸散发能力不小于深层蒸散发吸吮C
{
EU=WU+P[i];
EL=(K*E[i]-EU)*WL/WLM;
ED=0;
if (WL<=C*WLM)
{
if (WL >= C * (K*E[i] - EU))
{
EL = C * (K*E[i] - EU);
ED=0;
}
else
{
EL = WL;
ED = C * (K*E[i] - EU) - EL;
}
}
}
//土壤水计算
WU = WU + P[i] - R - EU;
WL = WL - EL;
WD = WD - ED;
if (WU < 0)
{
WU = 0;
}
if (WU > WUM)
{
WL = WU - WUM + WL;
WU = WUM;
if (WL > WLM)
{
WD = WD + WL - WLM;
WL = WLM;
}
}
//三水源的划分
X=FR;
if (PE<=0)
{
RS=0;
RSS=S*KSSD*FR;
RGD=S*KGD*FR;
S=S-(RSS+RG)/FR;
}
else
{
FR=R/PE;
S=X*S/FR;
SS=S;
Q=R/FR;
NN=int(Q/5.0)+1;
Q=Q/NN;
KSSDD = (1.0 -pow((float)(1.0-(KGD+KSSD)),(float)(1.0/NN)))/(1.0+KGD/KSSD);
KGDD = KSSDD * KGD / KSSD;
RS=0;
RSS=0;
RG=0;
SMM=(1.0+EX)*SM;
if (EX<0.001)
{
SMMF=SMM;
}
else
{
SMMF=SMM*(1.0 - pow((float)(1.0- FR),(float)(1.0/ EX)));
}
//}
SMF=SMMF/(1.0+EX);
for (int k=1;k<=NN;k++)
{
if (S>SMF)
{
S=SMF;
}
AU=SMMF * (1 -pow( (float)(1 - S / SMF) , (float)(1 / (1 + EX))));
if ((Q+AU)<=0)
{
RSD = 0;
RSSD = 0;
RGD = 0;
S = 0;
}
else if (Q+AU>=SMMF)
{
RSD = (Q + S - SMF) * FR;
RSSD = SMF * KSSDD * FR;
RGD = SMF * KGDD * FR;
S = SMF - (RSSD + RGD) / FR;
}
else if (Q+AU<SMMF)
{
RSD = (Q - SMF + S + SMF * pow((float)(1 - (Q + AU) / SMMF) ,(float)(1 + EX))) * FR;
RSSD = (S + Q - RSD / FR) * KSSDD * FR;
RGD = (S + Q - RSD / FR) * KGDD * FR;
S = S + Q - (RSD + RSSD + RGD) / FR;
}
RS=RS+RSD;
RSS=RSS+RSSD;
RG=RG+RGD;
}
}
RS = RS * (1 - IMP);
RSS = RSS * (1 - IMP);
RG = RG * (1 - IMP);
QRS = (RS + RIM) * U;
//cout<<QRS<<endl;
QRSS = QRSSO * CI + RSS * (1 - CI) * U;
QRG = QRGO * CG + RG * (1 - CG) * U;
QTR = QRS + QRSS + QRG;
for(int j=0;j<4;j++)
{
if (i+j>=Date_Num)
{
break;
}
QR[i+j]=QR[i+j]+QTR*UH[j];
//cout<<QR[i+j]<<endl;
}
//ofile<<QR[i]<<endl;
QRSSO=QRSS;
QRGO=QRG;
}
//ofile.close();
//cout<<"over"<<endl;
}
double XAJ::ComputeValue()
{
double Value_Num=0;
double Average_Q=0,Sum=0;
for (int i=0;i<Date_Num;i++)
{
Sum+=QR[i];
}
Average_Q=Sum/Date_Num;
double DQ=0,A=0,B=0;
for (int i=0;i<Date_Num;i++)
{
A+=((QRS[i]-QR[i])*(QRS[i]-QR[i]));
B+=((QRS[i]-Average_Q)*(QRS[i]-Average_Q));
}
DQ=1-sqrt(A/Date_Num)/sqrt(B/Date_Num);
// CString str;
// str.Format(L"%d",Value_Num);
// AfxMessageBox(str);
return DQ;
}
XAJ::~XAJ()
{
//AfxMessageBox(L"新安江对象析构!");
}
遗传算法的实现
Gene.h
#pragma once
#include "Afxtempl.h"
#include <fstream>
#include <vector>
#include "XAJ.h"
class GeneEvolution
{
public:
GeneEvolution();
~GeneEvolution();
//friend class
void SelectionOperator();//选择操作
void CrossoverOperator();//交叉操作
void MutationOperator();//变异操作
void InitialPopulation(std::ifstream& ifile);//种群初始化
void GenerateNextPopulation(); //生成下一代种群
void EvaluatePopulation(); //评价个体,求最佳个体
void CalculateObjectValue(XAJ m_XAJ); //计算目标函数值
void CalculateFitnessValue(); //计算适应度函数值
void FindBestAndWorstIndividual(); //寻找最佳个体和最差个体
int GetMaxGeneration();
void GetData(CDC* pDC,XAJ m_XAJ);
private:
int VariableNum;
struct Individual//种群
{
std::vector<double> Chromosome;
//染色体编码长度应该为变量的个数
//做为参数传给XAJ的计算程序
double Value;
double Fitness; //适应度
};
std::vector<double> VariableTop; //变量值
std::vector<double> VariableBottom; //变量值
int PopSize; //种群大小
//int Generation; //世代数
int Best_Index;
int Worst_Index;
int Generation;
double CrossOverRate; //交叉率
double MutationRate; //变异率
int MaxGeneration; //最大世代数
struct Individual BestIndividual; //最佳个体
struct Individual WorstIndividual; //最差个体
struct Individual Current; //当前个体
struct Individual Current1; //当前个体
struct Individual CurrentBest; //当前最佳个体
CList <struct Individual,struct Individual &> Population; //种群
CList <struct Individual,struct Individual &> NewPopulation; //新种群
CList <double,double> Cfitness; //存储适应度值
CList <double,double> CChance; //被选择的概率
//怎样使链表的数据是一个结构体????主要是想把种群作成链表。节省空间。
};
Gene.cpp
#include <stdafx.h>
#include "Gene.h"
#include <time.h>
#include <math.h>
GeneEvolution::GeneEvolution()
{
Best_Index=0;
Worst_Index=0;
CrossOverRate=0;
MutationRate=0;
MaxGeneration=0;
}
GeneEvolution::~GeneEvolution()
{
Best_Index=0;
Worst_Index=0;
CrossOverRate=0;
Generation=0;
MutationRate=0;
MaxGeneration=0;
NewPopulation.RemoveAll();
Population.RemoveAll();
Cfitness.RemoveAll();
}
void GeneEvolution::InitialPopulation(std::ifstream& iflie)//初始化种群
{
iflie>>VariableNum>>PopSize>>MaxGeneration>>CrossOverRate>>MutationRate;
VariableTop.resize(VariableNum);
VariableBottom.resize(VariableNum);
Current.Chromosome.resize(VariableNum);
Current1.Chromosome.resize(VariableNum);
CurrentBest.Chromosome.resize(VariableNum);
for (int i=0;i<VariableNum;i++)//输入参数的上下限
{
iflie>>VariableBottom[i]>>VariableTop[i];
}
//随机生成一个种群
srand((unsigned int)time(0));
for(int i=0;i<PopSize;i++)
{
for(int j=0;j<VariableNum;j++)
{
Current.Chromosome[j]=double(rand()%10000)/10000*(VariableTop[j]-VariableBottom[j])+VariableBottom[j];
}
Current.Fitness=0;
Current.Value=0;
Population.InsertAfter(Population.FindIndex(i),Current);
}
}
void GeneEvolution::CalculateObjectValue( XAJ m_XAJ)//计算种群的得分,使用外部的目标函数,(本程序用于新安江自动率参试验)
//或者说需要寻优的实际问题的参数好坏的评价函数,对该参数序列做好坏评价
{
for (int i=0;i<PopSize;i++)
{
Current=Population.GetAt(Population.FindIndex(i));
m_XAJ.InitialPA(Current.Chromosome);
m_XAJ.MainCompute();
Current.Value=m_XAJ.ComputeValue();
Population.SetAt(Population.FindIndex(i),Current);
}
}
void GeneEvolution::CalculateFitnessValue()//计算适应分,种群进化的评价标准,该函数的可变范围较大,要寻找一个合适的评分标准
{
for (int i=0;i<PopSize;i++)
{
Current=Population.GetAt(Population.FindIndex(i));
if (Generation>=MaxGeneration*7/8)
{
Current.Fitness=pow(Current.Value,1.5);
MutationRate=0.08;
CrossOverRate=0.9;
}
else if(Generation<=MaxGeneration*7/8&&Generation>=MaxGeneration*5/8)
{
MutationRate=0.06;
CrossOverRate=0.85;
Current.Fitness=pow(Current.Value,2.5);
}
else
{
Current.Fitness=pow(Current.Value,3.5);
}
Population.SetAt(Population.FindIndex(i),Current);
}
}
void GeneEvolution::FindBestAndWorstIndividual()//寻找最好和最坏的种群
{
BestIndividual=Population.GetAt(Population.FindIndex(Best_Index));
WorstIndividual=Population.GetAt(Population.FindIndex(Worst_Index));
for (int i=0;i<PopSize;i++)
{
Current=Population.GetAt(Population.FindIndex(i));
if (Current.Fitness>=BestIndividual.Fitness)
{
BestIndividual=Current;
Best_Index=i;
}
else if (Current.Fitness<WorstIndividual.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 (CurrentBest.Fitness<BestIndividual.Fitness)
{
CurrentBest=BestIndividual;
}
}
}
void GeneEvolution::EvaluatePopulation()//评估种群,该函数可有可无,包含以上三个函数
{
// CalculateObjectValue(m);
// CalculateFitnessValue();
// FindBestAndWorstIndividual();
}
void GeneEvolution::GenerateNextPopulation()//生成下一代种群,包含下面三个函数
{
SelectionOperator();
CrossoverOperator();
MutationOperator();
Generation++;
}
void GeneEvolution ::SelectionOperator()//选择
{
NewPopulation.RemoveAll();
Cfitness.RemoveAll();
for (int i=0;i<PopSize;i++)//从小到大排序
{
Current=Population.GetAt(Population.FindIndex(i));
for (int j=0;j<i;j++)
{
Current1=Population.GetAt(Population.FindIndex(j));
if (Current.Fitness<=Current1.Fitness)
{
Population.InsertBefore(Population.FindIndex(j),Current);
Population.RemoveAt(Population.FindIndex(i+1));
break;
}
}
}//排序结束
//计算总适应分
long double Sum=0.01;
for (int i=0;i<PopSize;i++)
{
Current=Population.GetAt(Population.FindIndex(i));
Sum+=Current.Fitness;
}
//计算适应度值
for(int i=0;i<PopSize;i++)
{
Current=Population.GetAt(Population.FindIndex(i));
Current.Value=Current.Value/Sum;
Cfitness.AddTail(Current.Value);//每一个染色体占适应分的比例
//占的比例越大,越优秀,应该被选择成为下一代群体的一员
}
//计算每一个基因被选择的概率,存储在CChance链表里
for (int i=0;i<PopSize;i++)
{
long double Chance_Sum=0;
for(int j=0;j<i;j++)
{
Chance_Sum+=Cfitness.GetAt(Cfitness.FindIndex(j));
}
CChance.AddTail(Chance_Sum);
}
//轮盘赌方法选择进化到下一代的染色体
srand((unsigned int )time(0));
for (int i=0;i<PopSize;i++)
{
double p=(double)(rand()%999)/1000+0.0001;
for (int j=0;j<PopSize;j++)
{
if (CChance.GetAt(CChance.FindIndex(j))>=p)
{
NewPopulation.AddTail(Population.GetAt(Population.FindIndex(j)));
break;
}
else if(j==PopSize-1)
{
NewPopulation.AddTail(Population.GetAt(Population.FindIndex(j)));
break;
}
}
}
//轮盘赌算法改进(把NewPopulation中出现5次以上的个体用Population中一个随机个体代替)
int* Con=new int[PopSize];
BOOL* iscopy=new BOOL[PopSize];
for (int i=0;i<PopSize;i++)//对NewPopulation做初始化标示
{
Con[i]=1;
iscopy[i]=FALSE;
}
for (int m=0;m<PopSize;m++)
{
Current1=NewPopulation.GetAt(NewPopulation.FindIndex(m));
for (int n=m+1;n<PopSize;n++)
{
Current=NewPopulation.GetAt(NewPopulation.FindIndex(n));
if ((Current1.Fitness==Current.Fitness)&&(!iscopy[n]))
{
Con[m]++;
iscopy[n]=TRUE;//表示有重复
}
}
}
for ( int m=0;m<PopSize;m++)//出现次数归一化
{
if (Con[m]>=5)
{
for (int i=m+1;i<PopSize;i++)
{
Current=NewPopulation.GetAt(NewPopulation.FindIndex(m));
Current1=NewPopulation.GetAt(NewPopulation.FindIndex(i));
if (Current.Fitness==Current1.Fitness)
{
Con[i]=Con[m];
}
}
}
}
srand((unsigned int)time(0));
for (int i=0;i<PopSize;i++)
{
int index=(int)((float)(PopSize-i) * rand() / (RAND_MAX+1.0));
if ((Con[i]>=5)&&(!iscopy[i]))
{
Population.SetAt(Population.FindIndex(i),Population.GetAt(Population.FindIndex(index)));
}
if (Con[i]<5)
{
Population.SetAt(Population.FindIndex(i),NewPopulation.GetAt(NewPopulation.FindIndex(i)));
}
}
delete []Con;
delete []iscopy;
NewPopulation.RemoveAll();
}
void GeneEvolution::CrossoverOperator()//交叉 非均匀算术线性交叉
{
//生成序号
CList <int ,int> Order_Code;
for(int i=0;i<PopSize;i++)
{
Order_Code.AddTail(i);
}
//打乱序号
CList <int, int> UnOrder_Code;
for (int i=0;i<PopSize;i++)
{
UnOrder_Code.AddTail(i);
}
srand((unsigned int)time(0));
for (int j=0;j<PopSize;j++)
{
int index=(int)((float)(PopSize-j) * rand() / (RAND_MAX+1.0));
UnOrder_Code.SetAt(UnOrder_Code.FindIndex(index),Order_Code.GetAt(Order_Code.FindIndex(PopSize-1-j)));
}
//做交叉计算
for(int i=0;i<PopSize-1;i+=2)
{
//srand((unsigned int)time(0));
double p=double(rand()%10000)/10000.0;
if (p<CrossOverRate)
{
double alpha=double(rand()%10000)/10000.0;
//double beta=(rand()%10000)/10000.0;
double beta=1-alpha;
Current=Population.GetAt(Population.FindIndex(UnOrder_Code.GetAt(UnOrder_Code.FindIndex(i))));
Current1=Population.GetAt(Population.FindIndex(UnOrder_Code.GetAt(UnOrder_Code.FindIndex(i+1))));
for (int j=0;j<VariableNum;j++)
{
int Sign;
srand((unsigned int)time(0));
Sign=rand()%2;
if(Sign)
{
Current.Chromosome[j]=(alpha)*Current.Chromosome[j]+beta*Current1.Chromosome[j];//非均匀算术线性交叉
}
else
{
Current.Chromosome[j]=(alpha)*Current.Chromosome[j]-beta*Current1.Chromosome[j];
}
if (Current.Chromosome[j]>VariableTop[j]) //判断是否超界.
{
Current.Chromosome[j]=double(rand()%10000)/10000*(VariableTop[j]-VariableBottom[j])+VariableBottom[j];
}
if (Current.Chromosome[j]<VariableBottom [j])
{
Current.Chromosome[j]=double(rand()%10000)/10000*(VariableTop[j]-VariableBottom[j])+VariableBottom[j];
}
if(Sign)
{
Current1.Chromosome[j]=alpha*Current.Chromosome[j]+
(beta)*Current1.Chromosome[j];
}
else
{
Current1.Chromosome[j]=alpha*Current.Chromosome[j]-
(beta)*Current1.Chromosome[j];
}
if (Current1.Chromosome[j]>VariableTop[j])
{
Current1.Chromosome[j]=double(rand()%10000)/10000*(VariableTop[j]-VariableBottom[j])+VariableBottom[j];
}
if (Current1.Chromosome[j]<VariableBottom [j])
{
Current1.Chromosome[j]=double(rand()%10000)/10000*(VariableTop[j]-VariableBottom[j])+VariableBottom[j];
}
}
}
NewPopulation.InsertAfter(NewPopulation.FindIndex(i),Current);
NewPopulation.InsertAfter(NewPopulation.FindIndex(i),Current1);
}//交叉计算结束
//ASSERT(NewPopulation.GetCount()==PopSize);//检验种群数量是否保持不变
for (int i=0;i<PopSize;i++)
{
Population.SetAt(Population.FindIndex(i),NewPopulation.GetAt(NewPopulation.FindIndex(i)));
}
NewPopulation.RemoveAll();
UnOrder_Code.RemoveAll();
}
void GeneEvolution::MutationOperator()//变异 使用高斯变异
//需要guass正态分布函数,生成方差为sigma
{
double R1,R2,P,Sigma;
for (int i=0;i<PopSize;i++)
{
Current=Population.GetAt(Population.FindIndex(i));
srand((int)time(0));
for (int j=0;j<VariableNum;j++)
{
P=double(rand()%10000)/10000.0;
R1=double(rand()%10001)/10000.0;
R2=double(rand()%10001)/10000.0;
if (P<MutationRate)
{
double Sign;
Sign=rand()%2;//产生一个随机数
Sigma=0.01*(VariableTop[j]-VariableBottom [j]);
if(Sign)
{
Current.Chromosome[j] = (Current.Chromosome[j]
+ Sigma*sqrt(-2*log(R1)/0.4323)*sin(2*3.1415926*R2));
}
else
{
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]=double(rand()%10000)/10000*(VariableTop[j]-VariableBottom[j])+VariableBottom[j];
}
if (Current.Chromosome[j]<VariableBottom [j])
{
Current.Chromosome[j]=double(rand()%10000)/10000*(VariableTop[j]-VariableBottom[j])+VariableBottom[j];
}
}
}
Population.SetAt(Population.FindIndex(i),Current);
}
}
int GeneEvolution::GetMaxGeneration()
{
return MaxGeneration;
}
void GeneEvolution::GetData(CDC* pDC,XAJ m_XAJ)
{
CString str(L"优选的参数");
pDC->TextOut(120,20,str);
str=L"参数的确定性系数";
pDC->TextOut(220,20,str);
for(size_t i=0;i<CurrentBest.Chromosome.size();i++)
{
str.Format(L"%f",CurrentBest.Chromosome[i]);
pDC->TextOut(120,50+i*30,str);
}
m_XAJ.InitialPA(CurrentBest.Chromosome);
m_XAJ.MainCompute();
CurrentBest.Value=m_XAJ.ComputeValue();
str.Format(L"%f",CurrentBest.Value);
pDC->TextOut(220,50,str);
}