【新安江模型】一个基于C++和MFC的新安江模型及遗传算法

说明

原始作者已不可考,程序属于半成品(见图),有志者可以继续完善。这里分享一下,供大家交流学习。
我在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);
}

文件下载

下载链接

猜你喜欢

转载自blog.csdn.net/qq_25262697/article/details/130088449