遗传算法学习笔记

遗传算法的定义,摘自维基百科:

遗传算法英语: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;
}

猜你喜欢

转载自www.cnblogs.com/zinyy/p/9139147.html