经典算法(9)、遗传算法(1):遗传算法简介及基本遗传算法
来源:互联网 发布:diy耳放 淘宝 靠谱么 编辑:程序博客网 时间:2024/05/19 06:35
遗传算法简介
据说,可以用在很多领域。
先学习在函数优化方面的应用。
据说,对于非线性、多模型、多目标的函数优化问题,GA似乎可以得出不错的结果。
“优胜劣汰”。
基本操作:选择、交叉,变异。
每一个基本操作,又有很多种方法。
1. 选择。
根据适应度来选择。在函数优化问题中,为了找最大值,那适应度可以直接定义为f(x0),把某一个个体送入函数,该函数的输出结果。、
(1) 按比例的适应度计算
(2) 基于排序的适应度计算
选择一般有:
(1) 轮盘赌(目前我只知道这个。就像外面搞抽奖活动,一个盘,一根指针。你去转那个盘,最后指针会停在某个扇形上。不过一般都是谢谢惠顾。)
(2) 随机遍历抽样
(3) 局部选择
(4) 截断选择
(5) 锦标赛选择
2. 交叉。
结合父辈的信息,交配产生信的个体。根据个体编码方式不同,可以有:
(1) 实值重组
离散重组
中间重组
线性重组
扩展线性重组
(2) 二进制交叉
单点交叉(我只知道,
多点交叉 这两种)
均匀交叉
洗牌交叉
缩小代理交叉
3. 变异
对子代基因按小概率进行扰动。根据个体编码方式不同,可以有:
(1) 实值变异
(2) 二进制变异(如:对某个个体的二进制编码的某一位取反)
基本遗传算法
用基本遗传算法求一元数量值函数的(近似)最大值。
几个关键点。
1. 个体的初始化是,在区间 [a,b] 上,随机挑一个数。这个随机数可以这样生成。 a + [b - a] / L * n, n是随机的。类似于对连续函数的量化过程(毕竟我是学通信的)。
2. 因为函数比较简单,又是求最大值,所以适应度可以直接把个体往目标函数 f( ) 里面代,返回值就是适应度。
3. 轮盘赌的代码实现可以这样实现。把每一个个体的适应度排在一条直线上,累加起来。(最好把适应度都归到这个区间。不然用轮盘赌的话,一个负数怎么能称为概率?)随机生成[0,1]的数,看落在哪个个体身上,就选它作为以第一代的父亲。为了简单,母亲就任意了(这婚姻也太随意了……)。
4. 如果要求函数f(x)的最小值的话,可以求去找 -f(x) 的最大值。目标函数写成 - f(x) 就好了。
这里贴上书上的代码。上面本来有一些注释,我又加了一点。
Main
clear;close all;clc%%NP = 100;NG = 100;precision = 0.001;prob_cross = 0.9;prob_variation = 0.01;x_low = 0;x_high = 40;[xv,fv] = my_GA1(@fitness,x_low,x_high,NP,NG,prob_cross,prob_variation,precision);[xv,fv]x = x_low:0.01:x_high;for i = 1:length(x) y(i) = fitness(x(i));endplot(x,y)
Main函数里面,调用my_GA1的时候,第一个参数传的是@fitness。fitness是一个函数,@fitness是函数句柄。感觉可以理解为函数指针。
适应度函数(简单起见可以直接选用目标函数)function [ res ] = fitness( x )% function [ res ] = fitness( x )% 这里直接把目标函数当做适应度% 要找f(x) 在区间 [a,b] 上的最大值res = (x^3 - 60 * x^2 + 900 * x + 100);% res = (x - 1) * (x - 2)^2;% res = sin(2*pi*x);% res = -(x^2-20);end基本遗传算法
function [xv,fv]=my_GA1(fitness,a,b,NP,NG,Pc,Pm,eps)L = ceil(log2((b-a)/eps+1)); %根据离散精度,确定二进制编码需要的码长x = zeros(NP,L); % NP个个体,L是二进制编码的长度 % NP行,L列。每个个体用L位二进制代表其基因。for i=1:NP x(i,:) = Initial(L); %种群初始化 % x随便取-_-! % fx 各个个体往目标函数里面代,返回值 fx(i) = fitness(Dec(a,b,x(i,:),L)); %个体适应值 --> 可以把个体往目标函数里面代 -_-! endfx = fx - min(fx); %%%%%%%%%%%%%%% 调整为全是正数!for k=1:NG % 一共产生NG代 sumfx = sum(fx); %所有个体适应值之和 Px = fx/sumfx; %所有个体适应值的平均值 --> 不是平均值啊,是各个个体适应度的比例,个体的选择概率 PPx = 0; PPx(1) = Px(1); % 这是累计概率 for i=2:NP %用于轮盘赌策略的概率累加 PPx(i) = PPx(i-1) + Px(i); end for i=1:NP % 轮转NP次,相当于是生了N个孩子 theta = rand(); % 每次轮转,就产生一个(0,1)的数,看落在哪个范围 for n=1:NP if theta <= PPx(n) % 累计范围 --> 这种写法相当于是NP个if… -_-! SelFather = n; %根据轮盘赌策略确定的父亲 break; end end Selmother = floor(rand()*(NP-1))+1; %随机选择母亲(这段婚姻真随意,甚至会出现“自交”???自己和自己交配。。。?) posCut = floor(rand()*(L-2)) + 1; %随机确定交叉点 r1 = rand(); if r1<=Pc % 以一定的概率,发生交叉 %交叉 nx(i,1:posCut) = x(SelFather,1:posCut); % 这种交叉的方法是,用父亲的前posCut & 母亲的后 posCut 相结合 nx(i,(posCut+1):L) = x(Selmother,(posCut+1):L); r2 = rand(); if r2 <= Pm % 以一定的概率,发生变异 %变异 posMut = round(rand()*(L-1) + 1); % 变异的位置 这里是 1位 nx(i,posMut) = ~nx(i,posMut); % 这里的变异就是,某一位取反 end else nx(i,:) = x(SelFather,:); % 如果不交叉,子代染色体就是父代 end end x = nx; % 新的个体,重新赋值给了x for i=1:NP fx(i) = fitness(Dec(a,b,x(i,:),L)); %子代适应值 end fx = fx - min(fx); %%%%%%%%%%%%%%% 调整为全是正数! end% 最后,在最终一代里面选,最佳适应的那个个体fv = -inf;for i=1:NP fitx = fitness(Dec(a,b,x(i,:),L)); if fitx > fv fv = fitx; %取个体中的最好值作为最终结果 xv = Dec(a,b,x(i,:),L); end endfunction result = Initial(len) %初始化函数for i=1:len r = rand(); % X = rand returns a single uniformly % distributed random number % in the interval (0,1). result(i) = round(r); endfunction y = Dec(a,b,x,L) %二进制编码转换为十进制编码base = 2.^((L-1):-1:0);y = dot(base,x);y = a + y*(b-a)/(2^L-1);
近似最大值点是 x = 10.0038,近似最大值是 fv = 4.1000e+03
为了求最小值,把适应度函数前面填个负号。
res = - (x^3 - 60 * x^2 + 900 * x + 100);
然后,输出结果的时候,[xv,-fv] 就代表最小值点和最小值了。
然后,输出结果的时候,[xv,-fv] 就代表最小值点和最小值了。
29.9992 100.0000
有个问题,这是一种概率的办法,所以就算参数相同,每次出来的结果也可能不一样 -_-!!
当然,基本算法肯定很简单,只是为了入门学习一下。以后再慢慢改善、完善。
说明
生成的每一代的每一个个体,都按一定的概率发生交叉和变异。
如果没有交叉,那下一代就先用父亲的基因,再去考虑是否要变异。
0 0
- 经典算法(9)、遗传算法(1):遗传算法简介及基本遗传算法
- (五)遗传算法
- 遗传算法(GA)
- 遗传算法(一)
- 遗传算法(一)
- 遗传算法简介
- 遗传算法简介
- 遗传算法简介
- 遗传算法简介
- 遗传算法简介
- 遗传算法简介
- <转>遗传算法简介
- 遗传算法
- 遗传算法
- 遗传算法
- 遗传算法
- 遗传算法
- 遗传算法
- opencv:log()函数
- python 基础 —— 获取文件路径
- 临时表空间组+好处
- Android studio的安装及环境配置
- Hadoop之HDFS原理及文件上传下载源码分析(下)
- 经典算法(9)、遗传算法(1):遗传算法简介及基本遗传算法
- opencv:矩阵归一化—normalize()函数
- 复制文本的四种方法
- 布局
- SqlCommand 类读取SqlDataReader数据动态创建DataTable
- 推箱子
- Android Framework:Binder(2)-Service Manager
- 告知你不为人知的UDP-疑难杂症和使用
- jsp+servlet 练习