找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開(kāi)始

搜索
查看: 5676|回復(fù): 0
收起左側(cè)

差分進(jìn)化算法C++語(yǔ)言實(shí)現(xiàn)

[復(fù)制鏈接]
ID:278642 發(fā)表于 2018-1-23 21:02 | 顯示全部樓層 |閱讀模式
差分進(jìn)化算法的C語(yǔ)言實(shí)現(xiàn),有大量的注釋?zhuān)?jiǎn)單易懂!
  1. /*DE_test
  2. *對(duì)相應(yīng)的Matlab程序進(jìn)行測(cè)試
  3. */

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

  8. //產(chǎn)生隨機(jī)數(shù),隨機(jī)數(shù)為(0.0,1.0)
  9. double Rand_Double(void)
  10. {
  11.         return static_cast<double>(rand()) / static_cast<double>(RAND_MAX);
  12. }

  13. //測(cè)試函數(shù)Hansen
  14. //參數(shù)個(gè)數(shù)為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;//指向測(cè)試函數(shù)的指針
  26.         int m_pars_num;//參數(shù)個(gè)數(shù)
  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.         //注冊(cè)函數(shù)
  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. //個(gè)體
  51. class CIndividual
  52. {
  53. public:
  54.         double *m_p_DNA;//參數(shù)
  55.         double m_f;//適應(yīng)值
  56.         int m_DNA_length;//DNA的長(zhǎng)度

  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.         //初始化,分配內(nèi)存空間
  68.         void Ini(int pars_num)
  69.         {
  70.                 m_DNA_length = pars_num;
  71.                 m_p_DNA = new double[m_DNA_length];
  72.         }

  73.         //假定兩者分配的內(nèi)存空間的大小一樣
  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.         //---------------------------設(shè)置隨機(jī)數(shù)------------------------------------
  92.         srand((unsigned int)(time(NULL)));

  93.         //獲得參數(shù)
  94.         int Num,T;
  95.         double zoom,cr;

  96.         cout<<"種群大。";
  97.         cin>>Num;

  98.         cout<<"進(jìn)化代數(shù):";
  99.         cin>>T;

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

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

  104.         //----------------------對(duì)函數(shù)進(jìn)行操作,注冊(cè)函數(shù)------------------------------
  105.         CHansen fun_Hansen;
  106.        
  107.         CFunction *p_fun = &fun_Hansen;//為了實(shí)現(xiàn)多態(tài)
  108.         int pars_num = p_fun->m_pars_num;//參數(shù)個(gè)數(shù)
  109.         double min = p_fun->m_min;//下限
  110.         double max = p_fun->m_max;//上限
  111.         bool pos = p_fun->m_pos;//求最大值還是最小值

  112.         //----------------------注冊(cè)種群,并分配內(nèi)存空間-----------------------------
  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.         //-------------------------產(chǎn)生初始的隨機(jī)種群--------------------------------
  121.         for(int i=0;i<Num;++i)//對(duì)種群進(jìn)行遍歷
  122.         {
  123.                 for(int j=0;j<pars_num;++j)//對(duì)參數(shù)列表進(jìn)行遍歷
  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)//開(kāi)始一代一代地進(jìn)化
  130.         {
  131.                 //顯示結(jié)果
  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)//對(duì)種群進(jìn)行遍歷
  143.                 {
  144.                         //產(chǎn)生三個(gè)隨機(jī)數(shù)
  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)//對(duì)參數(shù)列表進(jìn)行遍歷
  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.                 //交叉操作,注意,交叉要對(duì)每個(gè)實(shí)數(shù)位進(jìn)行交叉
  163.                 for(int i=0;i<Num;++i)//對(duì)種群進(jìn)行遍歷
  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)//對(duì)種群進(jìn)行遍歷
  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.                 //此時(shí),新種群的值被保存到p_old中
  186.         }

  187.         return 0;
  188. }
復(fù)制代碼





Main.rar

1.79 KB, 下載次數(shù): 7, 下載積分: 黑幣 -5

回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

手機(jī)版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表