|
差分进化算法的C语言实现,有大量的注释,简单易懂!
- /*DE_test
- *对相应的Matlab程序进行测试
- */
- #include <iostream>
- #include <cmath>
- #include <ctime>
- using namespace std;
- //产生随机数,随机数为(0.0,1.0)
- double Rand_Double(void)
- {
- return static_cast<double>(rand()) / static_cast<double>(RAND_MAX);
- }
- //测试函数Hansen
- //参数个数为2
- double Hansen(double *p_pars)
- {
- return ( cos(1.0) + 2.0*cos(p_pars[0]+2.0) + 3.0*cos(2.0*p_pars[0]+3.0)
- + 4.0*cos(3.0*p_pars[0]+4.0) + 5.0*cos(4.0*p_pars[0]+5.0) )
- * ( cos(2.0*p_pars[1]+1.0) + 2.0*cos(3.0*p_pars[1]+2.0) +
- 3.0*cos(4.0*p_pars[1]+3.0) + 4.0*cos(5.0*p_pars[1]+4.0) + 5.0*cos(6.0*p_pars[1]+5.0) );
- }
- class CFunction
- {
- public:
- void *m_p_fun;//指向测试函数的指针
- int m_pars_num;//参数个数
- double m_min;//下限
- double m_max;//上限
- bool m_pos;//求解最小值还是最大值,如果是最小值则m_pos为false,如果是最大值则m_pos为true
- public:
- CFunction(void *p_fun,int pars_num,double min,double max,bool pos)
- :m_p_fun(p_fun),m_pars_num(pars_num),m_min(min),m_max(max),m_pos(pos)
- {
- }
- virtual double Compute(double *p_pars) = 0;
- };
- class CHansen:public CFunction
- {
- public:
- //注册函数
- CHansen(void)
- :CFunction(Hansen,2,-10.0,10.0,false)
- {
- }
- double Compute(double *p_pars)
- {
- return Hansen(p_pars);
- }
- };
- //个体
- class CIndividual
- {
- public:
- double *m_p_DNA;//参数
- double m_f;//适应值
- int m_DNA_length;//DNA的长度
- public:
- CIndividual(void)
- :m_f(0.0),m_DNA_length(0),m_p_DNA(NULL)
- {
- }
- ~CIndividual(void)
- {
- if(m_p_DNA!=NULL)
- delete[] m_p_DNA;
- }
- //初始化,分配内存空间
- void Ini(int pars_num)
- {
- m_DNA_length = pars_num;
- m_p_DNA = new double[m_DNA_length];
- }
- //假定两者分配的内存空间的大小一样
- CIndividual& operator=(CIndividual& ind)
- {
- m_f = ind.m_f;
- //m_DNA_length = ind.m_DNA_length;
- for(int i=0;i<m_DNA_length;++i)
- {
- m_p_DNA[i] = ind.m_p_DNA[i];
- }
- return *this;
- }
- friend ostream& operator<<(ostream& o,CIndividual& ind)
- {
- return o<<ind.m_f;
- }
- };
- int main()
- {
- //---------------------------设置随机数------------------------------------
- srand((unsigned int)(time(NULL)));
- //获得参数
- int Num,T;
- double zoom,cr;
- cout<<"种群大小:";
- cin>>Num;
- cout<<"进化代数:";
- cin>>T;
- cout<<"缩放因子:";
- cin>>zoom;
- cout<<"交叉因子:";
- cin>>cr;
- //----------------------对函数进行操作,注册函数------------------------------
- CHansen fun_Hansen;
-
- CFunction *p_fun = &fun_Hansen;//为了实现多态
- int pars_num = p_fun->m_pars_num;//参数个数
- double min = p_fun->m_min;//下限
- double max = p_fun->m_max;//上限
- bool pos = p_fun->m_pos;//求最大值还是最小值
- //----------------------注册种群,并分配内存空间-----------------------------
- CIndividual *p_old = new CIndividual[Num];
- CIndividual *p_new = new CIndividual[Num];
- for(int i=0;i<Num;++i)
- {
- p_old[i].Ini(pars_num);
- p_new[i].Ini(pars_num);
- }
- //-------------------------产生初始的随机种群--------------------------------
- for(int i=0;i<Num;++i)//对种群进行遍历
- {
- for(int j=0;j<pars_num;++j)//对参数列表进行遍历
- p_old[i].m_p_DNA[j] = Rand_Double()*(max-min)+min;
- p_old[i].m_f = p_fun->Compute(p_old[i].m_p_DNA);
- }
- CIndividual ind_best;
- ind_best.Ini(pars_num);
- for(int t=0;t<T;++t)//开始一代一代地进化
- {
- //显示结果
- ind_best = p_old[0];
- for(int i=1;i<Num;++i)
- {
- if(pos==true && ind_best.m_f<p_old[i].m_f)//求最大值
- ind_best = p_old[i];
- else if(pos==false && ind_best.m_f>p_old[i].m_f)//求最小值
- ind_best = p_old[i];
- }
- cout<<ind_best<<"\n";
- //差分变异
- for(int i=0;i<Num;++i)//对种群进行遍历
- {
- //产生三个随机数
- int x1,x2,x3;
- x1 = rand() % Num;
- do
- {
- x2 = rand() % Num;
- }while(x1==x2);
- do
- {
- x3 = rand() % Num;
- }while(x1==x3||x2==x3);
- for(int j=0;j<pars_num;++j)//对参数列表进行遍历
- {
- p_new[i].m_p_DNA[j] = p_old[x1].m_p_DNA[j] + zoom * ( p_old[x2].m_p_DNA[j] - p_old[x3].m_p_DNA[j] );
- if(p_new[i].m_p_DNA[j]<min || p_new[i].m_p_DNA[j]>max)//越界
- p_new[i].m_p_DNA[j] = p_old[i].m_p_DNA[j];
- }
- }
- //交叉操作,注意,交叉要对每个实数位进行交叉
- for(int i=0;i<Num;++i)//对种群进行遍历
- {
- for(int j=0;j<pars_num;++j)
- {
- if(Rand_Double()>cr)//不交叉
- p_new[i].m_p_DNA[j] = p_old[i].m_p_DNA[j];
- }
- p_new[i].m_f = p_fun->Compute(p_new[i].m_p_DNA);
- }
- //选择操作
- for(int i=0;i<Num;++i)//对种群进行遍历
- {
- if(pos==true && p_new[i].m_f < p_old[i].m_f)//求最大值
- p_new[i] = p_old[i];
- else if(pos==false && p_new[i].m_f > p_old[i].m_f)//求最小值
- p_new[i] = p_old[i];
- }
- //交换
- CIndividual *p_tmp;
- p_tmp = p_old;
- p_old = p_new;
- p_new = p_tmp;
- //此时,新种群的值被保存到p_old中
- }
- return 0;
- }
复制代码
|
|