找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 5366|回复: 0
收起左侧

差分进化算法C++语言实现

[复制链接]
ID:278642 发表于 2018-1-23 21:02 | 显示全部楼层 |阅读模式
差分进化算法的C语言实现,有大量的注释,简单易懂!
  1. /*DE_test
  2. *对相应的Matlab程序进行测试
  3. */

  4. #include <iostream>
  5. #include <cmath>
  6. #include <ctime>
  7. using namespace std;

  8. //产生随机数,随机数为(0.0,1.0)
  9. double Rand_Double(void)
  10. {
  11.         return static_cast<double>(rand()) / static_cast<double>(RAND_MAX);
  12. }

  13. //测试函数Hansen
  14. //参数个数为2
  15. double Hansen(double *p_pars)
  16. {
  17.         return ( cos(1.0) + 2.0*cos(p_pars[0]+2.0) + 3.0*cos(2.0*p_pars[0]+3.0)
  18.                 + 4.0*cos(3.0*p_pars[0]+4.0) + 5.0*cos(4.0*p_pars[0]+5.0) )
  19.                 * ( cos(2.0*p_pars[1]+1.0) + 2.0*cos(3.0*p_pars[1]+2.0) +
  20.                 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) );
  21. }

  22. class CFunction
  23. {
  24. public:
  25.         void *m_p_fun;//指向测试函数的指针
  26.         int m_pars_num;//参数个数
  27.         double m_min;//下限
  28.         double m_max;//上限
  29.         bool m_pos;//求解最小值还是最大值,如果是最小值则m_pos为false,如果是最大值则m_pos为true
  30. public:
  31.         CFunction(void *p_fun,int pars_num,double min,double max,bool pos)
  32.                 :m_p_fun(p_fun),m_pars_num(pars_num),m_min(min),m_max(max),m_pos(pos)
  33.         {
  34.         }

  35.         virtual double Compute(double *p_pars) = 0;
  36. };

  37. class CHansen:public CFunction
  38. {
  39. public:
  40.         //注册函数
  41.         CHansen(void)
  42.                 :CFunction(Hansen,2,-10.0,10.0,false)
  43.         {
  44.         }

  45.         double Compute(double *p_pars)
  46.         {
  47.                 return Hansen(p_pars);
  48.         }
  49. };

  50. //个体
  51. class CIndividual
  52. {
  53. public:
  54.         double *m_p_DNA;//参数
  55.         double m_f;//适应值
  56.         int m_DNA_length;//DNA的长度

  57. public:
  58.         CIndividual(void)
  59.                 :m_f(0.0),m_DNA_length(0),m_p_DNA(NULL)
  60.         {
  61.         }

  62.         ~CIndividual(void)
  63.         {
  64.                 if(m_p_DNA!=NULL)
  65.                         delete[] m_p_DNA;
  66.         }

  67.         //初始化,分配内存空间
  68.         void Ini(int pars_num)
  69.         {
  70.                 m_DNA_length = pars_num;
  71.                 m_p_DNA = new double[m_DNA_length];
  72.         }

  73.         //假定两者分配的内存空间的大小一样
  74.         CIndividual& operator=(CIndividual& ind)
  75.         {
  76.                 m_f = ind.m_f;
  77.                 //m_DNA_length = ind.m_DNA_length;
  78.                 for(int i=0;i<m_DNA_length;++i)
  79.                 {
  80.                         m_p_DNA[i] = ind.m_p_DNA[i];
  81.                 }
  82.                 return *this;
  83.         }

  84.         friend ostream& operator<<(ostream& o,CIndividual& ind)
  85.         {
  86.                 return o<<ind.m_f;
  87.         }
  88. };


  89. int main()
  90. {
  91.         //---------------------------设置随机数------------------------------------
  92.         srand((unsigned int)(time(NULL)));

  93.         //获得参数
  94.         int Num,T;
  95.         double zoom,cr;

  96.         cout<<"种群大小:";
  97.         cin>>Num;

  98.         cout<<"进化代数:";
  99.         cin>>T;

  100.         cout<<"缩放因子:";
  101.         cin>>zoom;

  102.         cout<<"交叉因子:";
  103.         cin>>cr;

  104.         //----------------------对函数进行操作,注册函数------------------------------
  105.         CHansen fun_Hansen;
  106.        
  107.         CFunction *p_fun = &fun_Hansen;//为了实现多态
  108.         int pars_num = p_fun->m_pars_num;//参数个数
  109.         double min = p_fun->m_min;//下限
  110.         double max = p_fun->m_max;//上限
  111.         bool pos = p_fun->m_pos;//求最大值还是最小值

  112.         //----------------------注册种群,并分配内存空间-----------------------------
  113.         CIndividual *p_old = new CIndividual[Num];
  114.         CIndividual *p_new = new CIndividual[Num];
  115.         for(int i=0;i<Num;++i)
  116.         {
  117.                 p_old[i].Ini(pars_num);
  118.                 p_new[i].Ini(pars_num);
  119.         }

  120.         //-------------------------产生初始的随机种群--------------------------------
  121.         for(int i=0;i<Num;++i)//对种群进行遍历
  122.         {
  123.                 for(int j=0;j<pars_num;++j)//对参数列表进行遍历
  124.                         p_old[i].m_p_DNA[j] = Rand_Double()*(max-min)+min;
  125.                 p_old[i].m_f = p_fun->Compute(p_old[i].m_p_DNA);
  126.         }

  127.         CIndividual ind_best;
  128.         ind_best.Ini(pars_num);

  129.         for(int t=0;t<T;++t)//开始一代一代地进化
  130.         {
  131.                 //显示结果
  132.                 ind_best = p_old[0];
  133.                 for(int i=1;i<Num;++i)
  134.                 {
  135.                         if(pos==true && ind_best.m_f<p_old[i].m_f)//求最大值
  136.                                 ind_best = p_old[i];
  137.                         else if(pos==false && ind_best.m_f>p_old[i].m_f)//求最小值
  138.                                 ind_best = p_old[i];
  139.                 }
  140.                 cout<<ind_best<<"\n";

  141.                 //差分变异
  142.                 for(int i=0;i<Num;++i)//对种群进行遍历
  143.                 {
  144.                         //产生三个随机数
  145.                         int x1,x2,x3;
  146.                         x1 = rand() % Num;
  147.                         do
  148.                         {
  149.                                 x2 = rand() % Num;
  150.                         }while(x1==x2);
  151.                         do
  152.                         {
  153.                                 x3 = rand() % Num;
  154.                         }while(x1==x3||x2==x3);

  155.                         for(int j=0;j<pars_num;++j)//对参数列表进行遍历
  156.                         {
  157.                                 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] );
  158.                                 if(p_new[i].m_p_DNA[j]<min || p_new[i].m_p_DNA[j]>max)//越界
  159.                                         p_new[i].m_p_DNA[j] = p_old[i].m_p_DNA[j];
  160.                         }
  161.                 }

  162.                 //交叉操作,注意,交叉要对每个实数位进行交叉
  163.                 for(int i=0;i<Num;++i)//对种群进行遍历
  164.                 {
  165.                         for(int j=0;j<pars_num;++j)
  166.                         {
  167.                                 if(Rand_Double()>cr)//不交叉
  168.                                         p_new[i].m_p_DNA[j] = p_old[i].m_p_DNA[j];
  169.                         }
  170.                         p_new[i].m_f = p_fun->Compute(p_new[i].m_p_DNA);
  171.                 }

  172.                 //选择操作
  173.                 for(int i=0;i<Num;++i)//对种群进行遍历
  174.                 {
  175.                         if(pos==true && p_new[i].m_f < p_old[i].m_f)//求最大值
  176.                                 p_new[i] = p_old[i];
  177.                         else if(pos==false && p_new[i].m_f > p_old[i].m_f)//求最小值
  178.                                 p_new[i] = p_old[i];
  179.                 }

  180.                 //交换
  181.                 CIndividual *p_tmp;
  182.                 p_tmp = p_old;
  183.                 p_old = p_new;
  184.                 p_new = p_tmp;
  185.                 //此时,新种群的值被保存到p_old中
  186.         }

  187.         return 0;
  188. }
复制代码





Main.rar

1.79 KB, 下载次数: 7, 下载积分: 黑币 -5

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表