遗传算法了解

随机算法---遗传算法

遗传算法( Genetic Algorithms,GA) 是在1975 年首次由美国密西根大学的D。J。Holland 教授和他的同事们借鉴生物界达尔文的自然选择法则和孟德尔的遗传进化机制基础之上提出的。经过近30年的研究、应用,遗传算法已被广泛地应用于函数优化、机器人系统、神经网络学习过程、模式识别、图象处理、工业优化控制等领域。

遗传算法是将问题的每一个可能性解看作是群体中的一个个体(染色体),并将每一个染色体编码成串的形式,再根据预定的目标函数对每个个体进行评价,给出一个适应值。算法将根据适应度值进行它的寻优过程,遗传算法的寻优过程是通过选择、杂交和变异三个遗传算子来具体实现的。它的搜索能力由选择算子和杂交算子决定,变异算子则保证了算法能够搜索到问题空间的尽可能多的点,从而使其具有搜索全局最优的能力。要使遗传算法有效工作必须按照遗传算法的模式定理(或积木块假设) 根据具体问题设计合理的编码方案。

在运行遗传算法程序时,需要对一些参数作事先选择,它们包括种群的大小、染色体长、交叉率、变异率、最大进化代数等,这些参数对GA 的性能都有很重要的影响。在试验中参数一般选取如下:种群大小N= 20~100 ,交叉概率 = 0.4 ~0.9 ,变异概率 = 0.001~0.1 ,最大进化代数maxgen = 100~500。

遗传算法是具有“生成+检测”的迭代过程的搜索算法。它的基本处理流程如图1所示。

图1、遗传算法的基本流程

遗传算法的基本流程描述如下:

(1)编码:将解空间的解数据进行二进制编码,表达为遗传空间的基因型串(即染色体)结构数据,如将数据9编码为“1001”;

(2)初始化种群:定义整数pop_size作为染色体的个数,并且随机产生pop_size个染色体作为初始种群;

(3)评估种群中个体适应度:评价函数对种群中的每个染色体(chromosome)求得其个体适应度;

(4)选择:选择把当前群体中适应度较高的个体按某种规则或者模型遗传到下一代种群中,这里所用的规则是:染色体在种群中被选择的可能性与其个体的适应度的大小成正比;

(5)交叉:定义参数作为交叉操作的概率,由(4)选择得到的两个个体以概率交换各自的部分染色体,得到新的两个个体;

(6)变异:定义参数作为变异操作的概率,由(5)得到每个个体中的每个基因值都以概率进行变异;

(7)演化:经过选择、交叉和变异操作,得到一个新的种群,对上述步骤经过给定的循环次数(maxgen)的种群演化,遗传算法终止。

/*
用遗传算法求y=x*sin(10*pi*x)+2的最大值  -1=<x<=2
精确到6位小数
pow(2,21)<3*1000000<pow(2,22)
编码的二进制长度为22
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>

#define N 3000000
#define PI 3.14159265
#define MAX(a,b) ((a)>(b)?(a):(b))

#define SIZE  50
#define MAXGEN  50
#define P_CORSS 0.75
#define P_MUTATION 0.05

#define LEN 22

typedef struct node
{
    char x[LEN];
    double fitness,fitsum;
} node;

node cur[SIZE],next[SIZE],max,min;

double randd()
{
    return (double)rand()/RAND_MAX;
}
int randi(int k)
{
    return (int)(randd()*k+0.5);
}

//计算当前种群中各个个体的适应度
void cal_fitness()
{
    int i,j,k;
    double d;
    for(i=0; i<SIZE; i++)
    {
        k=0;
        for(j=LEN-1; j>=0; j--) k=(k<<1)+cur[i].x[j];
        d=(double)k/N*3-1;
        cur[i].fitness=d*sin(10*PI*d)+2;
        cur[i].fitsum=i>0?(cur[i].fitness+cur[i-1].fitsum):(cur[0].fitness);
    }
}

void init()
{
    int tmp;
    for(int i=0; i<SIZE; i++)
    {
        tmp=randi(N);
        for(int j=0; j<LEN; j++)
        {
            cur[i].x[j]=tmp%2;
            tmp=tmp>>1;
        }
    }
    cal_fitness();
}

int sel()
{
    double p=randd();
    double sum=cur[SIZE-1].fitsum;
    for(int i=0; i<SIZE; i++)
    {
        if(cur[i].fitsum/sum>p) return i;
    }
}

//换代
void tran()
{
    int i,j,pos;
    //找当前种群最优个体
    max=cur[0];
    for(i=1; i<SIZE-1; i++)
    {
        if(cur[i].fitness>max.fitness)  max=cur[i];
    }
    for(int k=0; k<SIZE; k+=2)
    {
        //选择交叉个体
        i=sel();
        j=sel();

        //选择交叉位置
        pos=randi(LEN-1);

        //交叉
        if(randd()<P_CORSS)
        {
            memcpy(next[k].x,cur[i].x,pos);
            memcpy(next[k].x+pos,cur[j].x+pos,LEN-pos);

            memcpy(next[k+1].x,cur[j].x,pos);
            memcpy(next[k+1].x+pos,cur[i].x+pos,LEN-pos);
        }
        else
        {
            memcpy(next[k].x,cur[i].x,LEN);
            memcpy(next[k+1].x,cur[j].x,LEN);
        }
        //变异
        if(randd()<P_MUTATION)
        {
            pos=randi(LEN-1);
            next[k].x[pos]^=next[k].x[pos];

            pos=randi(LEN-1);
            next[k+1].x[pos]^=next[k+1].x[pos];
        }
    }
    //找下一代的最差个体
    min=next[0],j=0;
    for(i=1; i<SIZE-1; i++)
    {
        if(next[i].fitness<min.fitness)  min=next[i],j=i;
    }
    //用上一代的最优个体替换下一代的最差个体
    next[j]=max;

    memcpy(cur,next,sizeof(cur));

    cal_fitness();
}

//打印个体适应度和二进制编码
void print(node tmp)
{
    printf("%.6lf",tmp.fitness);
    for(int i=0; i<LEN; i++)  printf(" %d",tmp.x[i]);
    printf("\n");
}

//打印种群
void printcur()
{
    for(int i=0; i<SIZE; i++) print(cur[i]);
}

void GA()
{
    int cnt=0;
    double ans;
    while(cnt++<MAXGEN)
    {
        tran();

//    printf("%.6lf\n",max.fitness);
//    printcur();
    }
    ans=cur[0].fitness;
    for(int i=1; i<SIZE; i++) ans=MAX(ans,cur[i].fitness);
    printf("%.6lf\n",ans);
}

int main()
{
    srand((unsigned)time(NULL));

        init();
        GA();
    return 0;
}

时间: 2024-12-10 23:05:11

遗传算法了解的相关文章

多目标遗传算法 ------ NSGA-II (部分源码解析) 交叉操作 crossover.c

遗传算法中的交叉操作是 对NSGA-II  源码分析的  最后一部分, 这一部分也是我 从读该算法源代码和看该算法论文理解偏差最大的  函数模块. 这里,首先提一下,遗传算法的  交叉操作.变异操作都是需要设定概率的, 即交叉概率和变异概率. 假设种群个体 大小为  popsize ,  那么交叉操作需要进行 popsize/2 次 ,   变异操作需要进行 popsize 次, 其中每次操作的时候都需要随机生成一个随机数来与给定的概率进行判断,若小于给定的概率则继续执行否则退出该操作. 如果继

用遗传算法GA改进CloudSim自带的资源调度策略(2)

遗传算法GA的核心代码实现: 最核心: private static ArrayList<int[]> GA(ArrayList<int[]> pop,int gmax,double crossoverProb,double mutationRate) { HashMap<Integer,double[]> segmentForEach=calcSelectionProbs(pop); ArrayList<int[]> children=new ArrayL

遗传算法在JobShop中的应用研究(part3:交叉)

2.交叉 交叉是遗传算法中的一个重要操作,它的目的是从两条染色体中各自取出一部分来组合成一条新的染色体这里,在车间调度中一种常见的交叉方法叫Generalized Order Crossover方法(GOX),假设有三个工件A,B,C, 每个工件下面包含三道工序,根据这一信息我们可以利用上一节介绍的编码技术随机生成两条染色体如下: 我们可以用一个list来存储一条染色体, 这个list中的每个元素是一个有序偶,有序偶的第一个元素是工件号,第二个元素是工序号. Parent1用list可以表示为[

遗传算法在JobShop中的应用研究(part 1)

1. 什么是JobShop问题 Job,中文翻译成工件.一个工件又由若干道工序加工完成. resource, 资源.在本文的车间调度中资源指的是机器,每道工序要在某个特定机器上加工. Constraint, 约束.在车间调度中约束主要有以下两种: 同一个工件包含的工序有先后顺序. 每个机器不能同时处理两道工序,因此这台机器上完成工序时要串行,不能并行. Objective,目标.JobShop问题的一个常见目标是使所有工件完成的总时间最小,这个总时间英语叫做Makespan. 一个JobShop

用遗传算法解八皇后问题

此算法收敛速度还可以,基本在1万代之内就能找到解 主程序 clear; clc; %% %八皇后问题,8X8的棋盘上,放置8个皇后,使之两两都不能攻击 %初始的状态,随机在棋盘上放置8个皇后,每列放一个 n = 8; %8皇后 %% %用遗传算法计算 %先随机获得几个个体,形成一个种群 %这个种群有10个个体 No_of_people = 10; people = randi(n,[No_of_people,n]); %计算每个初始种群的h值 people_h = ones(No_of_peop

如何通俗易懂地解释遗传算法?有什么例子?

遗传算法,核心是达尔文优胜劣汰适者生存的进化理论的思想. 我们都知道一个种群,通过长时间的繁衍,种群的基因会向着更适应环境的趋势进化,牛B个体的基因被保留,后代越来越多,适应能力低个体的基因被淘汰,后代越来越少.经过几代的繁衍进化,留下来的少数个体,就是相对能力最强的个体了. 那么在解决一些问题的时候,我们能不能学习这样的思想,比如先随机创造很多很多的解,然后找一个靠谱的评价体系,去筛选比较好的解,再用这些好的解像生小宝宝一样生一堆可能更好的解,然后再筛再生,反复弄个几代,得到的说不定就是近似最

遗传算法优化BP神经网络——非线性函数拟合

遗传算法基本的操作分为: 1.选择操作 2.交叉操作 3.变异操作 遗传算法的基本要素包括染色体编码方法.适应度函数.遗传操作和运行参数. 遗传算法优化BP神经网络算法流程如图3-4所示:

很好的理解遗传算法的样例

遗传算法的手工模拟计算演示样例 为更好地理解遗传算法的运算过程,以下用手工计算来简单地模拟遗传算法的各    个主要运行步骤.       例:求下述二元函数的最大值: (1) 个体编码           遗传算法的运算对象是表示个体的符号串,所以必须把变量 x1, x2 编码为一种       符号串.本题中,用无符号二进制整数来表示.           因 x1, x2 为 0 ~ 7之间的整数,所以分别用3位无符号二进制整数来表示,将它       们连接在一起所组成的6位无符号二进制

基于遗传算法的高校排课系统研究

基于遗传算法的高校排课系统研究 沈丽容  陈明磊 (南京林业大学信息学院计算机科学与工程系  南京 210037)     摘  要   提出并实现了一种高校自动排课算法,利用遗传算法建立数据模型,定义一个包含教师编号.班级编号.课程编号.教室编号.上课时间段的染色体编码方案和适应度函数,通过初始化种群.选择.交叉.变异等过程不断进化,最后得到最优解.利用该算法对某高校的真实数据进行实验,结果显示无一例教室.教师.班级冲突,算法具有合理性和可行性.     关键词  遗传算法: 排课问题: 适应

基于遗传算法求解TSP问题(Java界面)

近期为做展示,改写了一个遗传算法求TSP的Java界面版,思路代码和 http://blog.csdn.net/wangqiuyun/article/details/12838903 这篇文章思路是一样的,追加了Java用Graphics画点及画线做路径展示,展示部分做得比較粗糙,须要的拿走,效果图例如以下. 下载地址:http://download.csdn.net/detail/wangqiuyun/7406201 另C#界面版:http://blog.csdn.net/wangqiuyun