差分進化算法(DE)的C++面向對象方法實現


代碼來源於網絡,寫得非常棒

  1 /*DE_test
  2  *對相應的Matlab程序進行測試
  3  */
  4 
  5 #include <iostream>
  6 #include <cmath>
  7 #include <ctime>
  8 using namespace std;
  9 
 10 //產生隨機數,隨機數為(0.0,1.0)
 11 double Rand_Double(void)
 12 {
 13     return static_cast<double>(rand()) / static_cast<double>(RAND_MAX);
 14 }
 15 
 16 //測試函數Hansen
 17 //參數個數為2
 18 double Hansen(double *p_pars)
 19 {
 20     return (cos(1.0) + 2.0*cos(p_pars[0] + 2.0) + 3.0*cos(2.0*p_pars[0] + 3.0)
 21         + 4.0*cos(3.0*p_pars[0] + 4.0) + 5.0*cos(4.0*p_pars[0] + 5.0))
 22         * (cos(2.0*p_pars[1] + 1.0) + 2.0*cos(3.0*p_pars[1] + 2.0) +
 23             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));
 24 }
 25 
 26 class CFunction
 27 {
 28 public:
 29     void *m_p_fun;//指向測試函數的指針
 30     int m_pars_num;//參數個數
 31     double m_min;//下限
 32     double m_max;//上限
 33     bool m_pos;//求解最小值還是最大值,如果是最小值則m_pos為false,如果是最大值則m_pos為true
 34 public:
 35     CFunction(void *p_fun, int pars_num, double min, double max, bool pos)
 36         :m_p_fun(p_fun), m_pars_num(pars_num), m_min(min), m_max(max), m_pos(pos)
 37     {
 38     }
 39 
 40     virtual double Compute(double *p_pars) = 0;
 41 };
 42 
 43 class CHansen :public CFunction
 44 {
 45 public:
 46     //注冊函數
 47     CHansen(void)
 48         :CFunction(Hansen, 2, -10.0, 10.0, false)
 49     {
 50     }
 51 
 52     double Compute(double *p_pars)
 53     {
 54         return Hansen(p_pars);
 55     }
 56 };
 57 
 58 //個體
 59 class CIndividual
 60 {
 61 public:
 62     double *m_p_DNA;//參數
 63     double m_f;//適應值
 64     int m_DNA_length;//DNA的長度
 65 
 66 public:
 67     CIndividual(void)
 68         :m_f(0.0), m_DNA_length(0), m_p_DNA(NULL)
 69     {
 70     }
 71 
 72     ~CIndividual(void)
 73     {
 74         if (m_p_DNA != NULL)
 75             delete[] m_p_DNA;
 76     }
 77 
 78     //初始化,分配內存空間
 79     void Ini(int pars_num)
 80     {
 81         m_DNA_length = pars_num;
 82         m_p_DNA = new double[m_DNA_length];
 83     }
 84 
 85     //假定兩者分配的內存空間的大小一樣
 86     CIndividual& operator=(CIndividual& ind)
 87     {
 88         m_f = ind.m_f;
 89         //m_DNA_length = ind.m_DNA_length;
 90         for (int i = 0; i < m_DNA_length; ++i)
 91         {
 92             m_p_DNA[i] = ind.m_p_DNA[i];
 93         }
 94         return *this;
 95     }
 96 
 97     friend ostream& operator<<(ostream& o, CIndividual& ind)//運算符重載  98     {
 99         return o << ind.m_f;
100     }
101 };
102 
103 
104 int main()
105 {
106     //---------------------------設置隨機數------------------------------------
107     srand((unsigned int)(time(NULL)));
108 
109     //獲得參數
110     int Num, T;
111     double zoom, cr;
112 
113     cout << "種群大小:";
114     cin >> Num;
115 
116     cout << "進化代數:";
117     cin >> T;
118 
119     cout << "縮放因子:";
120     cin >> zoom;
121 
122     cout << "交叉因子:";
123     cin >> cr;
124 
125     //----------------------對函數進行操作,注冊函數------------------------------
126     CHansen fun_Hansen;
127 
128     CFunction *p_fun = &fun_Hansen;//為了實現多態
129     int pars_num = p_fun->m_pars_num;//參數個數
130     double min = p_fun->m_min;//下限
131     double max = p_fun->m_max;//上限
132     bool pos = p_fun->m_pos;//求最大值還是最小值
133 
134     //----------------------注冊種群,並分配內存空間-----------------------------
135     CIndividual *p_old = new CIndividual[Num];
136     CIndividual *p_new = new CIndividual[Num];
137     for (int i = 0; i < Num; ++i)
138     {
139         p_old[i].Ini(pars_num);
140         p_new[i].Ini(pars_num);
141     }
142 
143     //-------------------------產生初始的隨機種群--------------------------------
144     int i;
145     for (i = 0; i < Num; ++i)//對種群進行遍歷
146     {
147         for (int j = 0; j < pars_num; ++j)//對參數列表進行遍歷
148             p_old[i].m_p_DNA[j] = Rand_Double()*(max - min) + min;
149         p_old[i].m_f = p_fun->Compute(p_old[i].m_p_DNA);
150     }
151 
152     CIndividual ind_best;
153     ind_best.Ini(pars_num);
154 
155     for (int t = 0; t < T; ++t)//開始一代一代地進化
156     {
157         //顯示結果
158         ind_best = p_old[0];
159         for (int i = 1; i < Num; ++i)
160         {
161             if (pos == true && ind_best.m_f < p_old[i].m_f)//求最大值
162                 ind_best = p_old[i];
163             else if (pos == false && ind_best.m_f > p_old[i].m_f)//求最小值
164                 ind_best = p_old[i];
165         }
166         cout << ind_best << "\n";
167 
168         //差分變異
169         for (i = 0; i < Num; ++i)//對種群進行遍歷
170         {
171             //產生三個隨機數
172             int x1, x2, x3;
173             x1 = rand() % Num;
174             do
175             {
176                 x2 = rand() % Num;
177             } while (x1 == x2);
178             do
179             {
180                 x3 = rand() % Num;
181             } while (x1 == x3 || x2 == x3);
182 
183             for (int j = 0; j < pars_num; ++j)//對參數列表進行遍歷
184             {
185                 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]);
186                 if (p_new[i].m_p_DNA[j]<min || p_new[i].m_p_DNA[j]>max)//越界
187                     p_new[i].m_p_DNA[j] = p_old[i].m_p_DNA[j];
188             }
189         }
190 
191         //交叉操作,注意,交叉要對每個實數位進行交叉
192         for (i = 0; i < Num; ++i)//對種群進行遍歷
193         {
194             for (int j = 0; j < pars_num; ++j)
195             {
196                 if (Rand_Double() > cr)//不交叉
197                     p_new[i].m_p_DNA[j] = p_old[i].m_p_DNA[j];
198             }
199             p_new[i].m_f = p_fun->Compute(p_new[i].m_p_DNA);
200         }
201 
202         //選擇操作
203         for (i = 0; i < Num; ++i)//對種群進行遍歷
204         {
205             if (pos == true && p_new[i].m_f < p_old[i].m_f)//求最大值
206                 p_new[i] = p_old[i];
207             else if (pos == false && p_new[i].m_f > p_old[i].m_f)//求最小值
208                 p_new[i] = p_old[i];
209         }
210 
211         //交換
212         CIndividual *p_tmp;
213         p_tmp = p_old;
214         p_old = p_new;
215         p_new = p_tmp;
216         //此時,新種群的值被保存到p_old中
217     }
218 
219     return 0;
220 }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM