|
差分進化算法的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;//為了實現多態(tài)
- 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;
- }
復制代碼
|
-
-
Main.rar
2018-1-23 21:02 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
1.79 KB, 下載次數: 7, 下載積分: 黑幣 -5
|