⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ga.cpp

📁 遗传算法类的声明及定义
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//遗传算法类cpp文件
//Edit by Wang Shimin
//2004.7.5~2004.7.30
//本文件为最新文件,修改于2006.3.12

// GA.cpp: implementation of the GA class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "GA.h"
#include "math.h"
#include "fstream"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

GA::GA()
{
   /* 初始化计数变量和一些数值*/
	m_convergencenumber = 0;
	m_precision = 0.000001;
	m_errorflag = TRUE;
	m_oldbestfit.fitness = 0.0;
    m_bestfit.fitness = 0.0;
    m_bestfit.generation = 0;
	m_pc2 = 0.3;
	m_pc1 = 0.9;
	m_pm2 = 0.01;
	m_pm1 = 0.1;
	m_perlchrom = 16; //染色体中单个参数的长度默认为16位
    m_pcross = 0.0;     //交叉率
	m_pmutation = 0.0;  //变异率
	m_numbndload = 0;
	m_popsize = 10;
	m_maxgen = 20;
	m_currentgen = 0;
	m_pernumbytes = 1;

	/* 初始化随机种子 */
	srand((unsigned)time(NULL));
	m_randseed = double((rand()%10000)/10000.0);

	/*将指针置零*/
	p_Bndload = NULL;
	p_BAKindflag = NULL;
	p_iparameter = NULL;
	p_jparameter = NULL;
	p_calculation = NULL;
	p_observation = NULL;
	p_highboundary = NULL;             
	p_lowboundary = NULL;
	p_deltavariable = NULL;
	p_oldpop = NULL;
	p_newpop = NULL;
	m_bestfit.chrom = NULL;
	m_bestfit.variable = NULL;

	m_blErrorExit = false;
}

GA::~GA()
{
	/*释放内存空间*/
	for(int i = 0; i < m_popsize; i++)
    {
		delete[]p_oldpop[i].chrom;
		delete[]p_oldpop[i].variable;
		delete[]p_newpop[i].chrom;
		delete[]p_newpop[i].variable;
    }
	delete[]p_oldpop;
	delete[]p_newpop;
	delete[]m_bestfit.chrom;
	delete[]m_bestfit.variable;
	
	delete[]p_BAKindflag;
	delete[]p_iparameter;
	delete[]p_jparameter;
	delete[]p_highboundary;
	delete[]p_lowboundary;
	delete[]p_deltavariable;
	delete[]p_calculation;
	delete[]p_observation;
	delete[]p_Bndload;
}

/* 遗传算法初始化 */
void GA::initialize()  
{
    /* 输入遗传算法参数 */
	ReadINP();
	if(m_blErrorExit)return;

	CString csMEAFileName = mGcsFileName+_T(".MEA");
	ifstream cMEAFile;
	cMEAFile.open((LPCSTR)csMEAFileName); 
	if (cMEAFile.fail())
	{
		AfxMessageBox("Cannot open input MEA file!!!",MB_OK);
		m_blErrorExit = true;
		return;
	}
	
	cMEAFile >> m_numpoint;  /* 从MEA文件中读取观测点的个数 */
	cMEAFile.close();

    /*分配给全局数据结构空间 */
    initmalloc();

	/* 读入待反演参数 */
	ReadBAA();
	if(m_blErrorExit)return;

	/* 读入测点的观测值 */
	ReadMEA();
	if(m_blErrorExit)return;
	
 	/* 初始化种群,并统计计算结果 */
    initpop();
}

/* 读取遗传算法参数 */
void GA::ReadINP()
{
	CString csINPFileName = mGcsFileName+_T(".INP");
	ifstream cINPFile;
	cINPFile.open((LPCSTR)csINPFileName); 
	if (cINPFile.fail())
	{
		AfxMessageBox("Cannot open input INP file!!!",MB_OK);
		m_blErrorExit = true;
		return;
	}

	char tempch[256];

	cINPFile.getline(tempch,256);
	cINPFile >> m_popsize >> m_numvar >> m_pm2 >> m_maxgen
		>> m_pc2 >> m_perlchrom >> m_precisionnum;

	m_pernumbytes = m_perlchrom/8;

	cINPFile.close();

	if((m_popsize%2)==1)
	{
		AfxMessageBox(GIDS_PROMPT_NOT_SINGLE,MB_OK);
		m_blErrorExit = true;
		return;
	}
	/* 确定染色体的总长度 */
	m_sumlchrom = m_perlchrom*m_numvar ;
}

/*为数组数据变量分配空间 */
void GA::initmalloc()
{
	//当重新输入参数的时候调用此函数,释放原来的动态内存
	if(p_oldpop)
	{
		delete[]p_oldpop ;
		p_oldpop = NULL ;
	}
	
	if(p_newpop)
	{
		delete[]p_newpop ;
		p_newpop = NULL;
	}

	/* 分配给当前代和新一代种群内存空间 */
	p_oldpop=new individual[m_popsize];
	p_newpop=new individual[m_popsize];

	/* 分配给观测数据和计算数据内存空间 */
	if(p_calculation)
		delete[]p_calculation;
	
	if(p_observation)
		delete[]p_observation;

	p_calculation = new double[m_numpoint];
	p_observation = new double[m_numpoint];

	/* 为存储识别待反演参数性质的数组分配内存空间 */

	if(p_BAKindflag)
		delete[]p_BAKindflag;

	if(p_iparameter)
		delete[]p_iparameter;

	if(p_jparameter)
		delete[]p_jparameter;

	p_BAKindflag = new int[m_numvar];
	p_iparameter = new int[m_numvar];
	p_jparameter = new int[m_numvar];

	/* 为存储各个参数上下限和精度的数组分配内存空间 */
	if(p_highboundary)
		delete[]p_highboundary;
	
	if(p_lowboundary)
		delete[]p_lowboundary;
	
	if(p_deltavariable)
		delete[]p_deltavariable;
	
	p_highboundary = new double[m_numvar];
	p_lowboundary = new double[m_numvar];
	p_deltavariable = new double[m_numvar];
	
	/* 分配给染色体内存空间 */
	m_sumnumbytes = m_sumlchrom/8;
	
	for(int i = 0; i < m_popsize; i++)
	{
		p_oldpop[i].chrom = new BYTE[m_sumnumbytes];
		p_newpop[i].chrom = new BYTE[m_sumnumbytes];
		m_bestfit.chrom = new BYTE[m_sumnumbytes];

		p_oldpop[i].variable = new double[m_numvar];
		p_newpop[i].variable = new double[m_numvar];
		p_oldpop[i].objvalue = new double[m_numpoint];
		p_newpop[i].objvalue = new double[m_numpoint];
		m_bestfit.variable = new double[m_numvar];
		m_bestfit.objvalue = new double[m_numpoint];
	}
}

/* 从BAA文件中读入待反演参数的性质标志以及上下限 */
void GA::ReadBAA()
{
	char tempchar[256];
	int  index;

	CString csBaaFileName = mGcsFileName+_T(".BAA");
	ifstream cBaaFile;
	cBaaFile.open((LPCSTR)csBaaFileName); 
	if (cBaaFile.fail())
	{
		AfxMessageBox("Cannot open input BAA file!!!",MB_OK);
		m_blErrorExit = true;
		return;
	}
	

	cBaaFile.getline(tempchar,256);
	
	//读入各个参数的上下限,并计算出各个参数的精度
	for(int i=0; i<m_numvar; i++)
	{
		cBaaFile >> index;
		cBaaFile >> p_BAKindflag[i];
		cBaaFile >> p_iparameter[i];
		cBaaFile >> p_jparameter[i];
		cBaaFile >> p_lowboundary[i];
		cBaaFile >> p_highboundary[i];
		cBaaFile.getline(tempchar,256);
		p_deltavariable[i] = (p_highboundary[i]-p_lowboundary[i])/(pow(2.0,(double)m_perlchrom)-1.0);
	}

	cBaaFile >> m_numbndload;

	if(m_numbndload>0)
	{
		if(p_Bndload)
		{
			delete[]p_Bndload ;
			p_Bndload = NULL ;
		}

		p_Bndload = new bndload[m_numbndload];

		for(int j=0; j<m_numbndload; j++)
		{
			cBaaFile >> p_Bndload[j].index >> p_Bndload[j].wAddStage
				>> p_Bndload[j].wAddStep >> p_Bndload[j].iNode1
				>> p_Bndload[j].iNode2 >> p_Bndload[j].iCoordFlag
				>> p_Bndload[j].BeginLoad1 >> p_Bndload[j].BeginLoad2
				>> p_Bndload[j].BeginLoad3 >> p_Bndload[j].EndLoad1
				>> p_Bndload[j].EndLoad2 >> p_Bndload[j].EndLoad3;

			cBaaFile.getline(tempchar,256);
		}
	}

	cBaaFile.close();
}

/*产生0到1 之间均匀分布的随机数*/
double GA::randomperc(double *seed) 
{
  
 //r双精度实型变量指针。该指针指向的单元存放随机数的种子;返回一个新值。但是本函数返回的不是r
	int m;
    double s,u,v;
	double result;

    s = 65536.0;
	u = 2053.0;
	v = 13849.0;
    m = (int)(*seed/s);
	*seed = *seed-m*s;
    *seed = u*(*seed)+v;
	m = (int)(*seed/s);
    *seed = *seed-m*s;
	result = *seed/s;
    return(result);
}

/* 随机初始化种群 */
void GA::initpop()  
{

    int i, j, k,l;
    BYTE mask = 1;

    for(i = 0; i < m_popsize; i++)
    {	
		p_oldpop[i].fitness = 0.0;

        for(k = 0; k < m_sumnumbytes; k++)
        {
            p_oldpop[i].chrom[k] = 0;
            
			for(j = 1; j <= 8; j++)
            {
				p_oldpop[i].chrom[k] = p_oldpop[i].chrom[k]<<1;
				if(flip(0.5))
					p_oldpop[i].chrom[k] = p_oldpop[i].chrom[k]|mask;
            }
        }
		
    	/* 解码得到编码所对应的实数值 */
        decode(&(p_oldpop[i]));
		/* 计算适应度函数值 */
		
		WriteToFem(&(p_oldpop[i]));
	    if(m_blErrorExit)return;
		
		objectfunc();
	    if(m_blErrorExit)return;
		
		ReadFromFem(p_calculation);
	    if(m_blErrorExit)return;

		for(l=0; l<m_numpoint; l++)
		{
			p_oldpop[i].objvalue[l] = p_observation[l]-p_calculation[l];
			p_oldpop[i].fitness += pow(p_oldpop[i].objvalue[l],2.0);
		}
    }
	
	Keepbest(p_oldpop);
}

/* 以一定概率产生0或1 */
bool GA::flip(double prob)
{
	if(randomperc(&m_randseed) <= prob)
        return(1);
    else
        return(0);
}

/* 解码 */
void GA::decode(individual *critter)  
{
    BYTE mask=1;
    int bitpos;   //染色体中的每位在参数解码时的位数
    BYTE tp;
    double  bitpow ;
    int i, j, k, l;
	for(i=0; i<m_numvar; i++)
	{
		critter->variable[i] = 0.0;
		
		for(j=0; j<m_pernumbytes; j++)
		{
			k = i*m_pernumbytes+j;
			tp = critter->chrom[k];
			for(l=0; l<8; l++)
			{
				bitpos = j*8+l;

				if((tp&mask) == 1)
				{
					bitpow = pow(2.0,(double) bitpos);
					critter->variable[i] = critter->variable[i] + bitpow;
				}
				tp = tp>>1;
			}
		}
		
		critter->variable[i] = p_lowboundary[i]+critter->variable[i]*p_deltavariable[i];
	}
}

/* 计算有限元值 */
void GA::objectfunc() 
{
	if(EXCUTE_NUMERICAL_ANALYSIS()==false)
		m_blErrorExit=true;
}

/* 遗传演化 */
void GA::generation()
{
  int i,mate1, mate2,j = 0;
  double fitness;


  Keepbest(p_oldpop);
  
  //保留上一步最佳适应值
  m_oldbestfit.fitness = m_bestfit.fitness; 

  /* 选择, 交叉, 变异 */
  do
  {
      /* 挑选交叉配对 */
      mate1 = select();
      mate2 = select();

	  /* 调整交叉概率 */
	  fitness=min(p_oldpop[mate1].fitness,p_oldpop[mate2].fitness);
	  m_pcross=adjust_cp(fitness);
	  
      /* 交叉 */
      crossover(p_oldpop[mate1].chrom, p_oldpop[mate2].chrom, p_newpop[j].chrom, p_newpop[j+1].chrom);

	  /********************** 第j个个体******************/

	  /* 解码并计算个体适应值 */
      decode(&(p_newpop[j]));
	  WriteToFem(&(p_newpop[j]));
	  if(m_blErrorExit)return;

	  objectfunc();
	  if(m_blErrorExit)return;
	  
	  ReadFromFem(p_calculation);
	  if(m_blErrorExit)return;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -