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函数为例( 初学子 友好子 ) 的相关文章

  • 为什么 MATLAB 本机函数 cov(协方差矩阵计算)使用与我预期不同的除数?

    给定一个 M 维和 N 个样本的数据矩阵数据 例如 data randn N M 我可以计算协方差矩阵 data mu data ones N 1 mean data cov matrix data mu data mu N 如果我使用原生
  • 从 imread 返回的 ndims

    我正在从文件夹中选取图像 尺寸为128 128 为此 我使用以下代码行 FileName PathName uigetfile jpg Select the Cover Image file fullfile PathName FileNa
  • 如何每次使用按钮将数据添加到 MATLAB 中的现有 XLSX 文件?

    我有一个函数可以生成一些变量 例如分数 对 错 未回答 使用按钮调用此功能 问题是如何每次将函数生成的这些值添加 附加到 XLSX 文件中 或者 如何创建 MAT 文件以便可以添加它 可能的解决方案是什么 附加到 xls 文件所涉及的挑战是
  • 为什么 mex 文件中的 OpenMP 仅产生 1 个线程?

    我是 OpenMP 新手 我有以下代码 使用配置了 MSVS2010 的 Matlab mex 可以正常编译 计算机有 8 个可用处理器 我也使用 matlabpool 检查过 include mex h include
  • 垂直子图的单一颜色条

    我想让下面的 MATLAB 图有一个沿着两个子图延伸的颜色条 像这样的事情 使用图形编辑器手动完成 Note 这与提出的问题不同here https stackoverflow com questions 39950229 matlab t
  • 检查图像中是否有太薄的区域

    我正在尝试验证雕刻机的黑白图像 更多的是剪贴画图像 不是照片 我需要考虑的主要事情之一是区域的大小 或线条的宽度 因为机器无法处理太细的线条 所以我需要找到比给定阈值更细的区域 以此图为例 竖琴的琴弦可能太细而无法雕刻 我正在阅读有关 Ma
  • 如何在Matlab中绘制网络?

    我有一个矩阵AMatlab中的维数mx2每行包含两个节点的标签 显示网络中的直接链接 例如 如果网络有4矩阵的节点A可能A 1 2 1 3 2 1 2 4 3 2 4 1 4 2 其中第一行表示有一个链接来自1 to 2 第二行表示有一个链
  • Matlab:条形图中缺少标签

    使用 Matlab 2012 和 2013 我发现设置XTickLabel on a bar图表最多只能使用 15 个柱 如果条形较多 则标签会丢失 如下所示 绘制 15 个条形图 N 15 x 1 N labels num2str x d
  • FMINCON 的替代方案

    除了 fmincon 之外还有其他更快 更高效的求解器吗 我正在使用 fmincon 来解决特定问题 但对于中等大小的向量变量来说 我的内存不足 我也没有任何超级计算机或云计算选项可供使用 我知道任何替代解决方案仍然会耗尽内存 但我只是想看
  • 如何选择面积最大的对象?

    我用过bwconvhull检测图像的某个部分 正如您在图像中看到的那样 有许多具有特定质心的对象 我想做的是检测面积最大的物体 左起第一个大物体 并忽略其他物体 我应该遵循哪种方法 我将非常感谢您的帮助 以下是代码 由于我仍在努力 所以写得
  • 在 Matlab 中保存 Kinect 深度图像?

    通过使用 Kinect 我可以获得深度图像 其中每个深度图像像素存储相机和物体之间的距离 以毫米为单位 现在我想保存它们以便以后使用 最好的推荐是什么 我正在考虑将深度图像保存为图像 jpg png等 然而 该值通常是从50毫米到10000
  • matlab 中的动画绘图

    我正在尝试创建一个三角形的动画图 最终结果应该是十个三角形 后面跟着两个更大的三角形 后面跟着一条直线 使用matlab文档 https de mathworks com help matlab ref drawnow html 我最终得到
  • MATLAB 变量传递和惰性赋值

    我知道在 Matlab 中 当将新变量分配给现有变量时 会进行 惰性 评估 例如 array1 ones 1 1e8 array2 array1 的价值array1不会被复制到array2除非元素array2被修改 由此我推测Matlab中
  • 帮助我理解FFT函数(Matlab)

    1 除了负频率之外 FFT 函数提供的最小频率是多少 是零吗 2 如果它为零 我们如何在对数刻度上绘制零 3 结果总是对称的 或者只是看起来是对称的 4 如果我使用abs fft y 来比较2个信号 我是否会失去一些准确性 1 除了负频率之
  • Matlab:2行10列的子图

    如何在 matlab 中绘制 20 幅图像 2 行 10 列 我知道我必须使用 子图 功能 但我对给出的参数感到困惑 我尝试给予 子图 2 10 行索引 列索引 但它似乎不起作用 请帮忙 的前两个参数subplot函数分别给出图中子图的总行
  • 优先连接,Matlab 中的复杂网络

    大家好 我现在正在 MATLAB 中研究优先附件模型 在理解以下内容时遇到一些困难 假设我一开始有 4 个节点 连接如下 time 0 1 lt gt 2 3 lt gt 4 在下一个时间步骤中 我添加一个节点和 4 个连接 然后添加另一个
  • 氡变换线检测

    我正在尝试检测灰度图像中的线条 为此 我在 MATLAB 中使用 Radon 变换 我的 m 文件的示例如下所示 我可以使用此代码检测多行 我还使用线条的移位和旋转属性来绘制线条 但是 我不明白在获取rho和theta值后如何获取检测线的起
  • 在 Pari-GP 中嵌套特定递归

    每个人 我最初在 Stackexchange 上发布了类似的问题 它已移至此处 可以在链接中找到 在 Matlab 中声明函数递归序列 https stackoverflow com questions 67146061 declaring
  • MATLAB问题:在图块中引用变量的值[重复]

    这个问题在这里已经有答案了 可能的重复 matlab 绘图标题中的变量 https stackoverflow com questions 5629458 matlab variable in plot title 我想在图中引用 m 文件
  • Matlab strcat 不返回字符串?

    imgstr 无法识别 strcat 的输出字符串 homedir C Users images for img 01 bmp 02 bmp 03 bmp imgstr strcat homedir img I imread imgstr

随机推荐