改进遗传算法的参数反演--实例复现(详细注释)

2023-11-08

目录

主函数:

计算适应度大小:

选择操作(论文中的竞争选择法,锦标赛选择法):

 交叉操作(论文中的离散交叉法):

变异操作(论文中的非均匀变异法):

生成测试数据

某次运行结果:

​​​​​​​

主函数:

%% 清除变量,导入数据
clear, clc;
load('Data_Create_For_Test.mat');
Data_real = Data_Create;

% 如果想导入EXCEL的数据,请注释掉上面两段代码,使用下面的一段代码
% Data_real = xlsread('Data_Create_For_Test.xlsx'); %导入EXCEL表格的真实数据
%% 初始化参数
Pc = 0.8; %交叉概率
Pm = 0.01; %变异概率
iter_max = 200; %最大进化代数,即最大迭代次数
iter = 1; %初始化进化代数,即当前迭代次数
N_chrom = 20; %种群染色体的数目,解的个数
N_gen = 3; %染色体基因的数目,自变量的个数(表示论文里需反演的三个参数Alpha, Beta, S)
Up_gen = [0.5; 0.01; 0.01]; %三个基因的上界取值范围(三个参数的取值范围, 根据实际情况设定) 
Down_gen = [0; 0; 0]; %三个基因的下界取值范围

%% 生成初始解
chrom = zeros(N_chrom, N_gen); %初始化染色体矩阵(解集)
for i = 1 : N_chrom %初始化N_chrom组的参数值
    chrom(i, 1) = Down_gen(1) + rand(1) * (Up_gen(1) - Down_gen(1)); %初始化Alpha(i)
    chrom(i, 2) = Down_gen(2) + rand(1) * (Up_gen(2) - Down_gen(2)); %初始化Beta(i)
    chrom(i, 3) = Down_gen(3) + rand(1) * (Up_gen(3) - Down_gen(3)); %初始化S(i)
end

fitness = zeros(N_chrom, 1); %初始化适应度矩阵(每一个解对应的适应度大小)
for i = 1 : N_chrom
    fitness(i) = CalFitness(Data_real, chrom(i, : ));  %计算每一个初始解对应的适应度大小
end

fitness_best = zeros(iter_max, 1); %初始化每一代的最优适应度大小
for i = 1 : iter_max
    fitness_best(i) = inf;   %初始化为无穷大
end

chrom_best = zeros(iter_max, N_gen); %初始化每一代的最优染色体


%% 进化迭代
[row, line] = size(chrom); %初始化选择操作中父本和母本的对数
dad_mom = zeros(2 * row, line);    %初始化父本和母本,这里奇数行号认为是父本,偶数行号认为是母本
New_chrom = zeros(2 * row, line);  %初始化交叉操作生成的新种群
for iter = 1 : iter_max
%% 选择操作(论文中的竞争选择法,锦标赛选择法)
    dad_mom = Selection(chrom, fitness);
    
%% 交叉操作(论文中的离散交叉法)
    New_chrom = Cross(dad_mom, Pc);
    
%% 变异操作(论文中的非均匀变异法)
    New_chrom = Mutation(New_chrom, Up_gen, Down_gen, iter, iter_max, Pm);

%% 计算新种群的适应度大小    
    [row, line] = size(New_chrom);
    New_fitness = zeros(row, line);
    for i = 1 : row
        New_fitness(i) = CalFitness(Data_real, New_chrom(i, : )); %计算每一个新染色体的适应度大小
        if New_fitness(i) < fitness_best(iter) %判断当前新染色体的适应度,是否优于本迭代次数的最优适应度
            fitness_best(iter) = New_fitness(i); %判断结果为是,则更新当前迭代次数的最优适应度
            chrom_best(iter, : ) = New_chrom(i, : ); %同时更新最优染色体
        end
    end
    
    if ( (iter ~= 1) && ( fitness_best(iter - 1) < fitness_best(iter) ) )
        fitness_best(iter) = fitness_best(iter - 1); %记录截止到当前迭代次数,最优的适应度大小
        chrom_best(iter, : ) = chrom_best(iter - 1, : ); %记录截止到当前迭代次数,最优的适应度对应的最优染色体
    end
 
%% 形成新的种群,用于下一次迭代(自然选择)
    Sort_fitness = sort(New_fitness); %排序新种群的适应度(注意这里适应度值的个数是N_chrom的两倍)
    for i = 1 : (row/2)
        index = find(New_fitness == Sort_fitness(i), 1);
        chrom(i, : ) = New_chrom(index, : );  %取适应度排名前50%的染色体,作为下一次迭代的新种群,这里可以理解为自然选择操作
    end
end

%% 绘图
figure(1)
plot(1:iter_max, fitness_best, 'r');
title('迭代图')
xlabel('迭代次数')
ylabel('适应度大小')
    
%% 输出结果
disp(['最优适应度:' num2str( fitness_best(iter) )])
disp(['Alpha最优参数值:' num2str( chrom_best(iter, 1) )]) 
disp(['Beta最优参数值:' num2str( chrom_best(iter, 2) )]) 
disp(['S最优参数值:' num2str( chrom_best(iter, 3) )]) 

计算适应度大小:

%% 计算适应度大小
function Fitness_Chrom = CalFitness(Data_real, chrom) 
%输入:真实观测数据Data_real(两列),包括时间t(第一列数据)和真实水位抬升值s(第二列数据)
%      染色体解集chrom(三列,分别代表三个参数alpha,beta,S)
%输出:适应度大小

M = 60; %含水层厚度
Q = 58; %定流量
r = 0.1; %井径
A = Q / (4 * pi * M); %论文中的斜率A
B = A * log( 2.25*M / (r*r) ); %论文中的截距B

Data_t = Data_real(:, 1); %取第一列数据,即时间t
Data_s = Data_real(:, 2); %取第二列数据,即观测到的真实水位抬升值s
Alpha = chrom(:, 1); %取第一列数据,即参数alpha
Beta = chrom(:, 2);  %取第二列数据,即参数Beta
S = chrom(:, 3);     %取第三列数据,即参数S

Data_num = size(Data_s, 1); %计算真实观测数据的数目
Error_sum = 0; %总误差的平方和,即优化目标
X = zeros(Data_num, 1);

for j = 1 : Data_num
    X(j) = -1*Beta*Data_t(j) + log( Alpha*Data_t(j) ) - log( S );  %计算时刻t(i)对应的X(i)
    error = Data_s(j) - ( A*X(j)+B ) / ( Alpha * exp( -1*Beta*Data_t(j) ) ); %计算时刻t(i)对应的误差(s-s*)
    Error_sum = Error_sum + abs(error * error); %计算总误差的平方和
end
    
Fitness_Chrom = Error_sum; %记录染色体(一组参数)对应的优化目标值

选择操作(论文中的竞争选择法,锦标赛选择法):

function dad_mom = Selection(chrom, fitness)
%% 选择操作(竞争选择法,锦标赛选择法)
% 输入:染色体种群, 适应度矩阵 
% 输出:选择操作得到的父本和母本(用于交叉操作)

sn = 3; %从种群中选择的个体数目,进行竞争
[row, line] = size(chrom); %选择父本和母本的对数
dad_mom = zeros(2 * row, line); %初始化父本和母本,这里奇数行号认为是父本,偶数行号认为是母本

for i = 1 : 2 : 2*row   %间距为2
    r = randi([1 row], sn, 1); %从[1,sum]中随机生成sn个整数,即随机抽出来进行比赛的个体编号
    index = find(fitness == min(fitness(r)), 1); %在进行比赛的个体中,找到适应度最优的个体编号,即在原种群chrom中对应的编号
    dad_mom(i, : ) = chrom(index, : ); %将比赛胜出者作为父本
    dad_mom(i+1, : ) = chrom(randi([1, row]), : ); %随机选择一个个体作为母本
end

 交叉操作(论文中的离散交叉法):

function New_chrom = Cross(dad_mom, pc)
%% 交叉操作(离散交叉法)
%输入:选择操作得到的父本和母本;交叉概率
%输出:交叉操作后的新种群(子本)
[row, line] = size(dad_mom);
New_chrom = zeros(row, line); %初始化交叉操作的新种群
for i = 1 : 2 : row
    if rand < pc  %生成一个随机数,判断是否进行交叉操作
        for j = 1 : line %进行交叉操作
            if randi([0, 1]) == 1 %随机数为1,则对应基因不进行交叉操作
                New_chrom(i, j) = dad_mom(i, j);
                New_chrom(i+1, j) = dad_mom(i+1, j);
            else                  %随机数为0,则相邻两个个体(即父本和母本),进行相应基因的交叉操作(互换基因)
                New_chrom(i, j) = dad_mom(i+1, j);
                New_chrom(i+1, j) = dad_mom(i, j);
            end
        end
    else          %不进行交叉操作
        New_chrom(i, : ) = dad_mom(i, : ); %子代保持不变
        New_chrom(i, : ) = dad_mom(i+1, :); %子代保持不变
    end
end

变异操作(论文中的非均匀变异法):

function New_chrom = Mutation(Cross_chrom, Up_gen, Down_gen, iter, iter_max, pm)
%% 变异操作(非均匀变异法)
%输入:交叉操作得到的新种群;基因的上界;基因的下界;当前迭代次数;最大迭代次数;变异的概率
%输出:变异操作后的新种群
[row, line] = size(Cross_chrom);
New_chrom = zeros(row, line); %初始化变异操作得到的新种群

b = 2; %非均匀变异公式中的常数
a = 1 - iter/iter_max; %此常数随当前迭代次数的变化而变化,具体见非均匀变异中的公式

for i = 1 : row      %遍历每一个染色体,即每一个解
    for j = 1 : line %遍历每一个基因,即要求解的参数(这里可以根据个人情况修改代码,如果你只想变异一个特定的基因,只需只定j为特定常数)
        r = rand;    %生成一个随机数,表示非均匀变异公式中随机数
        if rand < pm    %判断是否发生变异操作(此处为发生变异操作)
            if randi([0, 1]) == 1 
                New_chrom(i, j) = Cross_chrom(i, j) + ( Up_gen(j) - Cross_chrom(i, j) ) * ( 1 - r^(a*b) );   %公式1
            else
                New_chrom(i, j) = Cross_chrom(i, j) + ( Cross_chrom(i, j) - Down_gen(j) ) * ( 1 - r^(a*b) ); %公式2
            end
        else
            New_chrom(i, j) = Cross_chrom(i, j); 
        end
    end
end

生成测试数据

%% 生成测试数据
clear, clc;
M = 60; %含水层厚度
Q = 58; %定流量
r = 0.1; %井径
A = Q / (4 * pi * M); %论文中的斜率A
B = A * log( 2.25*M / (r*r) ); %论文中的截距B

Alpha = 0.346; %参数1
Beta = 0.0044; %参数2
S = 0.00192;   %参数3

Sum = 15;
Data_Create = zeros(Sum, 2);
X = zeros(Sum, 1);
for i = 1 : 15
    Data_Create(i, 1) = i;
    X(i) = -1*Beta*Data_Create(i, 1) + log( Alpha * Data_Create(i, 1) ) - log( S );
    Data_Create(i, 2) = ( A*X(i)+B ) / ( Alpha * exp( -1*Beta*Data_Create(i, 1) ) );
end

save Data_Create_For_Test.mat  Data_Create;

算法使用的算子公式参考视频

参考论文链接

某次运行结果:

 

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

改进遗传算法的参数反演--实例复现(详细注释) 的相关文章

  • Matlab 错误:()-索引必须出现在索引表达式的最后

    我有这段代码 想要在制表符分隔的 txt 文件中写入一个数组 fid fopen oo txt wt for x 1 length s fprintf fid s t n s x 1 end fclose fid 但我收到此错误 Error
  • 当 MATLAB 变得非常非常忙时,如何中断它?

    我正在运行一个长时间的模拟MATLAB http en wikipedia org wiki MATLAB我意识到我需要停下来重新运行 然而 MATLAB 确实对这种计算很感兴趣 并且它停止了响应 如何在不终止 MATLAB 的情况下中断此
  • 如何调整x轴和y轴的大小

    如何调整 x 轴和 y 轴的大小 我想要什么 更具体 3900 60 30 0 60 120 180 3600 我做了什么 a 0 0 1 10000 plot a 我应该写什么才能按预期调整 x 和 y 轴的大小 EDIT 我不想 390
  • Matlab 的 fftn 在多线程下变得更慢?

    我可以访问 12 核机器和一些严重依赖 fftn 的 matlab 代码 我想加快我的代码速度 由于 fft 可以并行化 我认为更多的内核会有所帮助 但我看到的恰恰相反 这是一个例子 X peaks 1028 ncores feature
  • MATLAB 中的内存映射文件?

    我决定使用 memmapfile 因为我的数据 通常为 30Gb 到 60Gb 太大 无法放入计算机内存中 我的数据文件由两列数据组成 对应于两个传感器的输出 并且它们采用 bin 和 txt 格式 m memmapfile G E Str
  • 有没有办法在 MATLAB 中查看 pcode 文件 (.p) 的源代码?

    有没有办法在 MATLAB 中打开 pcode 文件 p 如果 开放 是指edit 那么当然不是 pcode 中的 p 代表 受保护 其主要设计目标是在保护其源代码的同时部署功能组件 如果 开放 是指run 那么当然是的 引用手册 http
  • ODE 时间 Matlab 与 R

    如果在 matlab 中使用可变时间步长求解器 例如 ODE45 我会定义输出的时间跨度 即times 0 50 matlab 将返回 0 到 50 之间不同时间步长的结果 然而在 R 中 我似乎必须定义我希望 ODE 返回结果的时间点 即
  • 如何将条形图的 XtickLabels 向左移动?

    我目前正在尝试创建频率直方图 为此 我必须创建一个条形图 条形图之间没有空格 然而 这集中于XTickLabels在酒吧的中间 由于它是一个直方图 我希望数值位于每个条形之间的线上 以便它可以直观地指示间隔 本质上 我需要将所有刻度标签移至
  • 在 3d 空间中的两个平面之间进行插值

    我正在开发一种工具 可以让您在 3D 体积 上圈出 包围事物 我想通过标记 切片 1 和 3 并从该信息 填充 切片 2 来节省时间 两个简单的解决方案是 1 slice2 slice1 AND slice3 gets the overla
  • FFT 的功率谱密度

    我有一段代码可以获取部分信号的 FFT 现在我正在尝试获取 PSD Fs 44100 cj sqrt 1 T 6 dt 1 Fs left test 1 right test 2 time 45 interval 636 w range t
  • Matlab:掩码/创建一个知道其原点且具有一定半径的圆形 roi

    只是一个简单的问题 我有一张图像 并且提取了某个点 特征 我知道每个帧中该点的坐标 说 x1 和 y1 我需要一个圆形 ROI 形式 该点在图像上具有我选择的半径 我尝试了 impoly 和 roipoly 当我知道图像中的要点时 不知道如
  • matlab mex 文件和 C++ dll (Windows)

    我有一个带有 Test 类的 DLL 标题 class MY EXPORT Test public int doit const string str 和来源 int Test doit const string str return in
  • 在 MATLAB 中使用 FFT 的频率响应

    这是场景 使用频谱分析仪 我有输入值和输出值 样本数是32000采样率为2000样本 秒 输入是正弦波50 hz 输入为电流 输出为压力 单位 psi 我如何使用 MATLAB 根据这些数据计算频率响应 使用 MATLAB 中的 FFT 函
  • Matlab:如何显示数组的“真实”值?

    我有一个在脚本中计算的向量 计算后 我将值显示到命令窗口 显示如下 finalResults 1 0e 05 0 0001 0 0 0005 0 0002 0 0001 0 0027 0 0033 0 0001 0 0000 0 0000
  • 扩展 MATLAB 函数名称的最大长度

    我编写了一个 MATLAB 程序 可以动态创建自定义 MATLAB 函数 并使用以下命令在其他 MATLAB 实例中启动它们unix命令 我使用这个程序来自动化 fMRI 神经影像分析 使用 SPM8 for MATLAB 一切正常 但是
  • 不等间隔时间序列的移动平均线

    我有一个证券交易所股票价格的数据集 时间 价格 但数据点之间的间隔并不相等 从 1 到 2 分钟不等 在这种情况下计算移动平均值的最佳实践是什么 如何在Matlab中实现呢 我倾向于认为 点的权重应该取决于自上一个点以来的最后时间间隔 Ma
  • MATLAB 特征函数

    我很好奇哪里可以找到完整的描述FEATURE功能 它接受哪些论点 没有找到文档 我只听说过memstats and getpid 还要别的吗 gt gt which feature built in undocumented 注意 更完整的
  • MATLAB 教程中的 SIFT 实现

    我正在寻找 MATLAB 中的一些基本 SIFT 实现 我需要从第一原则来写它 另外 我正在寻找一些可以解释程序中发生的事情的内容 Vedali 的代码和 David Lowe 的代码超出了我的理解范围 如果您是 Matlab 用户 您一定
  • 有没有办法在matlab中进行隐式微分

    我经常使用 matlab 来帮助我解决数学问题 现在我正在寻找一种在 matlab 中进行隐式微分的方法 例如 我想区分y 3 sin x cos y exp x 0关于dy dx 我知道如何使用数学方法通常做到这一点 但我一直在努力寻找使
  • Matlab 和 Python 中的优化算法(dog-leg trust-region)

    我正在尝试使用 Matlab 和 Python 中的狗腿信赖域算法求解一组非线性方程 在Matlab中有fsolve https www mathworks com help optim ug fsolve html其中此算法是默认算法 而

随机推荐

  • ESP8266使用详解(AT,LUA,SDK)

    https www cnblogs com yangfengwu p 10100152 html 8266综合开发教程 AT LUA SDK 推荐 https www cnblogs com yangfengwu category 1187
  • android 自定义时钟控件

    效果截图 自定义时钟组件源代码 package com sky dreaming analogic clock view import android content Context import android content Inten
  • Python 中的 sequence 类型

    在查看Python 内置的帮助文档的时候 我发现其对函数的定义def是如下形式的 duplicated subset Hashable Sequence Hashable None None keep Literal first Liter
  • 基于栈的算术表达式求值算法

    基于栈的算术表达式求值算法 在计算机科学中 算术表达式求值是一个非常重要且常见的问题 通常 我们使用中缀表示法来编写算术表达式 而计算机则使用后缀表示法 也称为逆波兰表示法 来进行求值 本文将介绍一种基于栈的算法来解决这个问题 栈数据结构
  • 一、认识Luci的整体结构

    Luci采用的是MVC的Web框架 即Model View Controller usr lib lua luci controller 控制层 usr lib lua luci view 视图层 usr lib lua luci mode
  • 巴特沃斯滤波器原理及其仿真设计

    前面的几篇文章对一阶低通滤波器原理及其数字化进行了探究 为了进一步探究滤波这条知识线路 今天对巴特沃斯滤波器滤波器进行了研究 1 什么是巴特沃斯滤波器 巴特沃斯 Butterworth 滤波器是一种具有最大平坦幅度响应低通滤波器 它在通信领
  • Windows环境搭建USRP-B210开发环境

    背景 近期在搞软件无线电 SDR 买了一块USRP B210作为发射机 决定在Windows平台下开发 找遍网络 基本上都是Linux下的开发资料 连官网上都没有什么关于Windows下的开发手册 我还就不信了 MATLAB上能跑 还不能在
  • QT中各类型数据转换(更新中)

    QT类型转换 数据转换 16进制 to int型 int型 to 16进制 16进制 to float型 QString型 to 16进制 16进制 to QString型 数据转换 开发过程中通常需要数据类型的转换 最近使用QT开发工具
  • 冒泡排序实现(c++)

    目录 冒泡排序简介 冒泡排序原理 动图演示 代码实现 冒泡排序简介 冒泡排序 最优时间复杂度O N 平均时间复杂度O N 2 最差空间复杂度O N 平均时间复杂度O 1 是一种代码简单的排序也是几乎最慢的算法 稳定 冒泡排序原理 比较相邻的
  • Notepad++ 删除空白行的方法

    方法一 插件处理 先下载安装插件 TextFX 下载后重新启动下 然后在菜单栏找到 TextFX gt TextFX Edit gt Delete blank lines 即可 方法二 正则处理 选择替换 把查找模式设置为正则表达式 在查找
  • windows server 2008 r2安装SQL SERVER 2008 R2 不能打开1433端口设置方法

    服务器 WINDOWS SERVER 2008 R2 SQL SQL SERVER 2008 R2 背景 同一个公司同一个局域网 网络可以ping通 但是不能连接服务器数据库 提示错误1326 前期设置 经过前期设置都不行 telnet l
  • 提升布局灵活性:掌握Vue中vue-splitpane分割面板的实用技巧

    项目中遇到内容分割化并且可以让用户自行调整面板大小的需求 即可使用此组件解决 首先看效果 使用 npm install vue splitpane S 引入组件库 import splitPane from vue splitpane 全局
  • Altium Designer中批量修改原理图中的器件属性

    网上关于批量修改也有很多的介绍 按照网上的尝试在PCB的修改中可以正常操作 但是在原理图中 却只能修改一个 究其原因 原来是差了一步 正确的步骤是 1 先选择需要修改的器件的其中一个 2 右键find similar objects 然后在
  • 史上最全的Unity面试题(含答案)

    一 什么是渲染管道 是指在显示器上为了显示出图像而经过的一系列必要操作 渲染管道中的很多步骤 都要将几何物体从一个坐标系中变换到另一个坐标系中去 主要步骤有 本地坐标 gt 视图坐标 gt 背面裁剪 gt 光照 gt 裁剪 gt 投影 gt
  • scrapy爬取动态网页_基于scrapy的动态网页采集方案总结

    基于scrapy的动态网页采集一直是个难点 而且如果想达到工程级别的抓取 需要有个高效率的解决方案 我列出了几个曾经尝试过的方案和它们的特点 基于PyV8等脚本解析引擎 这类方案的原理是利用开源浏览器项目中的脚本解释引擎 实现相关脚本片段的
  • unity 切换camera 渲染层

    camera有个属性cullingMask 改变cullingMask就可以改变camera渲染层 在做GUI时特别有用 camera cullingMask 1 lt lt 8 渲染除了层8的所有层 camera cullingMask
  • Redis生存时间TTL

    文章目录 为什么要设置key生存时间 设置key的生存时间 访问key的生存时间 清除生存时间 毫秒级时间 为什么要设置key生存时间 设置key的生存时间 可以用于以下使用场景 在登录网站后 将用户session存储在内存 设置一个过期时
  • Second season fifteenth episode,How are Ross and Rachel doing

    Scene Chandler and Joey s apartment Joey and Chandler enter with Chandler covering his eyes and Joey leading him JOEY Al
  • y2第一章 初始mybatis的上机3_MyBatis3.2.x从入门到精通之第一章

    第一章 一 引言 mybatis是一个持久层框架 是apache下的顶级项目 mybatis托管到goolecode下 再后来托管到github下 百度百科有解释 二 概述 mybatis让程序将主要精力放在sql上 通过mybatis提供
  • 改进遗传算法的参数反演--实例复现(详细注释)

    目录 主函数 计算适应度大小 选择操作 论文中的竞争选择法 锦标赛选择法 交叉操作 论文中的离散交叉法 变异操作 论文中的非均匀变异法 生成测试数据 某次运行结果 主函数 清除变量 导入数据 clear clc load Data Crea