EDBF优化算法来源:Zuo, Z., Yan, L., Ullah, S., Sun, Y., Zhang, R., & Zhao, H. (2021). Empirical distribution-based framework for improving multi-parent crossover algorithms. Soft Computing, 1-24.
编译器:VS2015
1. 新建一个dll工程(工程名:EDBFDLL.cpp)
文件----新建-----项目-----模板-----Win32-----Win32项目------应用程序设置------应用程序类型------DLL
项目名称(右键)-----添加-----类------类名与dll工程名一致(EDBFDLL.h)
2.EDBFDLL.h代码:
1 #ifndef EDBFDLL_H 2 #define EDBFDLL_H 3 #pragma once 4 #define LD double 5 #define PI 3.141592654 6 #define Euler 2.71828182845904523536 7 #include "stdafx.h" 8 #include <time.h> 9 #include <stdlib.h> 10 #include <stdio.h> 11 #include <math.h> 12 #include <iostream> 13 #include <iomanip> 14 #include <time.h> 15 #include <fstream> 16 #include <sstream> 17 using namespace std; 18 19 class _declspec(dllexport) EDBFDLL 20 { 21 private: 22 LD Random(); 23 double loge(double x); 24 void OutputScreen(int iterationNum, LD duration); 25 void OpenSpace(int ParentChromosomesNum, int GenesNum, int PullChromosomesNum); 26 27 public: 28 EDBFDLL(); 29 ~EDBFDLL(); 30 struct B 31 { 32 LD * p; 33 LD f; 34 }; 35 LD * a = NULL; 36 B * x = NULL, *new_x = NULL, *new_l_x = NULL; 37 void f(B & x, int n); 38 void f_array(int N, int n, B *&x); 39 int H(B x, int n, LD * GenesLeftLim, LD * GenesRightLim); 40 bool better(B x1, B x2, int n, LD * GenesLeftLim, LD * GenesRightLim); 41 void rand_init_population(int N, int n, B * _x, LD * GenesLeftLim, LD * GenesRightLim); 42 void swap(B &a, B &b); 43 void sort(int N, int n, B * x); 44 void rd(int M); 45 void mrd(int M); 46 void ConstraintLaw(int M); 47 void e_m_p_c(int M, int K, int L, int n, int N, B * _x); 48 void H(int n, int N, int M, int K, int L, B * _x, LD * GenesLeftLim, LD * GenesRightLim); 49 int Recombination(int ParentChromosomesNum, int GenesNum, int PullChromosomesNum, int ElitistParentChromosomesNum, LD * GenesLeftLim, LD * GenesRightLim); 50 clock_t Encoding(int ParentChromosomesNum, int GenesNum, int PullChromosomesNum, int ElitistParentChromosomesNum, LD * GenesLeftLim, LD * GenesRightLim); 51 EDBFDLL::B ED_BF(int ParentChromosomesNum, int GenesNum, int PullChromosomesNum, int ElitistParentChromosomesNum, LD * GenesLeftLim, LD * GenesRightLim); 52 void DeleteSpace(); 53 void Write_to_excel(B * _x, int p, int n, ofstream & outfile); 54 }; 55 #endif展开代码
3.EDBFDLL.cpp代码
1 // EDBFDLL.cpp : 定义 DLL 应用程序的导出函数。 2 // 3 4 #include "stdafx.h" 5 #include "EDBFDLL.h" 6 7 EDBFDLL::EDBFDLL() 8 { 9 } 10 11 12 EDBFDLL::~EDBFDLL() 13 { 14 } 15 16 LD EDBFDLL::Random() 17 { 18 return (LD)rand() / RAND_MAX; 19 } 20 double EDBFDLL::loge(double x) 21 { 22 return log(x) / log(exp(1)); 23 } 24 //fitness function 25 void EDBFDLL::f(B & x, int n)//n present dimension 26 { 27 /*f1*/ 28 /*double val1 = 0; 29 double val2 = 0; 30 for (int i = 0; i < n; i++) { 31 val1 += x.p[i] * x.p[i]; 32 val2 += cos(2 * PI*x.p[i] / 180 * PI); 33 } 34 x.f = ((-20)*exp((-0.2)*sqrt(val1 / n)) - exp(val2 / n) + 20 + exp(1));*/ 35 /*f2*/ 36 //double val = 0; 37 //for (int i = 0; i < n; i++) 38 // val += (x.p[i] * x.p[i]); 39 //x.f=-exp(-0.5*val); 40 /*f3*/ 41 //LD a, s = 0; 42 //for (int i = 0; i<n; i++) 43 //{ 44 // a = x.p[i] * x.p[i] - 10 * cos(2 * PI*x.p[i]); 45 // s += a; 46 //} 47 //x.f = s + 10 * n; 48 /*f4*/ 49 //double val = 0; 50 //for (int i = 0; i < n; i++) 51 // val += x.p[i] * sin(sqrt(abs(x.p[i]))); 52 //x.f=-val; 53 /*f5*/ 54 /*double val1 = 0, val2 = 1; 55 for (int i = 0; i < n; i++) 56 val1 += (loge(x.p[i] - 2)*loge(x.p[i] - 2) + loge(10 - x.p[i])*loge(10 - x.p[i])); 57 for (int i = 0; i < 10; i++) 58 val2 *= x.p[i]; 59 x.f=val1 - pow(val2, 0.2);*/ 60 /*f6*/ 61 /*double val = 0; 62 for (int i = 0; i < n; i++) { 63 val += x.p[i] * x.p[i]; 64 } 65 x.f=val;*/ 66 /*f7*/ 67 double val = 0; 68 for (int i = 0; i < n - 1; i++) { 69 val += 100 * (x.p[i + 1] - x.p[i] * x.p[i])*(x.p[i + 1] - x.p[i] * x.p[i]) + (x.p[i] - 1)*(x.p[i] - 1); 70 } 71 x.f = val; 72 /*f8*/ 73 //double val = 0; 74 //for (int i = 0; i < n; i++) 75 // val += (x.p[i] - i - 1)*(x.p[i] - i - 1); 76 //x.f = val; 77 /*f9*/ 78 //double val1 = 0; 79 //double val2 = 1; 80 //for (int i = 0; i < n; i++) { 81 // val1 += abs(x.p[i]); 82 // val2 = val2*abs(x.p[i]); 83 //} 84 //x.f=(val1 + val2); 85 /*f10*/ 86 //double val = 0; 87 //for (int i = 0; i < n; i++) 88 // val += (i + 1)*x.p[i] * x.p[i]; 89 //x.f = val; 90 } 91 //返回一组适应值 92 void EDBFDLL::f_array(int N, int n, B *&x) 93 { 94 for (int i = 0; i<N; i++) 95 { 96 f(x[i], n); 97 } 98 } 99 100 //若满足约束条件,返回true,否则,返回false 101 int EDBFDLL::H(B x, int n, LD * GenesLeftLim, LD * GenesRightLim) 102 { 103 int i, s = 0; 104 for (i = 0; i<n; i++) 105 { 106 if (x.p[i] >= GenesLeftLim[i]) 107 s += 1; 108 if (x.p[i] <= GenesRightLim[i]) 109 s += 1; 110 } 111 return s; 112 } 113 bool EDBFDLL::better(B x1, B x2, int n, LD * GenesLeftLim, LD * GenesRightLim) 114 { 115 int h1, h2; 116 LD f1, f2; 117 h1 = H(x1, n, GenesLeftLim, GenesRightLim); 118 h2 = H(x2, n, GenesRightLim, GenesRightLim); 119 f1 = x1.f; 120 f2 = x2.f; 121 if (h1<h2) 122 return false; 123 else if (h1>h2) 124 return true; 125 if (f1<f2) 126 return true; 127 return false; 128 } 129 //返回在搜索空间中随机产生满足约束条件的初始群体,t=0 130 void EDBFDLL::rand_init_population(int N, int n, B * _x, LD * GenesLeftLim, LD * GenesRightLim)//N presents the population size, n peresents the dimension 131 { 132 int i, j; 133 for (i = 0; i<N; ++i) 134 { 135 for (j = 0; j<n; j++) 136 { 137 _x[i].p[j] = Random()*(GenesRightLim[j] - GenesLeftLim[j]) + GenesLeftLim[j]; 138 } 139 } 140 } 141 void EDBFDLL::swap(B &a, B &b) 142 { 143 B temp = a; 144 a = b; 145 b = temp; 146 } 147 void EDBFDLL::sort(int N, int n, B * x) 148 { 149 for (int i = 0; i<N - 1; i++) 150 { 151 for (int j = 0; j<N - 1 - i; j++) 152 { 153 if (x[j].f>x[j + 1].f) 154 { 155 swap(x[j], x[j + 1]); 156 } 157 } 158 } 159 } 160 void EDBFDLL::rd(int M) 161 { 162 LD s, g = 4; 163 while (g>1.5 || g<-0.5) 164 { 165 s = 0; 166 for (int i = 0; i<M - 1; i++) 167 { 168 a[i] = Random() * 2 - 0.5; 169 s += a[i]; 170 } 171 g = 1 - s; 172 } 173 a[M - 1] = g; 174 } 175 //从[-0.5,1.5]中随机产生M个数,使得这M个数和为1 176 void EDBFDLL::mrd(int M) 177 { 178 LD s1 = -0.8586*powf(M, -0.9424) + 0.6115; 179 LD s2 = 0.5802*powf(M, -0.8598) + 0.3443; 180 int i; 181 LD s, g = 4, fld; 182 while (g>1.5 || g<-0.5) 183 { 184 s = 0; 185 for (i = 0; i<M - 1; i++) 186 { 187 fld = Random(); 188 if (fld <= s1) 189 a[i] = Random()*0.5 - 0.5; 190 else if (fld <= s1 + s2) 191 a[i] = Random(); 192 else 193 a[i] = Random()*0.5 + 1; 194 s += a[i]; 195 } 196 g = 1 - s; 197 } 198 a[M - 1] = g; 199 } 200 void EDBFDLL::ConstraintLaw(int M) 201 { 202 LD s, S, Last_Coeffient = 2, num = 0, t_low, t_up, b_low, b_up; 203 int r; 204 a[0] = Random() * 2 - 0.5; 205 206 while (Last_Coeffient <= -0.5 || Last_Coeffient >= 1.5) 207 { 208 num++; 209 S = s = 0; 210 for (int i = 1; i < M - 1; i++) 211 { 212 s += a[i - 1]; 213 t_low = -0.5 - s; 214 t_up = 1.5 - s; 215 b_low = t_low >= -0.5 ? t_low : -0.5; 216 b_up = t_up <= 1.5 ? t_up : 1.5; 217 a[i] = Random()*(b_up - b_low) + b_low; 218 } 219 S = s + a[M - 2]; 220 a[M - 1] = Last_Coeffient = 1 - S; 221 } 222 } 223 //精英多父体杂交 224 void EDBFDLL::e_m_p_c(int M, int K, int L, int n, int N, B * _x) 225 { 226 int i, j, l; 227 LD S; 228 229 //从种群中选择K个最好的个体 230 for (i = 0; i<K; i++) 231 { 232 new_x[i] = _x[i]; 233 } 234 //另外M-K个个体从种群中随机选取 235 for (i = 0; i<M - K; i++) 236 { 237 int t = rand() % N; 238 while (t<K) 239 { 240 t = rand() % N; 241 } 242 new_x[i + K] = _x[t]; 243 } 244 //由这M个个体张成子空间 245 for (l = 0; l<L; l++) 246 { 247 mrd(M); 248 //ConstraintLaw(M); 249 for (i = 0; i<n; i++) 250 { 251 S = 0; 252 for (j = 0; j<M; j++) 253 { 254 S += new_x[j].p[i] * a[j]; 255 } 256 new_l_x[l].p[i] = S; 257 } 258 } 259 //返回L个个体中最好的个体 260 f_array(L, n, new_l_x); 261 sort(L, n, new_l_x); 262 } 263 //每执行一次H函数,就为一代 264 void EDBFDLL::H(int n, int N, int M, int K, int L, B * _x, LD * GenesLeftLim, LD * GenesRightLim) 265 { 266 B best, worst; 267 worst = _x[N - 1]; 268 e_m_p_c(M, K, L, n, N, _x); 269 best = new_l_x[0]; 270 if (better(best, worst, n, GenesLeftLim, GenesRightLim)) 271 { 272 for (int i = 0; i<n; i++) 273 { 274 _x[N - 1].p[i] = best.p[i]; 275 } 276 _x[N - 1].f = best.f; 277 } 278 sort(N, n, _x); 279 } 280 void EDBFDLL::Write_to_excel(B * _x, int p, int n, ofstream & outfile) 281 { 282 283 for (int i = 0; i<p; i++) 284 { 285 for (int j = 0; j<n; j++) 286 outfile << setiosflags(ios::fixed) << setprecision(14) << _x[i].p[j] << ","; 287 outfile << _x[i].f << endl; 288 } 289 290 } 291 void EDBFDLL::OpenSpace(int ParentChromosomesNum, int GenesNum, int PullChromosomesNum) 292 { 293 int i; 294 try 295 { 296 a = new LD[ParentChromosomesNum]; 297 x = new B[PullChromosomesNum]; 298 new_x = new B[ParentChromosomesNum]; 299 new_l_x = new B[1]; 300 } 301 catch (bad_alloc&memExp) 302 { 303 cerr << memExp.what() << endl; 304 } 305 try 306 { 307 for (i = 0; i<PullChromosomesNum; i++) 308 { 309 x[i].p = new LD[GenesNum]; 310 } 311 for (i = 0; i<ParentChromosomesNum; i++) 312 { 313 new_x[i].p = new LD[GenesNum]; 314 } 315 for (i = 0; i<1; i++) 316 { 317 new_l_x[i].p = new LD[GenesNum]; 318 } 319 } 320 catch (bad_alloc&memExp) 321 { 322 cerr << memExp.what() << endl; 323 } 324 } 325 int EDBFDLL::Recombination(int ParentChromosomesNum, int GenesNum, int PullChromosomesNum, int ElitistParentChromosomesNum, LD * GenesLeftLim, LD * GenesRightLim) 326 { 327 ofstream outfile; 328 outfile.open("result.csv", ios::out); 329 int i = 0; 330 while (fabs(x[0].f - x[PullChromosomesNum - 1].f)>1E-14)//fabs(x[0].f-x[N-1].f)>1E-14 331 { 332 ++i; 333 H(GenesNum, PullChromosomesNum, ParentChromosomesNum, ElitistParentChromosomesNum, 1, x, GenesLeftLim, GenesRightLim); 334 outfile << setiosflags(ios::fixed) << setprecision(14) << x[0].f << endl; 335 } 336 outfile.close(); 337 return i; 338 } 339 clock_t EDBFDLL::Encoding(int ParentChromosomesNum, int GenesNum, int PullChromosomesNum, int ElitistParentChromosomesNum, LD * GenesLeftLim, LD * GenesRightLim) 340 { 341 clock_t start = clock(); 342 srand((unsigned)time(NULL)); 343 OpenSpace(ParentChromosomesNum, GenesNum, PullChromosomesNum); 344 rand_init_population(PullChromosomesNum, GenesNum, x, GenesLeftLim, GenesRightLim); 345 f_array(PullChromosomesNum, GenesNum, x); 346 sort(PullChromosomesNum, GenesNum, x); 347 return start; 348 } 349 void EDBFDLL::OutputScreen(int iterationNum, LD duration) 350 { 351 cout << "程序执行代数:" << iterationNum << "代" << endl;//hj 352 cout << "程序运行时间:" << setiosflags(ios::fixed) << setprecision(4) << duration << "s" << endl; 353 cout << "程序运行结果:" << setiosflags(ios::fixed) << setprecision(16) << x[0].f << endl; 354 } 355 void EDBFDLL::DeleteSpace() 356 { 357 delete[] a; a = NULL; 358 delete[] x; x = NULL; 359 delete[] new_x; new_x = NULL; 360 delete[] new_l_x; new_l_x = NULL; 361 } 362 EDBFDLL::B EDBFDLL::ED_BF(int ParentChromosomesNum, int GenesNum, int PullChromosomesNum, int ElitistParentChromosomesNum, LD * GenesLeftLim, LD * GenesRightLim) 363 { 364 clock_t start = Encoding(ParentChromosomesNum, GenesNum, PullChromosomesNum, ElitistParentChromosomesNum, GenesLeftLim, GenesRightLim); 365 int iterationNum = Recombination(ParentChromosomesNum, GenesNum, PullChromosomesNum, ElitistParentChromosomesNum, GenesLeftLim, GenesRightLim); 366 clock_t finish = clock(); 367 LD duration = (LD)(finish - start) / CLOCKS_PER_SEC; 368 OutputScreen(iterationNum, duration); 369 return x[0]; 370 }展开代码
4.编译(生成----生成解决方案)
编译之后,EDBFDLL.dll文件和EDBFDLL.lib文件在...\EDBFDLL\Debug目录下生成;EDBFDLL.h文件位于...\EDBFDLL\EDBFDLL目录下。
5.调用编译好的EDBFDLL.dll, EDBFDLL.lib和EDBFDLL.h文件
5.1 新建一个Win32控制台应用程序,并分别配置以上文件。
项目名称(右键)-----属性-------配置属性----- C/C++-------常规-------附加包含目录-------录入EDBFDLL.h文件所在的目录。
链接器-------常规-------附加库目录-------录入EDBFDLL.lib文件所在的目录。
链接器-------输入-------附加依赖项-------录入EDBFDLL.lib。
将EDBFDLL.dll拷贝至新项目的...\项目名\Debug目录下。
5.2 调用代码
1 // dlltest.cpp : 定义控制台应用程序的入口点。 2 // 3 #include "stdafx.h" 4 #include "EDBFDLL.h" 5 int main() 6 { 7 EDBFDLL * _EDBF = new EDBFDLL(); 8 LD * GenesLeftLim = new LD[3]; 9 LD * GenesRightLim = new LD[3]; 10 for (int i = 0; i < 3; i++) 11 { 12 GenesLeftLim[i] = -30; 13 GenesRightLim[i] = 30; 14 } 15 EDBFDLL::B optimal = _EDBF->ED_BF(15, 3, 100, 5, GenesLeftLim, GenesRightLim); 16 _EDBF->DeleteSpace(); 17 return 0; 18 }展开代码