1. 程式人生 > >遺傳算法學習筆記

遺傳算法學習筆記

wikipedia sig signed 需要 gin AS mat ali 一次

遺傳算法的定義,摘自維基百科:

遺傳算法英語:genetic algorithm (GA) )是計算數學中用於解決最佳化的搜索算法,是進化算法的一種。進化算法最初是借鑒了進化生物學中的一些現象而發展起來的,這些現象包括遺傳、突變、自然選擇以及雜交等。

具體怎麽實現呢?其實也很好理解,給每個對象一個屬性(也就是所謂的基因),再建立一套評判標準,來決定這種基因是好還是壞。為了得到更優化的結果,需要進行若幹次進化。每一輪進化,會選中一些對象來雜交(一般使用輪盤選擇,以保證性質優良的對象有更大概率雜交繁衍,但性質較為不良的也可以得到雜交的機會),再選中一些對象進行突變,以保證屬性的多樣性,最後再淘汰掉一些性質不良的對象,完成一次進化。

本質上和模擬退火這類隨機化算法是類似的,也就是玄學。也就是利用科學化的隨機來逼近問題的最優解。對於不同的問題,需要調整不同的隨機化參數以得到更好的結果。

下面就一個具體的問題來說明一下代碼的編寫:

借鑒的是:遺傳算法實例-求解函數極值,感覺我只是把他翻譯了一下emmmmmm…

f(x)=x+10sin(5x)+7cos(4x)

以上那個函數,求其在區間[-10,10]之間的最大值,不妨先畫一下圖:

技術分享圖片

emmm,抖啊老哥。

代碼如下:

#include<math.h>
#include<string.h>
#include<iostream>
#include
<stdio.h> #include<time.h> #include<algorithm> #include<sstream> //istringstream stm(string); stm >> x; #include<vector> #define INF 2139062143 #define inf -2139062144 #define ll long long #define Num 500 #define Step 5000 using namespace std; // double隨機數生成函數 double doubleram(double
a,double b) { double temp = (double)(rand()%101)/101; return temp * (b - a) + a; } // 整形隨機數生成函數 int intram(int a,int b) { return (rand() % (b-a+1))+ a; } // 個體類 struct indivdual { double x = 0.0,fitness = 0.0; }; bool cmp(indivdual p1, indivdual p2) { return p1.fitness > p2.fitness; } vector<indivdual> indi; // 適應度函數 double fitness(double x) { return x + 10.0 * sin(5.0 * x) + 7.0 * cos(4.0 * x); } // 初始化種群 void initPopulation() { indi.clear(); indivdual temp; for(int i = 0; i < Num; i++) { temp.x = doubleram(-10.0,10.0); temp.fitness = fitness(temp.x); indi.push_back(temp); } } // 雜交過程 void crossover() { int t1 = intram(0,Num-1); int t2 = intram(0,Num-1); indivdual tempvec[4]; tempvec[0] = indi[t1]; tempvec[1] = indi[t2]; indivdual child1,child2; child1.x = indi[t1].x * 0.9 + indi[t2].x * 0.1; // if(child1.x >= 10.0 || child1.x <= -10.0) printf("%llf\n",child1.x); child1.fitness = fitness(child1.x); child2.x = indi[t1].x * 0.1 + indi[t2].x * 0.9; // if(child2.x >= 10.0 || child2.x <= -10.0) printf("%llf\n",child2.x); child2.fitness = fitness(child2.x); tempvec[2] = child1; tempvec[3] = child2; sort(tempvec,tempvec + 4,cmp); indi[t1] = tempvec[0]; indi[t2] = tempvec[1]; } // 變異過程 void mut() { int ind = intram(0,Num - 1); indi[ind].x = doubleram(-10.0,10.0); indi[ind].x = fitness(indi[ind].x); } int main() { srand((unsigned)time(NULL)); // for(int i = 0;i < 10;i++) // printf("%llf\n",ram(-10.0,10.0)); initPopulation(); int t = Step; while(t--) { double x = doubleram(0.0,1.0); if(x < 0.1) { mut(); continue; } if(x < 0.75) { crossover(); continue; } } sort(indi.begin(),indi.end(),cmp); for(int i = 0;i < 5;i++){ printf(" %llf %llf\n",indi[i].x,indi[i].fitness); } return 0; }

遺傳算法學習筆記