matlab实现遗传算法——以Ras函数为例( 初学子 友好子 )

2023-11-19

遗传算法

演化思想

遗传算法的本质

遗传算法的本质=模拟生物演化。具体来说,模拟对象是生物演化中的种种自然现象(如变异,交叉互换,交配,淘汰)。因此,一个优秀的遗传算法首先应该做到生物演化的模拟。但是并非仅仅对生物演化进行简单复现,生物演化中有种种细节可以忽略不计,如DNA非编码段变异,等等

那演化中最重要的部分是什么?

对下一代种群的定向选择。这句话有三个要点,一个是下一代,另一个是定向,最后一个是选择。先说后两者,所谓定向就是人为设定衡量不同个体的可计算指标;而选择则是保留满足指标的个体;最后一点,下一代怎么产生呢?就是遗传,变异和交叉互换。

生物学有关名词这里就不解释了,假设高中生物老师都讲过。

Ras函数

Ras函数(Rastrigin’s Function)是一个典型的非线性多峰函数,具有多个局部的极大值点和极小值点,常规算法很容易陷入局部最优解中。
在n维空间中,Ras函数表达式为:
f ( x ) = A n + ∑ i = 1 n   [ x i 2 − A c o s ( 2 π x i ) ] f(x)=An+\sum_{i=1}^{n}\ [x^{2}_{i}-Acos(2\pi x_{i})] f(x)=An+i=1n [xi2Acos(2πxi)]
其中, A A A是可以人为定义的常量, n n n是Ras函数的维数
n = 2 n=2 n=2时,Ras函数为二维形式,这个函数在 ( 0 , 0 ) (0,0) (0,0)有全局最小值。

下图是 A = 10 , n = 2 A=10,n=2 A=10,n=2时,Ras函数在 x , y ∈ [ − 5 , 5 ] x,y\in[-5,5] x,y[5,5]上的三维图象

hello

遗传算法

目标函数 objective function

%%
% objective function
function ans = ras(A,x) 
    ans = 0;
    for i=1:2
        ans = ans+A+x(i)^2-A*cos(2*pi*x(i));
    end
end
%%

目标函数是Ras函数。计算这个函数需要三个参数,分别是 A A A, x x x, y y y。其中 A A A是我们自行设定的常数,而 x , y x,y xy则对应二维平面上的点
补充:
function------->matlab官方文档-function
fsurf------->matlab官方文档-fsurf

初始化种群 initialization population

% initialization population - binary form
function x = init (pop_size,chromolength)
    x = round(rand(pop_size*2,chromolength));
end
  • 初始种群要足够随机且多样:目的是尽可能扩大搜索范围,找到最优解
  • 染色体长度等于初始种群中每个个体的二进制编码长度

解码 decoding:from binary to decimal

% coding - binary to decimal floating point
function x = decoding(pop)
    [r,c] = size(pop);
    vector = ones(16,1); % 0~65535
    for i=1:c/2
        for j=1:(c/2-i)
            vector(i) = vector(i)*2;
        end
    end
    pop_xy = mat2cell(pop',[c/2 c/2]);
    pop_x = pop_xy{1,1}'*vector;  %1*16
    pop_y = pop_xy{2,1}'*vector; %1*16
    x=[pop_x pop_y]/65535;
end

每个个体由32位二进制数字组成。32位数字从中间划分成两组,前16位表示x,后16位表示y,组合起来代表二维平面上的点。

  • mat2cell的时候注意元胞数组的索引方式
    每个个体与向量 v e c t o r vector vector相乘,可以将16位二进制数转化成十进制数 v e c t o r = [ 2 15 , 2 14 , … , 2 , 1 ] vector=[2^{15} ,2^{14},…,2,1] vector=[215214,,2,1]
    得到的乘积是一个范围落在在 ( 0 , 65535 ) (0,65535) (0,65535)内的整数。为了将这个范围缩小到10附近,再将结果除以6553。
    函数最后输出一个50*2的矩阵,储存50个个体的二维坐标值
    补充:
    mat2cell函数------->matlab官方文档-mat2cell
    ones函数------->matlab官方文档-ones

计算目标函数 calculate the real value

% calculate the real value
function obj = calobjvalue(pop2)
    [r,c] = size(pop2);
    obj = [ ];
    for i=1:r
        for j=1:c
            obj(i) = ras(pop2(i,:));
        end
    end
    obj =obj';  % 1*50 objective value in floating point
end

计算适应度 calculate the fittness value

% calculate the fittness value; range in 0 and 1
function fit = calfitvalue(pop_obj)
    [r,c] = size(pop_obj);
    % calculate the max & min value
    for i=1:r/2 % divide the pop_obj into two sets % 注意对矩阵行列的索引是不是弄反了
        if pop_obj(i) > pop_obj(r+1-i)
            maxSet(i) = pop_obj(i);
            minSet(i) = pop_obj(r+1-i);
        else
            maxSet(i) = pop_obj(r+1-i);
            minSet(i) = pop_obj(i);
        end
    end
    pop_max = maxSet(1);
    pop_min = minSet(1);
    for i=2:r/2 %compare two sets separately
        if maxSet(i) > pop_max
            pop_max = maxSet(i);
        elseif minSet(i) < pop_min
            pop_min = minSet(i);
        end
    end       
    for i=1:r
        fit(i) = 1-(pop_obj(i)-pop_min)/(pop_max-pop_min);
    end
    fit = fit';
end

衡量适应度采用常见归一化方法
X = x − x m i n x m a x − x m i n X = \frac{x-x_{min}}{x_{max}-x_{min}} X=xmaxxminxxmin
如果求解最大值,则 X X X越大,个体适应度越高;
如果求解最小值时,则 ( 1 − X ) (1-X) (1X)的结果越大,个体适应度越高。

选择最优个体 choose the best individual

% best
function best = bestIndividual(pop)
    popDe = decoding(pop);
    obj = calobjvalue(popDe);
    fit = calfitvalue(obj);
    [r,c] = max(fit);
    best = popDe(r,:);
end

选择复制 selection copy

% evolution
function pop = evolutionpop(pop,fitvalue)
    % roulette wheel selection
    fitValue = fitvalue/sum(fitvalue);
    cumFit = cumsum(fitValue); % 工作是不是遗漏了一步
    [r,c] = size(pop);
    for i=1:r
        dartFather = rand; % select father 缺少交配这一步,仅仅是完全保留优秀个体
       % dartMother = rand; % select mother
        j = 1;
        while dartFather > cumFit(j)
            j = j+1;
        end
%         while dartMother >cumFit(k)
%             k = k+1;
%         end    
        popNew(i,:) = pop(j,:);
    end
    pop = popNew;
end

选择复制的思想是每次都保留种群中的优秀个体,逐代提高下一代种群适应度。特别要注意的是,种群适应度的提高的过程一定要 “逐步” ,提高速度太快,种群容易过早陷入局部最优解;提高速度过慢,则迭代次数过多,计算速度慢。
那么,怎样才能体现 逐步 这二字?
答案是,在每一代种群中选择优秀个体的同时,保留一些不那么优秀的个体,为种群提供多样性和可能性。
或者降低交叉互换,基因变异的概率
补充:
轮盘赌-------->轮盘赌算法
cumsum-------->matlab帮助文档-cumsum
进行到这一步,结合计算适应度、计算目标函数、选择最优个体和选择复制,已经可以得到多次演化大致的图象
在这里插入图片描述
图象在前10次迭代里快速向高适应度方向演化,但是在演化10次左右后最小值不再改变,呈现为一条平滑的直线,陷入局部最优解。
用这种不进行交叉互换,不产生基因突变,仅仅依靠选择复制的算法,计算得最优个体为 ( 3.3357 , 3.5710 ) (3.3357 ,3.5710) (3.3357,3.5710)

交叉互换 crossover

function popNew = crossover(pop,pc,fitvalue)
    [r,c] = size(pop);
    fitValue = fitvalue/sum(fitvalue);
    cumFit = cumsum(fitValue);
    for i=1:r
        dart = rand;
        popNew(i,:) = pop(i,:);
        if dart < pc % 选择是否进行交叉互换
            % 选择pop(i,:)的交叉互换对象 pop(j,:)
            dart2 = rand;
            j = 1;
            while dart2 > cumFit(j)
               j = j+1;
            end
             % 确定彼此从哪一位开始交叉互换
            dart3 = (c/2)*rand;
            k = 0;
            while k < dart3
                k = k+1;
            end
            % 进行交叉互换
            for n=1:(k-1)
                popNew(i,n) = pop(i,n);
                popNew(i,n+c/2) = pop(i,n+c/2);
            end
            for m=k:c/2
                popNew(i,m) = pop(j,m);
                popNew(i,m+c/2) = pop(j,m+c/2);
            end
        end
    end
end

从任意位置开始随机选择两个个体交换染色体,进行交叉互换
在这里插入图片描述
交叉互换后得到的解更加逼近于全局最优解,得到的最优个体为 ( 2.5010 , 1.5626 ) ( 2.5010 ,1.5626 ) (2.5010,1.5626)

随机变异 mutation

% mutation
function popNew = mutation(pop,pm)
    % 同比例放大pm与dart
    [r,c] = size(pop);
    dart = rand;
    for i=1:r
        popNew(i,:) = pop(i,:);
        if dart*10 < pm*10 %判断基因是否变异
            % 选择某位进行变异
            dart2 = rand*c;
            k = 0;
            while k < dart2
                k = k+1;
            end
            if popNew(i,k) == 0
                popNew(i,k) = 1;
            else
                popNew(i,k) = 0;
            end
        end
    end
end

在这里插入图片描述
随机选择染色体中某位1变成0,0变成1,得到的最优个体为 ( 0.0012 , 0.9962 ) ( 0.0012 ,0.9962) 0.00120.9962),更加逼近全局最优解。

总代码

clear all;
clc;
pc = 0.8; 				% 交叉互换概率
pm = 0.05;				% 基因变异概率
pop_size = 50; 			% 种群大小
chromolength = 32; 		% 染色体长度
times = 100;			% 迭代次数

pop{1,1} = init(pop_size,chromolength); %产生初始种群
for i=1:times %进行一百次种群演化
    pop2 = decoding(pop{i,1});
    pop_obj = calobjvalue(pop2);
    total(i) = sum(pop_obj);
    pop_fit = calfitvalue(pop_obj);
    pop{i+1,1} = evolutionpop(pop{i,1},pop_fit);
    pop{i+1,1} = crossover(pop{i+1,1},pc,pop_fit);
    pop{i+1,1} = mutation(pop{i+1,1},pm);
end
ret = choosebest(pop{times+1,1})
plot(total/pop_size);
%%
% objective function
function ans = ras(x)
    ans = 0;
    A = 10;
    for i=1:2
        ans = ans+A+x(i)^2-A*cos(2*pi*x(i));
    end
end
%%

%%
% initialization population - binary
function x = init (pop_size,chromolength)
    x = round(rand(pop_size,chromolength)); %产生随机01矩阵
end


% coding - binary to decimal floating point
function x = decoding(pop)
    [r,c] = size(pop);
    vector = ones(c/2,1); % 0~65535
    for i=1:c/2
        for j=1:(c/2-i)
            vector(i) = vector(i)*2;
        end
    end
    pop_xy = mat2cell(pop',[c/2 c/2]);
    pop_x = pop_xy{1,1}'*vector;  %1*16
    pop_y = pop_xy{2,1}'*vector; %1*16
    x=[pop_x pop_y]/6553;;
end
%%

% calculate the real value
function obj = calobjvalue(pop2)
    [r,c] = size(pop2);
    obj = [ ];
    for i=1:r
        for j=1:c
            obj(i) = ras(pop2(i,:));
        end
    end
    obj =obj';  % 1*50 objective value in floating point
end

% calculate the fittness value; range in 0 and 1
function fit = calfitvalue(pop_obj)
    [r,c] = size(pop_obj);
    % calculate the max & min value
    for i=1:r/2 % divide the pop_obj into two sets % 注意对矩阵行列的索引是不是弄反了
        if pop_obj(i) > pop_obj(r+1-i)
            maxSet(i) = pop_obj(i);
            minSet(i) = pop_obj(r+1-i);
        else
            maxSet(i) = pop_obj(r+1-i);
            minSet(i) = pop_obj(i);
        end
    end
    pop_max = maxSet(1);
    pop_min = minSet(1);
    for i=2:r/2 %compare two sets separately
        if maxSet(i) > pop_max
            pop_max = maxSet(i);
        elseif minSet(i) < pop_min
            pop_min = minSet(i);
        end
    end       
    for i=1:r
        fit(i) = 1-(pop_obj(i)-pop_min)/(pop_max-pop_min);
    end
    fit = fit';
end

% evolution
function popNew = evolutionpop(pop,fitvalue)
    % roulette wheel selection
    fitValue = fitvalue/sum(fitvalue);
    cumFit = cumsum(fitValue);
    [r,c] = size(pop);
    for i=1:r
        dartFather = rand; % select father 缺少交配这一步,仅仅是完全保留优秀个体
       % dartMother = rand; % select mother
        j = 1;
        while dartFather > cumFit(j)
            j = j+1;
        end
%         while dartMother >cumFit(k) %其实这里是想模拟母本的……
%             k = k+1;
%         end    
        popNew(i,:) = pop(j,:);
    end
    
end

function popNew = crossover(pop,pc,fitvalue)
    [r,c] = size(pop);
    fitValue = fitvalue/sum(fitvalue);
    cumFit = cumsum(fitValue);
    for i=1:r
        dart = rand;
        popNew(i,:) = pop(i,:);
        if dart < pc % 选择是否进行交叉互换
            % 选择pop(i,:)的交叉互换对象 pop(j,:)
            dart2 = rand;
            j = 1;
            while dart2 > cumFit(j)
               j = j+1;
            end
             % 确定彼此从哪一位开始交叉互换
            dart3 = (c/2)*rand;
            k = 0;
            while k < dart3
                k = k+1;
            end
            % 进行交叉互换
            for n=1:(k-1)
                popNew(i,n) = pop(i,n);
                popNew(i,n+c/2) = pop(i,n+c/2);
            end
            for m=k:c/2
                popNew(i,m) = pop(j,m);
                popNew(i,m+c/2) = pop(j,m+c/2);
            end
        end
    end
end

% mutation
function popNew = mutation(pop,pm)
    % 同比例放大pm与dart
    [r,c] = size(pop);
    dart = rand;
    for i=1:r
        popNew(i,:) = pop(i,:);
        if dart*10 < pm*10 %判断基因是否变异
            % 选择某位进行变异
            dart2 = rand*c;
            k = 0;
            while k < dart2
                k = k+1;
            end
            if popNew(i,k) == 0
                popNew(i,k) = 1;
            else
                popNew(i,k) = 0;
            end
        end
    end
end

% best
function best = bestIndividual(pop)
    obj = calobjvalue(pop);
    best = decoding(pop(1,:));
end

未回答的问题

算法虽好,仍有遗憾

  • 陷入局部最优无法跳出窘境

在这里插入图片描述
上图是迭代一千次的结果,每一个细小尖微的波动都是突变在演化中产生的影响,但是仍没有跳出局部最优的窘境。

沿着哲理的山路

局部最优与全局最优

随机 ≠ \ne = 均匀

退化反而是进化的开始

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

matlab实现遗传算法——以Ras函数为例( 初学子 友好子 ) 的相关文章

  • 计算数组中接下来的 n 个元素的乘积

    我想计算下一个的乘积n矩阵的相邻元素 号码n要相乘的元素数应在函数的输入中给出 例如 对于此输入 我应该从第一个开始计算每 3 个连续元素的乘积 p ind max product 1 2 2 1 3 1 3 这给出了 1 2 2 2 2
  • Matlab - 如果值包含xxx,则删除元胞数组中的行

    在 Matlab 中 如何删除包含变量字符串的元胞数组中的元胞 假设我的元胞数组是 C svnTrunk RadarLib radarlb utilities scatteredInterpolant m C svnTrunk RadarL
  • 如何使用matlab生成不同频率的正弦波?

    对于我的项目 我需要使用 matlab 生成一个正弦波 它有 100 000 个样本 并且频率在每 10 000 个样本后随机变化 采样率和频率可以根据方便而定 matlab中有没有函数可以生成这个 好的另一个例子 生成 5 个随机频率 r
  • 在另一列中添加具有特定条件的一列,如 excel 的 sumif

    我有一个像这样的矩阵 A 1 2 2 3 3 4 4 5 5 6 6 8 7 9 8 5 9 4 现在我想添加第二列 条件是如果 limit 0 interval 3 且 limit limit interval 或者换句话说 当第 1 列
  • MATLAB 中的多个捕获组

    我有一个包含数字或字母的字符串a 可能紧随其后的是r or l 在 MATLAB 中 以下正则表达式返回为 gt gt regexp 10r 0 9 a l r match ans 10r 我希望10 and r分开 因为我有两个捕获组 有
  • 使用mat2cell将MxN的矩阵划分为1xN大小的M矩阵

    我有一个大小为 MxN 的矩阵 比方说 1867x3 1867 行和 3 列 我想将其分成 1867 个大小为 1x3 的单元格 我使用了mat2cell X 1 1866 这里X是矩阵 1867x3 结果给出了两个单元格 一个单元格的大小
  • Matlab:保存后翻转图例顺序和图例重叠图

    我正在尝试根据以下内容反转我的图例条目顺序matlab条形图中图例颜色的逆序 https stackoverflow com questions 31178005 reverse ordering of legend colors in m
  • 在 MATLAB 中重命名文件

    我正在尝试以编程方式重命名工作目录中的文件a temp txt to b hello txt 您建议如何这样做 MATLAB中有一个简单的文件重命名函数吗 我认为您正在寻找 MOVEFILE
  • 如何找到在matlab中重复的矩阵的每一行的索引?

    我想找到矩阵中所有有重复项的行的索引 例如 A 1 2 3 4 1 2 3 4 2 3 4 5 1 2 3 4 6 5 4 3 要返回的向量将是 1 2 4 很多类似的问题建议使用unique函数 我已经尝试过 但我能得到的最接近我想要的功
  • MATLAB 特征函数

    我很好奇哪里可以找到完整的描述FEATURE功能 它接受哪些论点 没有找到文档 我只听说过memstats and getpid 还要别的吗 gt gt which feature built in undocumented 注意 更完整的
  • 如何在 Matlab 中将数组打印到 .txt 文件?

    我才刚刚开始学习Matlab 所以这个问题可能非常基本 我有一个变量 a 2 3 3 422 6 121 9 4 55 我希望将值输出到 txt 文件 如下所示 2 3 3 422 6 121 9 4 55 我怎样才能做到这一点 fid f
  • 有没有办法在matlab中进行隐式微分

    我经常使用 matlab 来帮助我解决数学问题 现在我正在寻找一种在 matlab 中进行隐式微分的方法 例如 我想区分y 3 sin x cos y exp x 0关于dy dx 我知道如何使用数学方法通常做到这一点 但我一直在努力寻找使
  • 通过 Matlab 访问 Physionet 的 ptbdb 中的数据库

    我首先设置系统 old path which rdsamp if isempty old path rmpath old path 1 end 8 end wfdb url http physionet org physiotools ma
  • 访问图像的 Windows“标签”元数据字段

    我正在尝试进行一些图像处理 所以现在我正在尝试读取图像 exif 数据 有 2 个内置函数可用于读取图像的 exif 数据 问题是我想读取图像标签 exifread and imfinfo这两个函数都不显示图像标签 Is there any
  • 如何在文本集中创建所有字符组合?

    例如 我有这样的文本集 第 1 栏 a b 第 2 栏 l m n 第 3 栏 v w x y 我想将它们组合起来以获得如下输出 alv alw alx aly amv amw amx amy 这将输出 24 种文本组合 如果我只使用前两列
  • 了解 fminunc 参数和匿名函数、函数处理程序

    请多多包涵 问题在最后 我试图找出 fminunc 调用方式的差异 这个问题源于 Andrew Ng 在他的 Coursera 机器学习课程中的第 3 周材料 我正在回答这个问题 Matlab Andrew Ng 机器学习课程中 t cos
  • 从开始/结束索引列表创建向量化数组

    我有一个两列矩阵M包含一堆间隔的开始 结束索引 startInd EndInd 1 3 6 10 12 12 15 16 如何生成所有区间索引的向量 v 1 2 3 6 7 8 9 10 12 15 16 我正在使用循环执行上述操作 但我想
  • 在matlab中绘制给定区域内(两个圆之间)的向量场

    我想在 Matlab 中绘制下面的向量场 u cos x x 0 y y 0 v sin x x 0 y y 0 我可以在网格中轻松完成 例如 x 和 y 方向从 2 到 2 x 0 2 y 0 1 x y meshgrid 2 0 2 2
  • 检测分段常数信号中的阶跃

    我有一个分段恒定信号 如下所示 我想检测步骤转换的位置 标记为红色 我目前的做法 使用移动平均滤波器平滑信号 http www mathworks com help signal examples signal smoothing html
  • 读出 Matlab / Octave fft2() 函数输出的特定点

    我正在熟悉 Octave 及其功能fft2 在此玩具示例中 我的目标是生成以下 256 x 256 png 图像的 2D DFT 为了能够轻松理解输出 我尝试将此图像转换为 256 x 256 图像 消除颜色信息 Im imread cir

随机推荐