编程语言
首页 > 编程语言> > 差分进化算法(DE)的C++面向对象方法实现

差分进化算法(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 }

 

标签:DNA,double,DE,C++,面向对象,num,pars,new,old
来源: https://www.cnblogs.com/zhanjiahui/p/11181821.html