遗传算法的定义,摘自维基百科:
遗传算法(英语: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 ",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 ",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 ",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 ",indi[i].x,indi[i].fitness); } return 0; }