遗传算法总结(迭代版本2:附带MATLAB例题代码)

news2024/9/28 11:22:55

目录

基本概念:

具体例子

1.我们先对图像进行抽象化:

2.我们将得到的六串数字进行扁平化处理:

3.解释即后续操作​编辑

基本步骤:

总结

例题1:

例题2:


基本概念:

  1. 染色体(Chromosome):染色体是遗传算法中表示解决方案的数据结构。它是由一系列基因组成的,每个基因对应着解决方案的一个组成部分

  2. 基因(Gene):基因染色体中的一个元素,它对应着解决方案的一个特定部分。基因可以是二进制、整数或实数等不同的类型(这里的基因【解决方案的一小部分】取决于想将染色体【即解决方案】划分成由多少个相同小部分的组成),具体取决于问题的性质

  3. 种群(Population):种群是由多个个体组成的集合,每个个体都表示解决方案的一个可能性。种群中的个体通过进化操作进行交叉变异,以产生新的个体。

  4. 适应度函数(Fitness Function):适应度函数用于衡量个体的优劣程度(即我们给出的函数的适应程度好不好)。它将染色体映射到一个适应度值,该值指示了染色体对问题的解决程度。适应度函数的设计取决于具体的问题优化目标

  5. 选择操作(Selection):选择操作用于选择优良个体作为下一代的父代。选择操作通常根据个体的适应度值进行选择,使适应度较高的个体有更高的概率被选中(即在进行交叉突变之后得到的种群,选择适应程度高的个体)。

  6. 交叉操作(Crossover):交叉操作是通过交换两个染色体部分基因(即解决方案的一部分),产生新的个体。通过交叉操作,可以将两个个体的优良特征进行组合,产生更好的解决方案

  7. 突变操作(Mutation):突变操作是在染色体中引入随机变化,以增加种群的多样性。突变操作有助于避免算法陷入局部最优解,并探索搜索空间中的新解。

  8. 进化(Evolution):进化是指种群中的个体通过选择、交叉和突变等操作逐代演化的过程。通过不断迭代优化,种群中的个体逐渐适应环境,并产生更好的解决方案

  9. 最优解(Optimal Solution):在遗传算法中,最优解是指具有最佳适应度值个体或染色体,它代表了问题的最优解决方案


具体例子

为了进一步的理解这里给出具体的例子:

先举一个实际例子采用b站【数之道14】六分钟时间,带你走近遗传算法_哔哩哔哩_bilibili视频所给出的例子:

 

就比如说我们现在要找出最适应的解决方案,能够成功展示上面的图像。

1.我们先对图像进行抽象化:

将整个图形化成相同的6*6大小的小方格,其中对于白色格子我们用0表示,黑色格子我们用1来表示,那么我们就可以把问题最终的图形抽象为六串数字:

第一行:0 0 0 0 0 0 

第二行:0 1 0 0 1 0

第三行:0 0 0 0 0 0

第四行:1 0 0 0 0 1

第五行:0 1 1 1 1 0

第六行:0 0 0 0 0 0
我们将该六串数字再重新表示一下并与原图进行比较,我们可以发现两者表示含义一样:

2.我们将得到的六串数字进行扁平化处理:

得到:0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 1 0 1 1 1 1 0 0 0 0 0 0 0

我们就将该得到的一串数字称为染色体,而基因则是对于其中的一个数字进行描述。

扁平化处理过程样例如下:

3.解释即后续操作

我们将扁平化后的一串数字称为原图染色体 。

基本步骤:

1.随机生成一个包含10个染色体的祖先群落:

2.随机选择两个染色体进行交叉操作,即截取染色体的一部分基因与另一个染色体进行交换,互换后得到两个新染色体(由两个原来的染色体,经过互换完成后形成的两个新染色体)

3.随机选取一个染色体进行突变操作,即在随机位置进行基因变异操作(例如让0变1,或者1变0),突变后得到一个新染色体。

4.将所有的染色体分别和原图染色体求基因差值的平方和(求得的即适合度值),对于适合值进行排序(现在有13个染色体),取最小的10个染色体作为新的群落。

重复上面的步骤,当我们每进行一次上面得到步骤,将得到的最小的染色体的逆扁平化,然后绘制成图片的时候,就可以得到染色体逐步进化的过程了。

总结

遗传算法是一个通过不断试错、交叉和突变的过程来更新种群并寻找最优解决方案的优化方法。我们可以观察到它是一个不断试错的过程。

交叉操作通过交换染色体的部分基因,促使优良特征种群中传递和组合,从而产生更优的解决方案。这种信息交流可以帮助种群逐渐趋向最优解。

突变操作引入随机性,使得染色体产生变化。它有助于避免算法陷入局部最优解,通过引入新的个体,扩大搜索空间,有机会发现更好的解决方案

虽然交叉和突变操作对于遗传算法的成功至关重要,但它们不是万能的。在某些情况下,交叉和突变可能无法有效地改进解决方案。在这种情况下,可能需要考虑其他策略,如改变选择操作、调整适应度函数或引入其他启发式方法。

例题1:

假设我们要使用遗传算法求解以下的多元多峰函数问题:

目标函数:f(x1, x2) = sin(x1) + cos(x2),其中 -10 ≤ x1 ≤ 10,-10 ≤ x2 ≤ 10。

我们可以使用遗传算法来寻找使目标函数取得最大值的解。

% 目标函数:f(x1, x2) = sin(x1) + cos(x2),其中 -10 ≤ x1 ≤ 10,-10 ≤ x2 ≤ 10。

% 遗传算法参数设置
populationSize = 50; % 种群大小
chromosomeLength = 2; % 染色体长度
generationCount = 100; % 迭代次数
mutationRate = 0.01; % 变异率

% 初始化种群
% 生成一个大小为 populationSize 行 chromosomeLength 列的随机矩阵
% 矩阵中的元素是从0到1之间均匀分布的随机小数。然后乘以 20
% 将随机数的范围扩大到0到20之间。最后减去 10,将随机数的范围调整到-10到10之间
population = rand(populationSize, chromosomeLength) * 20 - 10;

% 迭代优化过程
for generation = 1:generationCount
    % 计算适应度
    fitness = calculateFitness(population);
    
    % 选择操作
    selectedPopulation = selection(population, fitness);
    
    % 交叉操作
    offspringPopulation = crossover(selectedPopulation);
    
    % 变异操作
    mutatedPopulation = mutation(offspringPopulation, mutationRate);
    
    % 更新种群
    population = mutatedPopulation;
end

% 最优解
% 从种群中选择出第一个个体的所有基因
% 将这些基因赋值给 bestIndividual
% 即得到了种群中适应度最好的个体的染色体表示。
bestIndividual = population(1,:);
bestFitness = calculateFitness(bestIndividual);

% 打印结果
disp(['最优解: ', num2str(bestIndividual)]);
disp(['最优适应度: ', num2str(bestFitness)]);

% 计算适应度函数
function fitness = calculateFitness(population)
    % 计算每个个体的适应度值
    % 这里根据目标函数进行计算
    % fitness = sin(x1) + cos(x2);
    fitness = sin(population(:,1)) + cos(population(:,2));
end

% 选择操作(使用轮盘赌选择)
function selectedPopulation = selection(population, fitness)
    % 根据适应度值进行选择操作
    % 这里使用轮盘赌选择方法

    % 计算适应度值的总和 fitnessSum,用于后续计算选中概率。
    fitnessSum = sum(fitness);
    % 计算每个个体被选中的概率 probabilities,即每个个体适应度值除以适应度值总和。
    probabilities = fitness / fitnessSum;
    % 计算累积概率 cumulativeProbabilities,通过对选中概率进行累加得到的向量。
    cumulativeProbabilities = cumsum(probabilities);

    % 创建一个与种群大小相同的空矩阵 selectedPopulation,用于存储选择后的个体。
    selectedPopulation = zeros(size(population));
    for i = 1:size(population, 1)
        r = rand();
        % 在累积概率向量 cumulativeProbabilities 中找到第一个大于等于 r 的索引值 selectedIdx。
        selectedIdx = find(cumulativeProbabilities >= r, 1);
        % 将种群中索引为 selectedIdx 的个体复制到 selectedPopulation 中的对应位置。
        selectedPopulation(i,:) = population(selectedIdx,:);
    end
end

% 交叉操作(使用单点交叉)
function offspringPopulation = crossover(selectedPopulation)
    % 根据选择的个体进行交叉操作
    % 这里使用单点交叉方法

    % 创建一个与选择后种群大小相同的空矩阵 offspringPopulation,用于存储交叉后的后代个体。
    offspringPopulation = zeros(size(selectedPopulation));
    for i = 1:2:size(selectedPopulation, 1)
        % 获取第一个父母个体 parent1 和第二个父母个体 parent2。
        parent1 = selectedPopulation(i,:);
        parent2 = selectedPopulation(i+1,:);
        
        % 随机选择一个交叉点 crossoverPoint,位于染色体的基因位置上,用于划分交叉片段。
        crossoverPoint = randi([1 size(selectedPopulation, 2)]);
        
        % 通过将 parent1 的交叉点之前的基因与 parent2 的交叉点之后的基因连接,得到第一个后代个体 offspring1。
        offspring1 = [parent1(1:crossoverPoint) parent2(crossoverPoint+1:end)];
        % 通过将 parent2 的交叉点之前的基因与 parent1 的交叉点之后的基因连接,得到第二个后代个体 offspring2。
        offspring2 = [parent2(1:crossoverPoint) parent1(crossoverPoint+1:end)];
        
        % 将 offspring1 和 offspring2 分别存储到 offspringPopulation 中对应的位置。
        offspringPopulation(i,:) = offspring1;
        offspringPopulation(i+1,:) = offspring2;
    end
end

% 变异操作(使用位变异)
function mutatedPopulation = mutation(offspringPopulation, mutationRate)
    % 对交叉后的个体进行变异操作
    % 这里使用位变异方法

    % 创建一个与交叉后个体集合大小相同的矩阵 mutatedPopulation,用于存储变异后的个体。
    mutatedPopulation = offspringPopulation;
    for i = 1:size(mutatedPopulation, 1)
        for j = 1:size(mutatedPopulation, 2)
            % 如果 rand() 小于变异率 mutationRate,则进行变异操作。 
            if rand() < mutationRate
                mutatedPopulation(i,j) = rand() * 20 - 10;
            end
        end
    end
end

例题2:

假设我们要使用遗传算法求解以下的多元多峰函数问题:

目标函数:f(x1, x2) = -[(1 - x1)^2 + 100 * (x2 - x1^2)^2],其中 -2 ≤ x1 ≤ 2,-1 ≤ x2 ≤ 3。

该函数被称为Rosenbrock函数,是一个经典的多峰函数,具有一个全局最优解和多个局部最优解。

% 目标函数:f(x1, x2) = -[(1 - x1)^2 + 100 * (x2 - x1^2)^2],其中 -2 ≤ x1 ≤ 2,-1 ≤ x2 ≤ 3。
% 该函数被称为Rosenbrock函数,是一个经典的多峰函数,具有一个全局最优解和多个局部最优解。

% 遗传算法参数设置
populationSize = 50; % 种群大小
chromosomeLength = 2; % 染色体长度
generationCount = 100; % 迭代次数
mutationRate = 0.01; % 变异率

% 初始化种群
population = rand(populationSize, chromosomeLength) * 4 - 2;

% 迭代优化过程
for generation = 1:generationCount
    % 计算适应度
    fitness = calculateFitness(population);
    
    % 选择操作
    selectedPopulation = selection(population, fitness);
    
    % 交叉操作
    offspringPopulation = crossover(selectedPopulation);
    
    % 变异操作
    mutatedPopulation = mutation(offspringPopulation, mutationRate);
    
    % 更新种群
    population = mutatedPopulation;
end

% 最优解
bestIndividual = population(1,:);
bestFitness = calculateFitness(bestIndividual);

% 打印结果
disp(['最优解: ', num2str(bestIndividual)]);
disp(['最优适应度: ', num2str(bestFitness)]);

% 计算适应度函数
function fitness = calculateFitness(population)
    % 计算每个个体的适应度值
    % 这里根据目标函数进行计算
    x1 = population(:,1);
    x2 = population(:,2);
    fitness = -(1 - x1).^2 - 100 * (x2 - x1.^2).^2;
end

% 选择操作(使用轮盘赌选择)
function selectedPopulation = selection(population, fitness)
    % 根据适应度值进行选择操作
    % 这里使用轮盘赌选择方法
    fitnessSum = sum(fitness);
    probabilities = fitness / fitnessSum;
    cumulativeProbabilities = cumsum(probabilities);
    
    selectedPopulation = zeros(size(population));
    for i = 1:size(population, 1)
        r = rand();
        selectedIdx = find(cumulativeProbabilities >= r, 1);
        selectedPopulation(i,:) = population(selectedIdx,:);
    end
end

% 交叉操作(使用单点交叉)
function offspringPopulation = crossover(selectedPopulation)
    % 根据选择的个体进行交叉操作
    % 这里使用单点交叉方法
    offspringPopulation = zeros(size(selectedPopulation));
    for i = 1:2:size(selectedPopulation, 1)
        parent1 = selectedPopulation(i,:);
        parent2 = selectedPopulation(i+1,:);
        
        crossoverPoint = randi([1 size(selectedPopulation, 2)]);
        
        offspring1 = [parent1(1:crossoverPoint) parent2(crossoverPoint+1:end)];
        offspring2 = [parent2(1:crossoverPoint) parent1(crossoverPoint+1:end)];
        
        offspringPopulation(i,:) = offspring1;
        offspringPopulation(i+1,:) = offspring2;
    end
end

% 变异操作(使用位变异)
function mutatedPopulation = mutation(offspringPopulation, mutationRate)
    % 对交叉后的个体进行变异操作
    % 这里使用位变异方法
    mutatedPopulation = offspringPopulation;
    for i = 1:size(mutatedPopulation, 1)
        for j = 1:size(mutatedPopulation, 2)
            if rand() < mutationRate
                mutatedPopulation(i,j) = rand() * 4 - 2;
            end
        end
    end
end

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1363808.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

uniapp 文字超出多少字,显示收起全文按钮效果demo(整理)

收起展开 <template><view class"font30 color000 mL30 mR30"><text :class"showFullText ? : clamp-text">{{ text }}</text><view v-if"showToggleBtn && text.length > 42" click"toggleShowFu…

基于JAVA的服装店库存管理系统 开源项目

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 数据中心模块2.2 角色管理模块2.3 服装档案模块2.4 服装入库模块2.5 服装出库模块 三、系统设计3.1 用例设计3.2 数据库设计3.2.1 角色表3.2.2 服装档案表3.2.3 服装入库表3.2.4 服装出库表 四、系统展示五、核心代码5.…

小白入门基础 - tomcat

一&#xff1a;前言 Tomcat 服务器是一个免费的开放源代码的 Web 应用服务器&#xff0c;属于轻量级应用服务器&#xff0c;在中小型系统和并发访问用户不是很多的场合下被普遍使用&#xff0c;是开发和调试JSP 程序的首选。对于一个初学者来说&#xff0c;可以这样认为&#x…

解决“SQLServer 添加数据库,报Error 5118“错误

当将把一个SQLServer的数据库文件*.MDF和日志文件*.LDF&#xff0c;从电脑A拷贝到电脑B&#xff0c;然后在电脑B上&#xff0c;使用Microsoft SQL Server Management Studio添加该*.MDF文件&#xff0c;有时报"Error 5118"错误&#xff0c;如图(1)所示&#xff1a; 图…

【C程序设计】C指针

学习 C 语言的指针既简单又有趣。通过指针&#xff0c;可以简化一些 C 编程任务的执行&#xff0c;还有一些任务&#xff0c;如动态内存分配&#xff0c;没有指针是无法执行的。所以&#xff0c;想要成为一名优秀的 C 程序员&#xff0c;学习指针是很有必要的。 正如您所知道的…

Hadoop精选18道面试题(附回答思路)

1.简述Hadoop1和Hadoop2的架构异同 HDFS HA(High Availablity)一旦Active节点出现故障&#xff0c;就可以立即切换到Standby节点&#xff0c;避免了单点故障问题。加入了对zookeeper支持实现比较可靠的高可用。YARN将MapReduce1.0中的资源管理调度功能分离出来形成了YARN&…

Mac/Window 如何下载安装 Pycharm 2023

文章目录 1. 下载 Pycharm2. jiebra 工具下载3. jiebra 工具安装3.1 Window 端3.2 Mac 端 1. 下载 Pycharm Pycharm 下载官网&#xff0c;可以下载的是最新版的 Pycharm&#xff0c;但不保证可以jihuo&#xff1b; 如果需要保证可用的&#xff0c;建议直接下载资源&#xff…

@Transactional 注解的12种失效场景

请直接看原文: 原文链接:啪&#xff01;啪&#xff01;Transactional 注解的12种失效场景&#xff0c;这坑我踩个遍-腾讯云开发者社区-腾讯云 (tencent.com) ------------------------------------------------------------------------------------------------------------…

C++完成Query执行sql语句的接口封装和测试

1、在LXMysql.h 创建Query执行函数 //封装 执行sql语句 if sqllen 0 strlen获取字符长度bool Query(const char*sql,unsigned long sqllen0); 2、在LXMysql.cpp编写函数 bool LXMysql::Query(const char* sql, unsigned long sqllen){if (!mysql)//如果mysql没有初始化好{c…

功能强大且易于使用的视频转换软件—Avdshare Video Converter for Mac/win

在当今的数字时代&#xff0c;我们的生活离不开各种形式的媒体娱乐&#xff0c;而视频内容无疑是其中最为受欢迎的一种。然而&#xff0c;我们常常会遇到一些问题&#xff0c;比如我们在电脑上下载的视频无法在手机上播放&#xff0c;或是我们想将视频转换为其他格式以适应不同…

.NetCore部署微服务(一)

目录 前言 什么是微服务 微服务的优势 微服务的原则 创建项目 在Docker中运行服务 客户端调用 简单的集群服务 前言 写这篇文章旨在用最简单的代码阐述一下微服务 什么是微服务 微服务描述了从单独可部署的服务构建分布式应用程序的体系结构流程&#xff0c;同时这些…

【Linux】之搭建 PostgreSQL 环境

前言 在 Linux 系统下安装 PostgreSQL&#xff0c;可以选择快捷方便的 Docker 安装&#xff0c;但正常的服务器都是直接原生安装的&#xff0c;所以&#xff0c;这里我将讲解如何正常安装 PostgreSQL 以及安装之后的一些配置。如果想了解 Docker 安装的话&#xff0c;可以查看我…

二叉树的经典算法(算法村第八关青铜挑战)

二叉树里的双指针 所谓的双指针就是定义了两个变量&#xff0c;在二叉树中有需要至少定义两个变量才能解决问题。这两个指针可能针对一棵树&#xff0c;也可能针对两棵树&#xff0c;姑且也称之为“双指针”。这些问题一般与对称、反转和合并等类型题相关。 判断两棵树是否相…

004-Zynq实现SD卡存储灰度图片(彩色图片存储正点已开源)

文章目录 前言一、为什么参考ov7725照相机实验存储不了灰度&#xff1f;二、SD卡实现步骤1.配置Zynq核中的SD卡接口2.PS端勾选xilffs3.PS端代码4.读卡器读取SD卡结果呈现 总结 前言 最近在弄SD卡存储灰度图片&#xff0c;参考了正点原子的OV7725照相机实验&#xff0c;但发现最…

网安入门09-Sql注入(绕过方法梳理)

ByPass SQL注入ByPass是指攻击者通过各种手段绕过应用程序中已经实施的SQL注入防御措施&#xff0c;例如输入恶意数据、修改请求头等方式&#xff0c;绕过过滤、转义、限制等操作&#xff0c;从而成功地执行恶意SQL语句。攻击者使用SQL注入ByPass技术可以让应用程序的防御措施…

为什么Java中“1000==1000”为false,而”100==100“为true?

大家好&#xff0c;我是可乐。 在日常编程中&#xff0c;我们经常遇到一些看似简单却隐藏着复杂逻辑的问题。 比如&#xff0c;你是否想过为什么在 Java 中表达式10001000会返回 false&#xff0c;而 100100 却返回 true 呢&#xff1f; Integer a 100; Integer b 100; Sy…

王国维的人生三境界,这一生至少当一次傻瓜

一、人生三境界 古今之成大事业、大学问者&#xff0c;必经过三种之境界。“昨夜西风凋碧树&#xff0c;独上高楼&#xff0c;望尽天涯路。”此第一境也。“衣带渐宽终不悔&#xff0c;为伊消得人憔悴。”此第二境也。“众里寻他千百度&#xff0c;蓦然回首&#xff0c;那人却…

双向数据绑定详细解析(超详细)

文章目录 一、什么是双向绑定二、双向绑定的原理是什么理解ViewModel 三、实现双向绑定实现编译Compile依赖收集 参考文献 一、什么是双向绑定 我们先从单向绑定切入单向绑定非常简单&#xff0c;就是把Model绑定到View&#xff0c;当我们用JavaScript代码更新Model时&#xf…

永磁同步电机的磁场定向控制

目录 概述 通过系统仿真验证行为 探索模型架构 生成用于集成到嵌入式应用程序的控制器 C 代码 指定控制器模型的参考行为 创建 PIL 实现 准备用于 PIL 测试的控制器模型 测试生成的代码的行为和执行时间 结论 此示例说明从电机控制算法生成 C 代码并验证其编译行为和执…

AcWing 998. 起床困难综合症

原题链接 其实上面这一堆就是想说&#xff0c;输入 n,m以及 n 个数和该数所对应的运算&#xff0c;其中运算包括有 与、或、异或 三种&#xff0c;真正的问题就是在所有不大于 m 的数&#xff08;非负数&#xff09;中&#xff0c;对给定的 n 个数都按该数所对应的运算运算一遍…