代碼來源於網絡,寫得非常棒
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 }