遗传算法设计实例

article/2025/11/7 0:14:26

1.遗传算法实例程序设计

随机初始化种群P(t)={x1,x2…xn),计算P(t)中个体的适应值。其MATLAB程序的基本格式如下:

Begin
t=0
初始化P(t)
计算P(t)的适应值;
while (不满足停止准则)dobegint=t+1P(t+1)中选择P(t)重组P(t)计算P(t)的适应值
end

例1 求函数 f(x) =9*sin(5x) + cos(4x),x∈[0,15]的最大值

解:

  1. 初始化(编码)
%初始化
function pop = initpop( popsize, chromlength)
pop = round(rand(popsize, chromlength));
%rand随机产生每个单元为{0,1}行数为popsize,列数为chromlength的矩阵,
%roud对矩阵的每个单元进行圆整,这样产生的初始种群,
end
%round函数用于舍入到最接近的整数。语法形式只有1种:Y = round(X),这里的X可以是数,向量,矩阵,输出对应。

initpop.m函数的功能是实现群体的初始化,popsize表示群体的大小,chromlength表示染色体的长度(二值数的长度),长度大小取决于变量的二进制编码的长度。

  1. 目标函数值
  • 二进制数转化为十进制数
function pop2 = decodebinary(pop)
[px,py]= size(pop);
%求pop行和列数
for i= 1:pypop1(:,i)=2.^(py - i). * pop(:,i);
end
pop2 = sum(pop1,2);
%求popl的每行之和
end
  • 二进制编码转化为十进制数

decodechrom.m函数的功能是将染色体(或二进制编码)转换为十进制,参数spoint表示待解码的二进制串的起始位置。对于多个变量而言,如有两个变量,采用20表示,每个变量为10,则第一个变量从1开始,另一个变量从11开始。

%将二进制编码转换成十进制
function pop2 = decodechrom( pop, spoint, length)
pop1 = pop(:, spoint:spoint + length- 1);
pop2 = decodebinary(pop1);
end
  1. 计算目标函数值
function  [abjvalue] = calobjvalue(pop)
templ = decodechrom(pop, 1,10); %将pop每行转化成十进制数
x= templ * 10/1023;             %将二值城中的数转化为变量域的数
abjvalue = 10* sin(5*x)+7* cos(4*x);%计算目标函数值
end
  1. 计算个体的适应值
%计算个体的适应值
function fitvalue = calfitvalue( objvalue)
global Cmin;
Cmin= 0;
[px, py]= size(objvalue);
for i = 1:pxif objvalue(i) + Cmin>0temp = Cmin + objvalue(i);elsetemp = 0.0;fitvalue(i) = temp;
end
fitvalue = fitvalue'
  1. 选择复制

选择或复制操作是决定哪些个体可以进入下一代。程序中采用赌轮盘选择法选择,这种方法较易实现。根据方程 pi= fi/fsum.选择步骤如下:
(1) 在第t代,计算fsum和pi
(2)产生{0,1}的随机数rand(.),求s=rand(.)* fsum
(3)求 Σfi ≥s中最小的k,则第k个个体被选中。
(4) 进行N次(2)、(3)操作,得到N个个体,成为第t=t+1代种群。

%选择复制
function [newpopl = selection(pop, fitvalue)
totalfit = sum(fitvalue);       %求适应值之和
fitvalue = fitvalue/ totalfit;  %单个个体被选择的概率
fitvalue = cumsum(fitvalue);    %如fitvalue=[1 2 3 4],cumsum(fitvalue)=[1 3 6 10]
[px,py]= size(pop);
ms = sort( rand(px,1));         %从小到大排列
fitine 1;
newin= 1;
while newin <= pxif(ms( newin))< fitvalue(fitin)newpop(newin) = pop(fitin);newin= newin+ 1;elsefitin = fitin+1;end
end
  1. 交叉

群体中的每个个体之间都以一定的概率pc交叉,即两个个体从各自字符串的某一位置(一般是随机确定)开始互相交换,这类似生物进化过程中的基因分裂与重组。

例如,假设两个父代个体x1.x2为:
x1 =0100110
x2 = 1010001.
从每个个体的第3位开始交叉,交叉后得到两个新的子代个体y1、y2分别为:
y1 = 0100001
y2= 1010110
这样两个子代个体就分别具有了两个父代个体的某些特征。
利用交叉有可能由父代个体在子代组合成具有更高适合度的个体。事实上交叉是遗传算法区别于其他传统优化方法的主要特点之一。

%交叉
function [newpop] = crossover(pop, pc)
[px, py] = size(pop);
newpop = ones(size(pop));
for i= 1:2:px- 1  %2为间隔if(rand <pc)cpoint = round(rand* py);newpop(i,:) = [pop(i,1:cpoint),pop(i+ 1,cpoint+1:py)];nevpop(i+1,:)= [pop(i + 1,1:cpoint),pop(i,cpoint+ 1:py)];elsenewpop(i,:) = pop(i);newpop(i+ 1,:)=pop(i+1);end
end
  1. 变异
    基因的突变普遍存在于生物的进化过程中。变异是指父代中的每个个体的每一位都以概率pm翻转,即由1变为0,或由0变为1。

遗传算法的变异特性可以使求解过程随机地搜索到解可能存在的整个空间,因此可以在一定程度上求得全局最优解。

%变异
function [newpop] = mutation( pop,pa)
[px,py]= size(pop); 
newpop = ones(size(pop);
for i= 1:pxif(rand< pm)mpoint = round(rand * py);if mpoint<= 0mpoint= 1;endnewpop(i) = pop(1);if any( newpop( i, mpoint))==0newpop( i, mpoint) = 1;elsenewpop(i, mpoint) = 0;endelsenewpop(i) = pop(i);end
end
  1. 求出群体中最大适应值及其个体
%求出群体中适应值最大的值
function [ bestindividual, bestfit] = best(pop, fitvalue)
[px,py]= size(pop);
bestindividual = pop(1,:);
bestfit= fitvalue(1);
for i= 2:pxif fitvalue( i> bestfitbestindividual= pop(i,:);bestfit= fitvalue(i);end
end
  1. 主程序
clc;
clear all;
popsize= 20;        %群体大小
chromlength= 10;    %字符串长度(个体长度)
pc = 0.7;           %交叉概率
pm= 0.005;          %变异概率
pop = initpop(popsize, chromlength);    %随机产生初始群体
for i= 1:20         %20为迭代次数[objvalue] = calobjvalue(pop);         %计算目标函数fitvalue = calfitvalue(objvalue);      %计算群体中每个个体的适应度[newpop] = selection( pop, fitvalue);   %复制[newpop]  = crossover(pop, pc);         %交叉[newpop] = mutation(pop, pc);           %变异[bestindividual, bestfit]= best(pop, fitvalue); %求出群体中适应值最大的个体及其适应值y(i) = max(bestfit);n(i)= 1;pop5 = bestindividual;x(i) = decodechrom( pop5, 1, chromlength) * 10/1023;pop= newpop;
end
fplot(@(x)9.*sin(5.*x)+8.*cos(4.*x))
hold on
plot(x,y,'r* ')
hold off

结果如下:最高点为最大值

在这里插入图片描述
注意:遗传算法有4个参数需要提前设定,一般在以下范围内进行设置。

  • 群体大小: 20~100。
  • 遗传算法的终止进化代数: 100~500。
  • 交叉概率: 0.4~0.99。
  • 变异概率: 0. 0001~0.1。

注意

1算法的参数设计

在单纯的遗传算法中,有时候也会出现不收敛的情况,即使在单峰或单调也是如此。这是因为种群的进化能力已经基本丧失,种群早熟。为了避免种群的早熟,参数的设计一般遵从以下原则。

  1. 种群的规模

当群体规模太小时,很明显会出现近亲交配,产生病态基因。而且造成有效等位基因先天缺乏,即使采用较大概率的变异算子,生成具有竞争力高阶模式的可能性仍很小,.况且大概率变异算子对已有模式的破坏作用极大。

同时遗传算子存在随机误差(模式采样误差),妨碍小群体中有效模式的正确传播,使得种群进化不能按照模式定理产生所预测的期望数量;种群规模太大,结果难以收敛且浪费资源,稳健性下降。种群规模的一个建议值为0~ 100。

  1. 变异概率

当变异概率太小时,种群的多样性下降太快,容易导致有效基因的迅速丢失且不容易修补;当变异概率太大时,尽管种群的多样性可以得到保证,但是高阶模式被破坏的概率也随之增大。变异概率一般取0. 0001~0.2。

  1. 交配概率

交配是生成新种群最重要的手段。与变异概率类似,交配概率太大容易破坏已有的有利模式,随机性增大,容易错失最优个体;交配概率太小不能有效更新种群。交配概率一般取0.4~0. 99.

  1. 进化代数

进化代数太小,算法不容易收敛,种群还没有成熟;代数太大,算法已经熟练或者种群过于早熟不可能再收敛,继续进化没有意义,只会增加时间开支和资源浪费。进化代数一般取100~500。

  1. 种群初始化

初始种群的生成是随机的。在初始种群的赋予之前,尽量进行一个大概的区间估计,以免初始种群分布在远离全局最优解的编码空间,导致遗传算法的搜索范围受到限制,同时也为算法减轻负担。

2.适应度函数的调整

  1. 在遺传算法运行的初期阶段

群体中可能会有少数几个个体的适应度相对其他个体来说非常高。若按照常用的比例选择算子来确定个体的遗传数量时,则这几个相对较好的个体将在下一代群体中占有很高的比例。

在极端情况下或当群体现模较小时,新的群体甚至完全由这样的少数几个个体所组成。这时交配运算就起不了什么作用,因为相同的两个个体不论在何处发生交叉行为都永远不会产生新的个体。

这样就会使群体的多样性降低,容易导致遗传算法发生早熟现象(或称早期收敛),使遗传算法所求到的解停留在某一局部最优点上。

因此,希望在遗传算法运行的初期阶段,算法能够对–些适应度较高的个体进行控制,降低其适应度与其他个体适应度之间的差异程度,从而限制其复制数量,以维护群体的多样性。

  1. 在遗传算法运行的后期阶段

群体中所有个体的平均适应度可能会接近于群体中最佳个体的适应度。也就是说,大部分个体的适应度和最佳个体的适应度差异不大,它们之间无竞争力,都会有以相接近的概率被遗传到下一代的可能性,从而使得进化过程无竞争性可言,只是一种随机的选择过程。这将导致无法对某些重点区域进行重点搜索,从而影响遗传算法的运行效率。

因此,希望在遗传算法运行的后期阶段,算法能够对个体的适应度进行适当的放大,扩大最佳个体适应度与其他个体适应度之间的差异程度,以提高个体之间的竞争性。


http://chatgpt.dhexx.cn/article/NOK4AYR2.shtml

相关文章

遗传算法GA原理详解及实例应用 附Python代码

遗传算法GA 遗传算法&#xff08;Genetic Algorithm, GA&#xff09;是模拟达尔文生物进化论的自然选择和遗传学机理的生物进化过程的计算模型&#xff0c;是一种通过模拟自然进化过程搜索最优解的方法。 生物在自然界中的生存繁衍&#xff0c;显示了其对自然环境的优异的自适…

vue实现点击下载exe,运行报错shellexecuteex失败 代码2

页面效果 exe插件放在vue项目的public文件夹里&#xff0c;然后用a标签实现点击下载 <a href"/VideoWebPlugin.exe">下载插件</a> 成功下载后运行报错 解决方法&#xff1a;选择在文件夹中显示&#xff0c;右击属性&#xff0c;在兼容性设置里的以管理员…

VC++分别使用WinExec、CreateProcess、ShellExecute和ShellExecuteEx来启动程序(附源码)

VC++常用功能开发汇总(专栏文章列表,欢迎订阅,持续更新...)https://blog.csdn.net/chenlycly/article/details/124272585C++软件异常排查从入门到精通系列教程(专栏文章列表,欢迎订阅,持续更新...)

API函数ShellExecute与ShellExecuteEx用法

ShellExecute: 1.函数功能:你可以给它任何文件的名字,它都能识别出来并打开它。2.函数原型: HINSTANCE ShellExecute( HWND hwnd, LPCTSTR lpOperation, LPCTSTR lpFile, LPCTSTR lpParameters, LPCTSTR lpDirectory, INT nShowCmd ); 3.参数说明:hwnd:用于指定父窗口句…

C/C++ 使用 API 函数 ShellExecuteEx 实现文件打印

本文章主要介绍使用ShellExecuteEx实现打印文件的功能。 函数原型&#xff1a;BOOL ShellExecuteExA(__inout SHELLEXECUTEINFOA *pExecInfo) 输入输出参数都是 SHELLEXECUTEINFO 结构体。 SHELLEXECUTEINFO定义&#xff1a; typedef struct _SHELLEXECUTEINFO { DWORD c…

Windows函数 ShellExecuteEx

点击进入视频教程 代码&#xff1a; #include<windows.h> #include<tchar.h> #pragma comment(lib, "Urlmon.lib") int WINAPI _tWinMain(HINSTANCE hinstance, HINSTANCE hPreInstance, LPTSTR lpCmdLine, int nShowCmd) {// 下载图片&#xff0c;并保…

UpdatePanel终于可以上传文件了!

我们要做的&#xff0c;只是在页面上添加一个控件而已。 不过&#xff0c;其实这只是个半成品&#xff0c;或者说是一个原型&#xff0c;但是很明显&#xff0c;我们做对了。:) 在实现上&#xff0c;我曾经在两个做法上斟酌了许久&#xff0c;第一种是继承ScriptManager&#x…

updatepanel 排版问题

使用 ASP.NET AJAX 開發人員&#xff0c;一定不會錯過 UpdatePanel 這個超級控制項&#xff0c;它可以讓輕易的讓原有設計的頁面很輕易的具有 AJAX 的效果。可是在設計階段使用 UpdatePanel 去排版常造成我們的困擾&#xff0c;放置在 UpdatePanel 中的控制項無法正確呈現實際的…

学习UpdatePanel控件-

原文可以显示图片&#xff08;转载&#xff1a;http://blog.csdn.net/ILOVEMSDN/archive/2007/11/11/1879343.aspx&#xff09; UpdatePanel控件的使用 2008-10-07 05:46 P.M. ScriptManager和UpdatePanel控件联合使用可以实现页面异步局部更新的效果。其中的UpdatePanel就是…

UpdatePanel的用法

UpdatePanel控件也是Ajax里用得最多的控件之中的一个&#xff0c;UpdatePanel控件是用来局部更新网页上的内容&#xff0c;网页上要局部更新的内容必须放在UpdatePanel控件里&#xff0c;他必须和上一次说的ScriptManager控件一起使用。如今来看UpdatePanel的属性 UpdatePanel …

浅谈UpdatePanel

这是我以前刚学习asp.net ajax的时候总结的&#xff0c;如果有什么错误的地方&#xff0c;请大家指出&#xff0c;以便我能早日改正。 1. 作用&#xff1a; UpdatePanel控件用来控制页面的局部更新&#xff0c;这些更新依赖于ScriptManager的EnablePartialRendering属性&…

UpdatePanel 控件简介

UpdatePanel 控件简介 全部折叠全部展开 代码&#xff1a;全部 代码&#xff1a;多种 代码&#xff1a;Visual Basic 代码&#xff1a;C# 代码&#xff1a;Visual C 代码&#xff1a;F# 代码&#xff1a;JScript UpdatePanel 控件简介 在本教程中&#xff0c;您将使用两…

ScriptManager updatepanel

在项目开发中&#xff0c;遇到了一个ajax更新问题&#xff0c;母版上有个通知区域&#xff08;通知区域为ajax定时更新&#xff08;updatepanel&#xff09;&#xff09;&#xff0c;上面有需要显示的几列信息&#xff0c;如最新文章数&#xff0c;批阅数&#xff0c;FTP受信状…

使用 UpdatePanel

1 概述 ASP.NET UpdatePanel 控件能让你创建丰富的、以客户为中心的 Web 应用程序。使用 UpdatePanel 控件&#xff0c;可以刷新选择的页面部分而不是使用回发来刷新整个页面&#xff0c;这就像是执行了一个局部页面更新一样。包含一个 ScriptManager 和一个或多个 UpdatePanel…

UpdatePanel控件

ASP.NET UpdatePanel控件可用于生成功能丰富、以客户端为中心的Web应用程序。通过使用UpdatePanel控件&#xff0c;可以在回发期间刷新网页的选定部分而不是刷新整个网页。这称为执行部分页更新。包含一个ScriptManager控件和一个或多个UpdatePanel控件的ASP.NET网页&#xff0…

ASP.NET AJAX入门系列(4):使用UpdatePanel控件(一)

UpdatePanel可以用来创建丰富的局部更新Web应用程序&#xff0c;它是ASP.NET 2.0 AJAX Extensions中很重要的一个控件&#xff0c;其强大之处在于不用编写任何客户端脚本&#xff0c;只要在一个页面上添加几个UpdatePanel控件和一个ScriptManager控件就可以自动实现局部更新。通…

UpdatePanel的用法及 UpdatePanel与JS冲突的解决方法

UpdatePanel的用法 ScriptManager和UpdatePanel控件联合使用可以实现页面异步局部更新的效果。其中的UpdatePanel就是设置页面中异 步局部更新区域&#xff0c;它必须依赖于ScriptManager存在&#xff0c;因为ScriptManger控件提供了客户端脚本生成与管理UpdatePanel的功 能。…

Java定时器 @Scheduled注解的使用

1.定时器Scheduled简介 Scheduled注解可以用于做定时任务&#xff0c;再方法上加上Scheduled注解&#xff0c;可以将这个方法定义为一个任务发放&#xff0c;可以搭配cron表达式进行任务的控制。 开启定时任务时在类上加注解 EnableScheduling 2.cron表达式的用法 1.按顺序…

java定时器的实现_java定时器实现总结

前言&#xff1a;Java定时器目前主要有3种实现方式&#xff1a;JDK组件&#xff0c;Spring Task&#xff0c;Quartz框架。 1. JDK组件 (1) java.util.TimerTask MyTimerTask.java&#xff1a; public class MyTimerTask extendsTimerTask { Overridepublic voidrun() { System.…

简单实现Java定时器

✨✨hello&#xff0c;愿意点进来的小伙伴们&#xff0c;你们好呐&#xff01; &#x1f43b;&#x1f43b;系列专栏&#xff1a;【JavaEE】 &#x1f432;&#x1f432;本篇内容&#xff1a;自己实现Java定时器 &#x1f42f;&#x1f42f;作者简介:一名现大二的三非编程小白&…